Relative paths with MSBuild project and solution

I have a number of projects that are combined into a solution. Each project has its own directory structure, and csproj files are located at different levels of the folder structure. Each csproj has an OutputPath property. OutputPath is a relative path and varies from project to project so that all projects have the same output directory. It works fine if I create a separate project. But everything changes if I try to create a solution file. In this case, each project output folder is different (depends on the number of ".." in this OutputPath project).

I know that until that moment everything worked fine. No one changed build.cmd to either the sln or csproj files. But now I have the situation described above.

So my question is: what affects the estimation of the relative path? I mean, how can I get the relative OutputPath to be evaluated, starting from the folder where the csproj file of this particular project is located. Not from the folder where the .sln file is located.

Let assume I have following directory structure: dir1 a.sln dir2 a.csproj dir21 dir3 b.csproj 

a.csproj has an output path set to "../../_bin", which is located just above dir1, if calculated from the a.csproj folder b.csproj has an output path set to "../../ .. / _bin ", which is the same - only near dir1 if counted from b.csproj

a.sln contains both a.csproj and b.csproj.

When I run msbuild, I get the project assembly in 'dir1 /../../_ bin' and b project to 'dir1 /../../../_ bin' - both relative paths of the project files are calculated from the location solution file, not project files.

+5
source share
2 answers

Well, I was able to find out what caused it. It was a customtargets file that displayed the SolutionDir property at the beginning of any msbuild. I found out about this using MSBuild Explorer. The tool turned out to be very useful in my case - I did not know about third-party .target files on my system.

+3
source

From Msbuild Import Item Description

Relative paths in imported projects are interpreted relative to the catalog of the importing project. Therefore, if the project file is imported into several project files in different places, the relative paths in the imported project file will be interpreted differently for each imported project.

All reserved MSBuild properties related to the project file, for example, MSBuildProjectDirectory and MSBuildProjectFile referenced in the imported project, are assigned values ​​based on the import project file.

If you add more details or a few samples to your question, it will be easier to understand the exact problem.

Edit: Well, let's try to identify this secret. First of all, environment variables can affect OutputPath.

2nd - during the assembly of the sln file, converted to the msbuild project file format and saved in a temporary file. You can get this temporary file if you run "set msbuildemitsolution = 1" in cmd and then build through the command line. There you can check this file and see what your individual projects are called. But I guess you will see a few .csproj / "> entries. And the global msbuild properties inherited by what causes.

So, I suspect that everything was fine until some point and no changes were made - you are missing the environment variable OutputPath or some other variable that contributed to the creation of OutputPath.

BTW - I think if you want to fix your problem with a forced relative dir - you can also use $ (MSBuildProjectDirectory). This is one of the msbuild reserved properties (from here ), but for this you will need to configure your OutputPath in each csproj file. What I personally prefer to avoid, because it can affect some other goals and introduce subtle problems.

+2
source

Source: https://habr.com/ru/post/914648/


All Articles