2011-10-28 19 views
7

トピックで言うように、ビルド中に特定のコマンドを実行し、その出力をプリプロセッサマクロの定義にすることができます。とxcode、コマンドの出力からプリプロセッサマクロを定義する方法は?

は今のところ、私は(project.pbxprojで)いくつかのユーザ定義変数を持っていると私は次のように、マクロ定義を埋めるためにそれらの値を使用することができる午前:

GCC_PREPROCESSOR_DEFINITIONS =(
「文字列化(X) = @#x "、
" _MACRO = STRINGIFY($ {MACRO}) "、
);
MACRO = foo;

MACROをスキームごとに異なる値に設定することができます(たとえば、デバッグとリリースの比較)。これは非常に便利です。しかし、コマンドを実行して設定する方法を理解できません。

答えて

11

私は3つのオプションを考えることができます:

環境変数:あなたは、コマンドラインからビルドする場合は、ビルドコマンドを呼び出す前に、変数(export ENVMACRO=superfoo)をエクスポートし、Xcodeの設定ファイルOTHER_CFLAGS=-DMACRO=$(ENVMACRO)でそれを使用することができます。ターゲットを.xcconfigファイルで設定する必要があります。

実行スクリプト作成フェーズ:ヘッダーファイルを生成するカスタムスクリプト。

MACROVALUE=$(run-command-to-obtain-value) 
echo "#define MACRO ($MACROVALUE)" > $(SRCROOT)/path/to/header.h 

私のテストでは、正しくコンパイルするためには、空のヘッダファイルが必要です。 sedまたは他のコマンドを使用して既存のファイルを変更するなどの他のオプションがあります。

カスタムビルドルール:入力ファイルを処理して出力ファイルを作成するカスタムスクリプト。 に似ています。スクリプトは、入力ファイルが変更されたときにのみスクリプトを実行するため、段階的に構築されていますが、やや優れています。たとえば、.macroファイルを作成し、それを処理してヘッダーファイルを更新します。

[Xcode]> [ターゲット]> [ビルドルール]で、新しいカスタムルールを追加します。

プロセス*.macro

カスタムスクリプト:

HEADER="${SRCROOT}/Config.h" 
cd ${SRCROOT} 
echo "// Do not edit" > $HEADER 
cat "${INPUT_FILE_PATH}" | while read line 
do 
    macro="`echo $line | cut -d= -f1`" 
    cmd="`echo $line | cut -d= -f2-`" 
    value=$($cmd) 
    echo "#define ${macro} @\"${value}\"" >> $HEADER 
done 
echo "// Updated on "`date` >> $HEADER 

出力ファイル$(SRCROOT)/Project.h

Project.macroがペアMACRO=one-liner-commandが含まれています。これら二つの非センス例のように:

COMMIT=git log --pretty=format:%h -n 1 
BUILDYEAR=date +%Y 

生成されたファイルは、次のようになります。

// Do not edit 
#define COMMIT @"c486178" 
#define BUILDYEAR @"2011" 
// Updated on Sat Oct 29 14:40:41 CEST 2011 

たびProject.macro変化を、生成されたヘッダが更新されます。

+0

ありがとう - 2番目の選択肢は本質的に私が行ったことです - 私の場合、私はすべてのビルドでコマンドを実行したい。唯一の皺は、その内容が(依存関係の変更を避けるために)新しく生成された内容と同じでない場合、私は実際のヘッダファイルに書き込まないということです。私は特に同様に3番目のオプションが好きです。 – michael

0

好奇心が強い方は、私が使用したソリューションは、必要なマクロを使って手動でヘッダファイルを生成するスクリプトを実行する新しいビルドフェーズを追加することです。それはエレガントではない、と私はまだより良いものを好むだろうが、それは動作します。

+1

解決策のおめでとうございます。あなたの答えが「受け入れられた」とマークして、他の人があなたの成功から学ぶかもしれないようにしてください。乾杯〜 –

0

私は(リリースのRELEASE、デバッグ用などDEBUG)の設定を構築し、よりよい解決策は、プロジェクトに一つだけプリプロセッサマクロを宣言することだと思うし、その後、あなたのPrefix.pchファイルにあなたが決めるために、値をチェックすることができます定義する他のマクロは次のとおりです。例:

// Use NSLOG and NSASSERT so that they are only output in debug mode 
#ifdef DEBUG 

//#warning You are running in Debug mode 
#define NSLOG NSLog 
#define NSASSERT NSAssert 
#define NSASSERT1 NSAssert1 

#else 

#define NSLOG if(false)NSLog 
#define NSASSERT(X, Y) \ 
if(!(X)) {   \ 
NSLogOkay(Y);  \ 
}     
#define NSASSERT1(X, Y, Z) \ 
if(!(X)) {    \ 
NSLogOkay(Y, Z);  \ 
}      

#endif 
関連する問題