在VS项目文件中,使用分号扩展变量的预处理器定义。

huangapple go评论56阅读模式
英文:

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:

  &lt;PropertyGroup Label=&quot;Globals&quot;&gt;
    &lt;DefineConstants&gt;&lt;/DefineConstants&gt;
  &lt;/PropertyGroup&gt;
...
  &lt;ItemDefinitionGroup Condition=&quot;&#39;$(Configuration)|$(Platform)&#39;==&#39;Release|x64&#39;&quot;&gt;
    &lt;ClCompile&gt;
      &lt;PreprocessorDefinitions&gt;$(DefineConstants);WIN32;_WINDOWS;%(PreprocessorDefinitions)&lt;/PreprocessorDefinitions&gt;

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 &quot;FOO;BAR&quot; /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 &quot;FOO;BAR&quot; wrong: not split into multiple /D
/p:DefineConstants=&quot;FOO;BAR&quot; /D &quot;\&quot;FOO&quot; /D &quot;BAR\&quot;&quot; wrong: split, but includes \&quot;
/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=&quot;FOO;BAR&quot; FOO;BAR
5 msbuild test.proj /p:&quot;DefineConstants=FOO;BAR&quot; 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:

&lt;Project&gt;
  &lt;Target Name=&quot;TestProp&quot;&gt;
    &lt;Message Text=&quot;$(DefineConstants)&quot; /&gt;
  &lt;/Target&gt;
&lt;/Project&gt;

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=&quot;FOO;BAR&quot; FOO;BAR
5 msbuild test.proj /p:&quot;DefineConstants=FOO;BAR&quot; 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 :

      &lt;PreprocessorDefinitions&gt;FOO;BAR;WIN32;_WINDOWS;%(PreprocessorDefinitions)&lt;/PreprocessorDefinitions&gt;

But somewhere in your project, quotes are being added. Is there code that you haven't shown, that is modifying the DefineConstants property?

huangapple
  • 本文由 发表于 2023年5月6日 18:29:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188396.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定