Showing posts with label MSBuild. Show all posts
Showing posts with label MSBuild. Show all posts

Wednesday, December 11, 2013

Source files missing from project, but still there (Linking error)

Situation: Some .cpp and .h files shared between several Visual Studio Project files in different VS solutions (I know - bad practice, but it was not my idea and I could not change it) were being relocated to a separate directory beside the solution dir of the project I was working on. By unloading the project in VS, then manually editing the .vcxproj file, it was a simple task to search and replace string entries like:

     ClCompile Include="folder\
with
     ClCompile Include="($SolutionDir)..\folder 

Since the job involved much more reorganizing, and there was a lot of other files in the project as well, it was not unexpected that several referencing and linker errors occurred along the way. 

Symptom: In the end I was faced with a linker problem I was not able to get rid of. LNK2001 and LNK2019 errors were filling my screen. I diffed the old and the new .vcxproj files to search for what I had lost along the way, but found no apparent problem at first. Not until I closely examined what reference the linker could not find, making sure that both a header entry and an implementation body (usually in a corresponding .cpp file) were actually present in the project. Somehow some of the files were not!

Problem: It turns out that for file references, the .vcxproj file simply ignores files written with MsBuild variable references like my ($SolutionDir)..\folder\file.cpp -They show up when you view the .vcxproj file in a text editor, but not from within Solution Explorer. Update: Seems like the MsBuild variable actually sometimes works (see the strikeout above), but not in the combination with double dots for jumping one step up in the folder hierarchy. Needs verification what conditions are for this problem to occur.


Solution: Once I had replaced the ($SolutionDir)..\folder entries in the .vcxproj file with the more boring and less flexible ..\..\folder, everything was fine.

Saturday, February 23, 2013

How MSBuild could make a file inparseable

Problem: A text file that was being parsed from an assembly being part of a developing system. In the developer environment, this worked great. After having deployed the text file and the necessary assemblies to a different location using MSBuild, where MSBuild also replaced a couple of strings inside the text file, parsing would no longer work.
  • Looking at the file in a text editor (i use Notepad++) confirmed that the edited version looked fine.
  • Editing the file in the developer environment manually (not running MSBuild on it) worked fine - the file was parseable afterwards.
Obviously, MSBuild made the file inparseable So how could MSBuild make the text file inparseable? The command touching the file was
<MSBuild.ExtensionPack.FileSystem.File 
     TaskAction="Replace" 
     RegExPattern="Something" Replacement="SomethingElse"
     Files="%(filename)"/>
Only when tracing the code parsing the file it became clear to me that the file now contained some extra characters at the beginning of the file. Then it occurred to me:

Solution: MSBuild changed the file encoding. To make sure MSBuild used the right encoding, I had to add one more key/value pair to the MSBuild tag mentioned above:
TextEncoding="Windows-1252"
I found this by inspecting the file encoding on the source and destination text files. My source file was reported as ANSI, whileas my destination file was reported as UTF-8. It was however not as simple as putting "ANSI" as the TextEncoding, as described in this excellent StackOverflow article, which also lead me on the right path to "Windows-1252".

In my opinion, MSBuild should have retained the original encoding on the files it touches instead of  defaulting it into something unwanted. But then again, that's wat keeps bread on my table... Thanks, MS...

Friday, June 8, 2012

"Could not find a part of the path" from MSBuild/CruiseControl.NET

This case turned out to be a no-brainer, but for my own (and others who may need it) later reference, here it is:
Scenario: I had set up a test environment for testing MSBuild targets run from CruiseControl.NET. The target I wanted to run was supposed to do simple file operations like copying and unzipping files to a specific disk letter, which in my test environment happened to be a subst to a folder on my local hard drive. Windows 7 64-bits with UAC (User Account Control) on was used, running CruiseControl.NET elevated to give it necessary privileges.
Problem: When running the MSBuild target itself, things worked like a dream. However, when running the target from CruiseControl.NET, it always grinded to a halt at the first attempt to copy/unzip data to my disk
Cause: This is the no-brainer: Since CruiseControl.NET ran with elevated privileges (i.e. started with "run as an administrator"), it did not see the substed drive I had set up from a non-elevated cmd window.
Solution: Simply start a cmd window elevated (run as administrator) and do the same subst from there, and voilla! - it works.