2011-10-28 1 views
7

주제가 말했듯이 빌드하는 동안 특정 명령을 실행하고 출력을 전 처리기 매크로의 정의로 만들 수 있어야합니다.과 xcode, 명령의 출력에서 ​​전 처리기 매크로를 정의하는 방법은 무엇입니까?

는 지금, 나는 몇 가지 사용자 정의 변수를 (project.pbxproj)에 다음과 같이 나는, 매크로 정의를 채우기 위해 그 값을 사용할 수 있어요 :

GCC_PREPROCESSOR_DEFINITIONS = (
"캐릭터 라인 화 (X) = @ # x ",
"_MACRO = STRINGIFY ($ {MACRO}) ",
);
MACRO = foo;

MACRO를 체계 당 다른 값 (예 : Debug vs. Release)으로 설정할 수 있습니다. 이는 매우 유용합니다. 하지만 명령을 실행하여 설정하는 방법을 알 수는 없습니다.

답변

11

나는 3 가지 옵션을 생각할 수 있습니다

환경 변수 : 당신이 명령 줄에서 빌드하는 경우 당신이 빌드 명령을 호출하기 전에 변수 (export ENVMACRO=superfoo)를 내보내고 엑스 코드 구성 파일 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.macroMACRO=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

감사합니다 - 두 번째 옵션은 본질적으로 내가 함께 간 것입니다 - 제 경우에는 모든 빌드에서 명령을 실행하고 싶었습니다. 유일한 주름은 내용이 새로 생성 된 내용과 동일하지 않으면 (종속성 변경을 피하기 위해) 실제 헤더 파일에 쓰지 않는다는 것입니다. 나는 특히 제 3의 옵션을 좋아한다. – michael

0

궁금한 점이 있다면 필자가 사용했던 솔루션은 내가 원하는 매크로를 사용하여 수동으로 헤더 파일을 생성하는 스크립트를 실행하는 새로운 빌드 단계를 추가하는 것입니다. 그것은 우아하지 않고, 나는 여전히 더 나은 것을 선호 할 것이지만 그것은 효과가 있습니다.

+1

솔루션에 대한 축하. 다른 사람들이 귀하의 성공을 통해 배울 수 있도록 귀하의 답변을 '수락'으로 표시하십시오. 건배 ~ –

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