Rabid
Rabid

Reputation: 3034

Referencing macros on msbuild (12.0) command line property assignment

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?

Upvotes: 2

Views: 1997

Answers (1)

Giulio Vian
Giulio Vian

Reputation: 8353

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).

Upvotes: 3

Related Questions