使用xcode,如何从命令输出定义预处理器宏?

时间:2011-10-28 18:09:18

标签: xcode macros preprocessor

正如主题所说,我希望能够在构建期间运行特定命令,并使其输出成为预处理器宏的定义。

现在,我有几个用户定义的变量(在project.pbxproj中),我可以使用它们的值来填充宏定义,如下所示:

GCC_PREPROCESSOR_DEFINITIONS =(
 “字符串(X)= @#X”,
 “_MACRO =字符串化($ {MACRO})”,
);
MACRO = foo;

我可以将MACRO设置为每个方案的不同值(例如Debug与Release),这非常有用。但是,我无法弄清楚如何通过运行命令来设置它。

3 个答案:

答案 0 :(得分: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更改时,生成的标头都会更新。

答案 1 :(得分:0)

如果有人好奇,我使用的解决方案是添加一个新的构建阶段,该阶段运行一个脚本,该脚本手动生成带有我想要的宏的头文件。它不优雅,我仍然会更喜欢更好的东西,但它确实有效。

答案 2 :(得分:0)

我认为更好的解决方案是在项目构建设置中声明一个预处理器宏(例如DEBUG用于调试,RELEASE用于发布),然后在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