开发者

How to build a VS2010 MakeFile project (vcxproj) with TFS Build (No VS 2010)

开发者 https://www.devze.com 2023-02-05 09:27 出处:网络
I have a project that was building fine in VS 2008, and then we installed and started using TFS Build, and then we upgraded to TFS 2010.Everything was still fine and building correctly (开发者_JAVA技巧

I have a project that was building fine in VS 2008, and then we installed and started using TFS Build, and then we upgraded to TFS 2010. Everything was still fine and building correctly (开发者_JAVA技巧after I implemented our new build process that made everything very nice with a single-click build initiation from any remote Visual Studio 2010 client). Visual Studio did not need to be installed on the Build Agent. I'm trying very hard (very hard) not to install Visual Studio on the Build Agent because my understanding is that it's not necessary, and we're not licensed to install it on a non-development machine.

Now I tried upgrading the solution to VS 2010, still targeting .NET 3.5 because it's an assembly targeted for SQL Server CLR procedures, and SQL Server doesn't support .NET 4.0 yet. But I simply cannot make it build any more under TFS Build. I can't seem to get a consistent error message from TFS Build and from an MS Build command line, but I think it has something to do with Microsoft.Cpp.Targets not being in C:\Program Files\MSBuild\ because I haven't installed Visual Studio. I did install the Microsoft Windows SDK 7.1 so that I could run the .NET 4.0 SDK tools like svcutil for some other .NET 4.0 projects, but nothing seems to install what this build wants. The error TFS build gives me is:

C:\TFSBld[...]\GenerateLanguage\GenerateLanguage.vcxproj(46,3): error MSB4019: The imported project "C:\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

And when I click on that error it takes me to this line in the vcxproj file:

  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

All I really need to do in this project is run resgen to generate resources files from resx files, and compile them into sattelite assemblies. I was using a makefile build to do this, manually running resgen (I think it was because I can't find a way to compile sattelite assemblies as a stand-alone solution any other way), and then compile those into a DLL (I can't remember how that worked now, but I think it was manually running AL.exe to compile DLL files from resources files). So basically I just need to run command lines to build this project, and I can't seem to find a reasonable way to do it without throwing out the entire project and editing the TFS build script to run a bunch of hard-coded command lines instead. There's got to be a better way.

I've been at this all day, and tried writing my own .targets file and .xml property sheets to take the place of the standard file, but it's way over my head. I tried simply deleting the lines, but then MSBuild complains that there's no "Build" target. I tried adding a dummy to the vcxproj file, but then it didn't seem to run the pre- and post-build steps where all the work is done.


The Microsoft Windows SDK 7.1 has several installation options. Having only the ".NET Development" child "Tools" checked is apparently not enough to build vcxproj projects, even if they don't include any C++ code (only pre- and post-build steps). Adding the "Visual C++ compilers" option and fully selecting the "Intellisense and Reference Assemblies" checkbox installs the necessary files and settings. I'm not sure if both are necessary, but that combination did work for me.


I have devised a somewhat complex, but functional work around involving the following steps.

  1. Copy these files from C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0 on a system where VS2010 is installed -- check them into source control so they are retrieved as part of the workspace:
    • Microsoft.Build.CPPTasks.Common.dll
    • Microsoft.BuildSteps.targets
    • Microsoft.Cl.Common.props
    • Microsoft.Cpp.Default.props
    • Microsoft.Cpp.props
    • Microsoft.Cpp.targets
    • Microsoft.CppBuild.targets
    • Microsoft.CppCommon.targets
    • Microsoft.Link.Common.props
    • Microsoft.MakeFile.targets
    • Platforms\Win32\Microsoft.Cpp.Win32.default.props
    • Platforms\Win32\Microsoft.Cpp.Win32.props
    • Platfotms\Win32\Microsoft.Cpp.Win32.targets
  2. Change the vcxproj file to refer to the relative path where the workspace puts those files instead of $(VCTargetsPath).
  3. Change lines (in all those files) to use attribute AssemblyFile="Microsoft.Build.CPPTasks.Common.dll" instead of referring to this using the AsssemblyName attribute.
  4. Delete "$(VCTargetsPath)\" in the files at the root of the new location so that it finds its sibling files instead of trying to refer to the non-existent VCTargetsPath macro. You can find instances that you missed by trying to run a command line build with MSBuild on the machine without VS 2010 and looking at the error messages.
  5. Similarly replace $(VCTargetsPath) in child directory files with relative paths.
  6. At the end of the file Microsoft.Cpp.Win32.targets, comment out the "<VCMessage Code="MSB8008" ... />" line and the following related <Import>.
  7. Trial and error, run command line build and see what else I may have forgotten to mention. I think that was most of it.


An improved alternative to BlueMonkMN is to add

<PropertyGroup>
  <VCTargetsPath Condition="'$(VCTargetsPath)' == ''">[path_to_the_fileset_listed]</VCTargetsPath>
</PropertyGroup>

as a level 1 child near the top of the vcxproj.

The path could include an environment variable or some other well-known path containing variable.

This makes less of an an intrusion and is easier to revert than changing lots of lines.


An even more simple approach with adding an environment variable for VCTargetsPath:

  1. Locate the CPP Msbuild Folder mentioned by BlueMonkMN
    • e.g. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120
  2. Open Windows environment variables
    • Control Panel > System > Advanced Settings > Advanced > Environment Variables
  3. Add a new user variable with:
    • Name: VCTargetsPath
    • Value: [your path to MsBuild targets from step 1]
  4. Restart Visual Studio.
  5. Done. Your project should build now.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号