web-dev-qa-db-ja.com

msbuild:コマンドラインで特定のプリプロセッサ#defineを設定します

C++ファイルには、次のようなコードがあります。

#if ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif

MsbuildコマンドラインでこのACTIVE定義を1に設定したいと思います。

これを試しましたが、機能しません。

msbuild /p:DefineConstants="ACTIVATE=1"

何か案が?

21
acemtp

私はパーティーに少し遅れていますが(わずか4年ほど)、プロジェクトでこの問題を回避する必要があり、修正を探しているときにこの質問に出くわしました。私たちの解決策は、_/D_が定義されている環境変数を、VisualStudioの[追加オプション]ボックスと組み合わせて使用​​することでした。

  1. Visual Studioで、環境変数マクロ$(ExternalCompilerOptions)を、プロジェクトオプション-> C/C++->コマンドラインの下の追加オプションに追加します(デバッグ構成とリリース構成の両方を覚えておいてください)
  2. Msbuildを呼び出す前に、環境変数を設定してください。 _/D_コンパイラオプションを使用してマクロを定義します
_    c:\> set ExternalCompilerOptions=/DFOO /DBAR 
    c:\> msbuild
_

アイテム#1は、vcxprojファイルで次のようになります。

_    <ClCompile>
      <AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
    </ClCompile>
_

これはVS2010で機能します。さまざまなビルドスクリプトからmsbuildを駆動するため、環境変数の醜さが少し隠されています。定義を特定の値(_/DACTIVATE=1_)に設定する必要がある場合に、これが機能するかどうかはテストしていないことに注意してください。うまくいくと思いますが、そこに複数の「=」があるのではないかと心配しています。

H ^ 2

27
bigh_29

C++プロジェクト(およびソリューション)は(まだ?)MSBuild環境に統合されていません。ビルドプロセスの一部として、 VCBuild task が呼び出されます。これは、 vcbuild.exe の単なるラッパーです。

あなたは出来る :

  • _ACTIVATE=1_が定義されるソリューションの特定の構成を作成し、 devenv.exe/ ProjectConfig スイッチを使用)でコンパイルします。
  • VCBuildタスク への独自の呼び出しをラップする独自のターゲットファイルを作成します(Overrideパラメーターを参照)。
  • msbuild.exeの代わりにvcbuild.exeを使用します。 (vcbuild.exeにはOverrideパラメーターに相当するものがないようです)。

プロジェクトファイルを少し調整しない限り、ソリューションはC#プロジェクトでも機能しないことに注意してください。参考までに、これを行う方法は次のとおりです。

  • <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />を呼び出す前に、次のコードを追加します。
<PropertyGroup Condition = "'$(MyConstants)'!= ''"> 
 <DefineConstants> $(DefineConstants); $(MyConstants)</ DefineConstants> 
 </ PropertyGroup>
  • 次のようにMSBuildを呼び出します。
msbuild/p:MyConstants = "ACTIVATE = 1"
10
Mac

私はあなたが欲しいと思います:

/p:DefineConstants=ACTIVATE
8
Matt Howells

true/falseだけでなく)定数を定義する必要がある場合は、次の方法で定義できます。

コマンドライン:

MSBuild /p:MyDefine=MyValue

Vcxprojファイル内(必要な場所に応じて、セクション<ClCompile>;および/または<ResourceCompile>内):

<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>

MSBuildの呼び出しで/p:MyDefine=MyValueを指定しない場合、空の文字列がMY_DEFINEマクロに割り当てられることに注意してください。よろしければ、それだけです。そうでない場合は、読み続けてください。

対応するMSBuildパラメーターが指定されていない場合にマクロを未定義にする方法

空の文字列ではなくMY_DEFINEマクロを未定義にするには、次のトリックを使用できます。

<ClCompile>
  ....
  <PreprocessorDefinitions>_DEBUG;_CONSOLE;OTHER_UNCONDITIONAL_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  <PreprocessorDefinitions Condition="'$(MyDefine)'!=''">MY_DEFINE=$(MyDefine);%(PreprocessorDefinitions)</PreprocessorDefinitions>
  ....
</ClCompile>

最初のPreprocessorDefinitionsは、無条件マクロを定義します。 2番目のPreprocessorDefinitionsは、MyDefineが空の文字列でない場合に、MY_DEFINEマクロを追加で定義します。これをテストするには、次のコードをcppファイルに配置します。

#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)

#ifndef MY_DEFINE
#pragma message("MY_DEFINE is not defined.")
#else
#pragma message("MY_DEFINE is defined to: [" STRINGIZE(MY_DEFINE) "]")
#endif

と実行中:

> MSBuild SandBox.sln /p:Configuration=Debug /p:MyDefine=test /t:Rebuild
...
MY_DEFINE is defined to: [test]
...

> MSBuild SandBox.sln /p:Configuration=Debug /p:MyDefine= /t:Rebuild
...
MY_DEFINE is not defined.
...

> MSBuild SandBox.sln /p:Configuration=Debug /t:Rebuild
...
MY_DEFINE is not defined.
...
7
4LegsDrivenCat

CL環境変数を使用してプリプロセッサマクロを定義します

MSBUILDを呼び出す前に、次のように環境変数「CL」を「/ D」オプションで設定するだけです。

set CL=/DACTIVATEACTIVATEを定義する

「#」記号を使用して「=」記号を置き換えることができます

set CL=/DACTIVATE#1はACTIVATE = 1を定義します

次に、MSBUILDに電話をかけます

CL環境変数の詳細については、次のURLを参照してください。 https://msdn.Microsoft.com/en-us/library/kezkeayy(v = vs.140).aspx

3
Jay

私もこれを行う必要がありました-アプリの2つの異なるバージョンをビルドできる必要があり、VCBUILDを使用してビルドをスクリプト化できるようにしたかったのです。 VCBUILDには/ overrideコマンドラインスイッチがありますが、#if条件付きコンパイルを使用してテストできる#defineシンボルを変更するために使用できるかどうかはわかりません。

私が思いついた解決策は、環境変数の状態に基づいてシンボルを#defineするヘッダーファイルを作成する簡単なユーティリティを作成し、ビルド前のステップからユーティリティを実行することでした。 VCBUILDステップを実行する前に、スクリプトは環境変数を設定し、アプリ内のファイルに「タッチ」して、ビルド前のステップが確実に実行されるようにします。

はい、それは醜いハックですが、それは私が思いつくことができた最高でした!

0
Bruce Ikin

VS2010以降の場合、元のプロジェクトファイルの変更を必要としないソリューションについては、私の回答 ここ を参照してください。

0
stijn

@ bigh_29が述べたように、環境変数を使用してプリプロセッサを定義または未定義にします。

彼がプリプロセッサの定義を解除する方法を提案したのは、実際には/ ACTIVATEです。

このように、ACTIVATEに一致するプリプロセッサはすべて否定され、コンパイラは#if ACTIVATE#endifエンクロージャを通過しません。

0
Anthony

そのような古い質問に答えるのは悪い考えかもしれませんが、最近私は同様の問題をグーグルで検索し、このトピックを見つけました。いくつかのビルドシステム用のcmdスクリプトを作成しましたが、解決策を見つけることに成功しました。私はそれを将来の世代のためにここに残します(:

@acemtpの問題によると、私の解決策は次のようになります。

@echo off

:: it is considered that Visual Studio tools are in the PATH
if "%1"=="USE_ACTIVATE_MACRO" (
    :: if parameter USE_ACTIVATE_MACRO is passed to script
    :: the macro ACTIVATE will be defined for the project
    set CL=/DACTIVATE#1
)
call msbuild /t:Rebuild /p:Configuration=Release

UPD:set CL=/DACTIVATE=1を使おうとしましたが、うまくいきましたが、 公式ドキュメント番号記号の使用をお勧めします

0
Lex Sergeev