MSBuild.exe not accepting either /p:DefineConstants nor /p:PreprocessorDefinitions - command-line

I've been through quite a number of articles on Stack Overflow that answered the question "How do I pass preprocessor definitions to the compiler from the MSBuild command line," and they all responded with some variation of:
MSBuild.exe /p:DefineConstants=THING_TO_BE_DEFINED
I have tried every variation that I could come up with:
MSBuild.exe "/p:DefineConstants=THING_TO_BE_DEFINED"
MSBuild.exe /p:DefineConstants="THING_TO_BE_DEFINED"
MSBuild.exe "/p:DefineConstants=THING_TO_BE_DEFINED=1"
MSBuild.exe /p:DefineConstants="THING_TO_BE_DEFINED=1"
...and dozens of others. I've also flirted with overriding PreprocessorDefinitions in similar ways. All of them triggered the #error below:
#include "stdafx.h"
#if !defined(THING_TO_BE_DEFINED)
#error "THING_TO_BE_DEFINED is not defined"
#endif
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
I've been trying this with the simple command-line application above, as well as with a huge game project that I have here. I can only guess that Visual Studio (I'm seeing this with 2005 and 2008) has some default set deep in its bowels that is preventing my command line argument from being applied, but I've found no evidence to support this hypothesis.
Any ideas on how I can get this to work? Why in the name of FSM didn't they stick with good ol' -D THING_TO_BE_DEFINED?

If you are calling MSBuild on the command line you cannot specify the value for DefineConstants. But if you are building a .csproj, or another MSBuild script, then you can specify it. If you create a msbuild file to "replace" your solution file then you can use that an specify the value for that when you build your projects. For example:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Default value here -->
<DefineConstants Condition=" '$(DefineConstants)'==''" >DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Projects Include="one.csproj" />
<Projects Include="two.csproj" />
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="#(Projects)"
Properties="DefineConstants=$(DefineConstants)"/>
</Target>
</Project>
Then you can use msbuild.exe buid.proj /p:DefineConstants="YourValue;Debug;Trace"
Note the usage of the quotes on the command line.
I have written a blog post a while back about something related to this at http://sedodream.com/2008/05/07/MSBuildBuildingTheSameProjectMultipleTimes.aspx.

If you want to define TRACE & DEBUG Constants this should work:
msbuild mysln.sln /t:Rebuild /p:Configuration=Release /p:DefineConstants="DEBUG;TRACE"

The below are needed modification to the vcxproj for the /p to work.
put
<DefineConstants>< /DefineConstants>
under the <PropertyGroup Label=Globals >
<PreprocessorDefinitions>$(DefineConstants);WIN32;_DEBUG;_CONSOLE;UNIT_TEST_SIM;%(PreprocessorDefinitions)
This way MSBuild will know that for the preprocessor it needs to use the values from the DefineConstants which come from the Globals PropertyGroup unless provided from the command line by the /p:DefineConstants="MY_DEFINE"

For completeness, this is what I found worked when I wanted THING_TO_BE_DEFINED="VALUE WANTED", for VB.NET, and msbuild version 3.5.30729.1, in a batch file:
#msbuild /t:Rebuild /p:Configuration=Release;Platform="Any CPU";
DefineConstants="THING_TO_BE_DEFINED=\"VALUE WANTED\"" mysln.sln
(all on one line of course)

Related

Ant replace task doesn't work

I have Powershell script. It has a first line:
$installation_folder = #aaa#
And have an Ant buildfile with this task:
<target name="prepare-install-script" description="Preparation of installation script">
<replace file="install.ps1" propertyfile="${template-properties}">
<replacefilter token="#aaa#" value="installation.dir"/>
</replace>
</target>
All files are initialized. Logs said:
[replace] Replacing in c:\Users\install.ps1: #aaa# --> sdfsdf
But in the file nothing changed.
What can it be?
You have to change the encoding. This will work:
<target name="prepare-install-script" description="Preparation of installation script">
<replace file="install.ps1" token="#aaa#" value="installation.dir" encoding="UTF-16"/>
The problem was that when you write script in PowerShell default Windows IDE it became somethings like "binary" file with some system information. That's why Ant can't do replacing.
Fixing by copy script to simply text editor and save as ps1.

Run a command in ccnet.config

I am trying to run the nuget command that I would normally set in the projects post build $(ProjectDir)nuget\pack.bat $(ProjectDir) $(TargetDir) $(ConfigurationName) $(SolutionDir) to run instead in the ccnet.config on a successful build. What I have does not seem to be running at all.
<exec>
<Target>
<executable>cmd</executable>
<buildArgs>/C c:\build\project\nuget\pack.bat c:\build\project\ c:\build\project\bin\nuget\ Nuget c:\build\project\ /M</buildArgs>
</Target>
</exec>
Edit
Figured it out partially. Needed to make sure I was pointing to <executable>c:\Windows\System32\cmd.exe</executable> and not using cmd.

CodeAssassin.ConfigTransform for of arbitrarily named config files

NuGet packages such as CodeAssassin.ConfigTransform tranform web.*.config or app.*.config to web.*.config.transformed or app.*.config.transformed upon a VS build.
However, what if you have config files of form {arbitrary-name}.config ?
For example, MyAssembly.dll.config and its transform rulesets MyAssembly.dll.debug.config & MyAssembly.dll.release.config
CodeAssassin.ConfigTransform does not appear to work for these file patterns.
If you look at the target source code it looks quite simple to modify it to allow any .config file to be transformed. Actually I think that transforming any XML file should be possible.
I will fork that repository tomorrow for and experiment with this.
Disclaimer: In this example I modified CodeAssassin.ConfigTransform.targets directly. But you should create a separate .targets file and reference that in your .csproj.
Add a ConnectionString.config (as an example) and then add the transforms.
Add this to the .targets file (your config name just has to match the regex expression - (?i)^ConnectionString\. in this case):
<Target Name="TransformAllConnectionStringConfigTransformFiles"
Condition="'$(WebProjectOutputDir)'!=''"
BeforeTargets="Compile">
<ItemGroup>
<ConnectionStringConfigTransformFile Include="#(None);#(Content)" Condition="'$([System.Text.RegularExpressions.Regex]::IsMatch(%(Filename),"(?i)^ConnectionString\."))' == true and '%(Extension)'=='.config'" />
</ItemGroup>
<TransformXml Source="ConnectionString.config" Destination="%(ConnectionStringConfigTransformFile.Identity).transformed" Transform="#(ConnectionStringConfigTransformFile)"
Condition="'#(ConnectionStringConfigTransformFile)'!=''" />
<CreateItem Include="%(ConnectionStringConfigTransformFile.Identity).transformed"
AdditionalMetadata="CopyToOutputDirectory=Always">
<Output TaskParameter="Include" ItemName="Content"/>
</CreateItem>
</Target>
Build, and your .transformed files are created.

TeamCity and running NUnit tests

In TeamCity, i need to state exact locations of assemblies that contain NUnit tests to be executed.
Is there an option to state a .SLN file so it will look up these test projects dynamically?
You can use wildcard expressions in the Run tests from box:
Source\\**\bin\\**\*Tests.dll
The above would run tests from any assembly under any bin folder under the Source folder which contains 'Tests' at the end of the assembly name.
Depending on whether you're using MSBuild or NAnt, you can add an entry to your build script like this:
<ItemGroup>
<TestAssemblies Include="tests\\test*.dll"/>
<TestAssemblies Include="tests.lib\\test*.dll"/>
</ItemGroup>
<Target Name="runTests">
<Exec Command="$(teamcity_dotnet_nunitlauncher) v2.0 x86 NUnit-2.5.0 %(TestAssemblies)" />
</Target>
In the example above, the two TestAssemblies lines point to your assemblies.
You can read more about this here: http://blogs.jetbrains.com/teamcity/2008/09/24/using-teamcity-nunit-launcher/

Where are logs located while running NUnit?

I'm running NUnit tests from Resharper. I want to track execution process so my question is where can I find logs produced by my application?
I use NLog, logger output path is relative, e.g. logs\mylog.txt.
I have a similar setup with my current project and for the unit tests, my NLog output goes to \UnitTests\bin\Debug\Logs. The logger is set up as follows in NLog.config (this produces a daily log file):
<target name="FileLog" xsi:type="File" fileName="${basedir}/logs/${shortdate}_log.txt"
If you aren't getting any output at all from NLog, try adding the throwExceptions, internalLogLevel and internalLogFile attributes to your NLog.config like this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true"
internalLogLevel="Debug"
internalLogFile="nlog_log.log">
I realise this is an old question but just in case you haven't found the answer yet, I though I would see if this helps.