0

I have a build process (let's call it the "engine") that has been using a command line call to Visual Studio's devenv.exe to build a project. I have known for some time that VS is just building with MSBuild, so I finally got around to updating the engine to use MSBuild directly. However, I'm finding a strange anomaly with MSBuild.

For the sake of discussion, there's projects A, B, C, and D. Project A is the main project I'm building, a web app, that depends (through project references) on the other 3 projects. When built manually in VS, A\bin is populated with assemblies. When built in the engine with devenv.exe A\bin is again populated with the expected binaries. When built in the engine use MSBuild, A\bin contains nothing. However, B\Release\bin, C\Release\bin and D\Release\bin contain their binaries as they did using the former 2 build methods.

This happens with just a single project as well. The problem doesn't appear to be related to dependent projects.

I have attempted to explicitly set the MSBuild OutDir property, but it doesn't appear to have any affect.

I have run builds with diagnostic output on and can't see anything obvious (granted, there is a LOT there so it's possible I have yet to find something significant).

I've also been trying to figure out how to see the command line call to MSBuild that VS is making when run from devenv.exe but I can't seem to find it.

I have looked at several other SO posts (here and here) but they aren't the same problem.

Anyone have an idea of what this could be or where else I could look for an answer or more diagnostic information?

EDIT 1: The arguments pattern used for the call to MSBuild looks like this:

/nologo /target:Compile /property:Configuration=%%BUILDCONFIG%% /maxcpucount 
  /property:OutDir=%%OUTDIR%%\bin\ /verbosity:diag /detailedsummary "%%PROJPATH%%"

The lower half of that shows my attempt to force the output directory as well as the enhanced output to show more details of the process. Build engine code replaces with "%%TOKEN%%" items with the appropriate replacement values for the project being built.

EDIT 2: After more research and looking into suggested provided, I've decided to abandon the effort to use msbuild instead of devenv. It seems there is a lot more going on under the hood of devenv in preparation its own call to msbuild and I could likely break something else going on if I don't fully understand the entrance in msbuild. I did try to see if the call to msbuild from devenv is logged, but it doesn't seem to be. I've considered building a dummy msbuild app to just dump the command going into it and temporarily swap out the actual msbuild to generate this diagnostic information, but that's more effort than it's worth at this point. The performance gain isn't so great that it's worth pursuing further for now.

Community
  • 1
  • 1
Peter
  • 1,488
  • 2
  • 17
  • 23
  • On the commandline, do you explicitly provide a Configuration and Platform? Visual Studio always does. It might be that your project files contain multiple configurations and that you have one of those selected in Visual Studio. MsBuild will just use the default values if you don't provide a Platform/Config explicitly. – jessehouwing Feb 04 '13 at 21:41
  • Yes, see edit 1. Should have included that... – Peter Feb 04 '13 at 21:59
  • What is the value you seen in the logs for %%OUTDIR%% for project A and for one of the projects that works? – Alex Feb 04 '13 at 22:19
  • That doesn't add the `Platform` yet `/property:"Platform='AnyCpu'"` – jessehouwing Feb 04 '13 at 22:33

2 Answers2

0

I would look at the Output path on the build tab of your project properties. There are more than few differences when using MSBuild and when using Visual Studio (Even from the command line). It could be you have A configured differently than B,C,D and synching A to the rest will make it work. Also, if you plan to build the projects individually, not as a solution make sure you don't use Solution Level macros that won't be available to the project file on it own.

Alex
  • 12,749
  • 3
  • 31
  • 45
  • I've simplified testing to a single project and, as noted in the original post, the problem still occurs. So I'm sure the problem has nothing to do with dependencies. I've examined the output path. I'm not sure what you might consider wrong in this case. It's set to bin\ and works just fine when built in the VS IDE and using a CLI call to `devenv`. Only in MSBuild are the binaries not copied. I don't have any SLN macros. – Peter Feb 05 '13 at 14:05
  • Are all four of them just bin\ ? or are the other 3 something different. – Alex Feb 06 '13 at 19:28
  • In several test cases, yes, the projects are all configured to output to `bin\`. However, at this point I have reduced testing to single, standalone libraries that don't reference anything and it still happens. The pattern seems to be that the binaries for dependencies get copied to the dependent project one layer below the "top" most project. – Peter Feb 07 '13 at 21:04
0

You are supposed to set OutputPath instead of OutputDir.

Since you already used /verbosity:diag, why not redirect the output to a text file and carefully analyze where csc.exe (or another compiler in use) stores the binaries? That's quite simple and informative for you to learn how MSBuild works under the hood.

Lex Li
  • 60,503
  • 9
  • 116
  • 147