英文:
Expand variable with semicolons in VS project file for PreprocessorDefinitions
问题
I'm using this idea to inject preprocessor definitions from a command line build script using a global named $(DefineConstants)
.
vcxproj file snippet:
<PropertyGroup Label="Globals">
<DefineConstants></DefineConstants>
</PropertyGroup>
...
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>$(DefineConstants);WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
My script launches msbuild
with the following (abridged) command line:
msbuild.exe Solution.sln /p:DefineConstants=FOO%3BBAR
where FOO%3BBAR
is dynamic and comes from any number of user-supplied values. (Using %3B
as a separator comes from this thread since using a raw ;
character results in an error.)
But the compiler (cl
) command line shows that the entire value of $(DefineConstants)
is getting placed into a single /D
switch instead of getting split into multiple.
ClCompile:
CL.exe ... /D "FOO;BAR" /D WIN32 /D _WINDOWS
It's as if the semicolons inside the variable aren't expanded. Is there any way to make it produce /D FOO /D BAR
?
Summary of things I've tried so far:
msbuild command line |
results in cl command line |
comment |
---|---|---|
/p:DefineConstants=FOO%3BBAR |
/D "FOO;BAR" |
wrong: not split into multiple /D |
/p:DefineConstants="FOO;BAR" |
/D "\"FOO\" /D \"BAR\"" |
wrong: split, but includes \" |
/p:DefineConstants=FOO;BAR |
n/a | error: property not valid |
英文:
I'm using this idea to inject preprocessor definitions from a command line build script using a global named $(DefineConstants)
.
vcxproj file snippet:
<PropertyGroup Label="Globals">
<DefineConstants></DefineConstants>
</PropertyGroup>
...
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>$(DefineConstants);WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
My script launches msbuild
with the following (abridged) command line:
msbuild.exe Solution.sln /p:DefineConstants=FOO%3BBAR
where FOO%3BBAR
is dynamic and comes from any number of user-supplied values. (Using %3B
as a separator comes from this thread since using a raw ;
character results in an error.)
But the compiler (cl
) command line shows that the entire value of $(DefineConstants)
is getting placed into a single /D
switch instead of getting split into multiple.
ClCompile:
CL.exe ... /D "FOO;BAR" /D WIN32 /D _WINDOWS
It's as if the semicolons inside the variable aren't expanded. Is there any way to make it produce /D FOO /D BAR
?
Summary of things I've tried so far:
msbuild command line |
results in cl command line |
comment |
---|---|---|
/p:DefineConstants=FOO%3BBAR |
/D "FOO;BAR" |
wrong: not split into multiple /D |
/p:DefineConstants="FOO;BAR" |
/D "\"FOO" /D "BAR\"" |
wrong: split, but includes \" |
/p:DefineConstants=FOO;BAR |
n/a | error: property not valid |
答案1
得分: 1
I tested with the following small test file:
<Project>
<Target Name="TestProp">
<Message Text="$(DefineConstants)" />
</Target>
</Project>
Example commands and outputs:
MSBuild Command | Output | Comment | |
---|---|---|---|
1 | msbuild test.proj /p:DefineConstants=FOO;BAR |
MSB1006 error | |
2 | msbuild test.proj /p:DefineConstants=FOO;DefineConstants=BAR |
BAR | |
3 | msbuild test.proj /p:DefineConstants=FOO,DefineConstants=BAR |
BAR | |
4 | msbuild test.proj /p:DefineConstants="FOO;BAR" |
FOO;BAR | |
5 | msbuild test.proj /p:"DefineConstants=FOO;BAR" |
FOO;BAR | |
6 | msbuild test.proj /p:DefineConstants=FOO%3BBAR |
FOO;BAR |
The /property
switch (short version /p
) to MSBuild defines an MSBuild Property. The /property
switch accepts one or more name/value pairs delimited by semicolon or comma.
Example 1 is an error because the switch is expecting a name/value pair after the semicolon. BAR
is either a name without a value or a value without a name.
The same name can appear multiple times. MSBuild just redefines the property. Essentially the last value is used. This is what is happening in examples 2 and 3.
Examples 4 and 5 use quotes to show the semicolon is part of one name/value pair.
Example 6 is hex encoding the semicolon.
Note that in examples 4, 5, and 6 the value of the DefineConstants
property doesn't include quotes.
When $(DefineConstants)
is replaced in PreprocessorDefinitions
it should be :
<PreprocessorDefinitions>FOO;BAR;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
But somewhere in your project, quotes are being added. Is there code that you haven't shown, that is modifying the DefineConstants
property?
英文:
I tested with the following small test file:
<Project>
<Target Name="TestProp">
<Message Text="$(DefineConstants)" />
</Target>
</Project>
Example commands and outputs:
MSBuild Command | Output | Comment | |
---|---|---|---|
1 | msbuild test.proj /p:DefineConstants=FOO;BAR |
MSB1006 error | |
2 | msbuild test.proj /p:DefineConstants=FOO;DefineConstants=BAR |
BAR | |
3 | msbuild test.proj /p:DefineConstants=FOO,DefineConstants=BAR |
BAR | |
4 | msbuild test.proj /p:DefineConstants="FOO;BAR" |
FOO;BAR | |
5 | msbuild test.proj /p:"DefineConstants=FOO;BAR" |
FOO;BAR | |
6 | msbuild test.proj /p:DefineConstants=FOO%3BBAR |
FOO;BAR |
The /property
switch (short version /p
) to MSBuild defines an MSBuild Property. The /property
switch accepts one or more name/value pairs delimited by semicolon or comma.
Example 1 is an error because the switch is expecting a name/value pair after the semicolon. BAR
is either a name without a value or a value without a name.
The same name can appear multiple times. MSBuild just redefines the property. Essentially the last value is used. This is what is happening in examples 2 and 3.
Examples 4 and 5 use quotes to show the semicolon is part of one name/value pair.
Example 6 is hex encoding the semicolon.
Note that in examples 4, 5, and 6 the value of the DefineConstants
property doesn't include quotes.
When $(DefineConstants)
is replaced in PreprocessorDefinitions
it should be :
<PreprocessorDefinitions>FOO;BAR;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
But somewhere in your project, quotes are being added. Is there code that you haven't shown, that is modifying the DefineConstants
property?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论