2

I am curious, is it possible to reference a macro on a command line property assignment for MSBuild?

E.g:

msbuild.exe MySolution.sln /p:CustomBeforeMicrosoftCSharpTargets="$(SolutionDir)\custom.targets"

Would this also work when specified as "MSBuildArguments" from an "Edit Build Definition"/"Queue New Build" from Visual Studio connected to TFS?

E.g:

/p:CustomBeforeMicrosoftCSharpTargets="$(SolutionDir)\custom.targets"

Because it doesn't appear to be importing these targets for me. But the targets file is definitely there, alongside the solution, in the build workspace.

I don't want to have to specify an absolute path. Not sure how working with relative paths is meant to work here, can't find any advice on the internet, and debugging it is quite difficult, as it is called on a build agent using a workflow. The workflow logging is definitely reporting it is calling MSBuild with these arguments, but nowhere in the verbose logging output can I see it is making reference to the CustomBeforeMicrosoftCSharpTargets target, or calling it.

EDIT

I wrote a little test build project buildme.proj to further my understanding.

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
    <SetMe>NotInTheSandbox</SetMe>
</PropertyGroup>

<PropertyGroup>
    <SomeMacroValue>c:\Sandbox\BuildTest</SomeMacroValue>
</PropertyGroup>

<PropertyGroup>
    <AlreadySet>$(SomeMacroValue)\InTheSandbox</AlreadySet>
</PropertyGroup>

<Target Name="Build">
    <Message Text="I am building!" />
    <Message Text="Some macro value: $(SomeMacroValue)" />
    <Message Text="$(SetMe)" />
    <Message Text="$(AlreadySet)" />
</Target>

</Project>

When I execute with the command:

msbuild buildme.proj /p:SetMe="$(SomeMacroValue)\StillNotInSandbox"

I get the following output:

Microsoft (R) Build Engine version 12.0.31101.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 10/12/2015 22:12:08.
Project "C:\Sandbox\BuildTest\buildme.proj" on node 1 (default targets).
Build:
  I am building!
  Some macro value: c:\Sandbox\BuildTest
  $(SomeMacroValue)\StillNotInSandbox
  c:\Sandbox\BuildTest\InTheSandbox
Done Building Project "C:\Sandbox\BuildTest\buildme.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.02

So clearly, it is not behaving how I expected: The macro identifier appears in the output message text.

Is there a solution to this?

1
  • 1
    How about passing /p:MyCustomBeforeMicrosoftCSharpTargets="custom.targets" to the project, and inside the project set the property CustomBeforeMicrosoftCSharpTargets to "$(SolutionDir)\$(MyCustomBeforeMicrosoftCSharpTargets)" ? Commented Dec 11, 2015 at 9:17

1 Answer 1

3

A "macro" like $(SolutionDir) exists only in VisualStudio and VS passes the value to MSBuild.

Instead MSBuild makes Environment variables available as properties, so a batch file like this

set SomeMacroValue=foo
msbuild buildme.proj /p:SetMe="$(SomeMacroValue)\StillNotInSandbox"

is probably what you are looking for. And you can set environment variables per-user or per-machine (Control Panel\All Control Panel Items\System Advanced System Settings, Environment variables).

Sign up to request clarification or add additional context in comments.

2 Comments

Agree with Giulio, @Rabid, you can use environment variables. And there are some predefined TFS environment variables you can use it in MSBuild argument. See: msdn.microsoft.com/en-us/library/hh850448.aspx
Thanks, I had come across those variables. Unfortunately I'm using TFS 2012, so they didn't exist. However, after I had found them, I took the spirit of them and modified my build workflow to substitute the equivalent values from workflow variables into my MSBuild arguments using string.replace(). I'm not quite on the cutting edge sadly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.