= 재귀적 확장매크로(recursively expanded)
장점: recursive 확장, 정의가 뒤에 있어도 됨.
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar
단점: 자기 자신을 assign 못함
CFLAGS = $(CFLAGS) -O
make 무한루프 에러
:= 단순확장매크로(simply expanded)
장점: shell 함수와 := 를 결합해서 사용할 때 유용, 딱 한번 확장되고 끝
ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
단점: 공백문자를 변수값으로 사용할 수 있다.조심해서 써야한다.
nullstring :=
space := $(nullstring) # end of the line
space 값은 하나의 스페이스이다
dir := /foo/bar # directory to put the frobs in
dir 변수의 값은 '/foo/bar ' 푸바와 4개 스페이스이다.
+= 기존 매크로에 추가
?= 정의안된 매크로일 때만 정의(conditional variable assignment operator)
dmake
http://network.hanb.co.kr/view.php?bi_id=385
컴파일 과정을 병렬화합니다
CPU 사용률을 높인다.
리눅스의 make -j [thread_number]와 같다.
장애 : make warning
test -e include/linux/autoconf.h -a -e include/config/auto.conf || ( \
echo; \
echo " ERROR: Kernel configuration is invalid."; \
echo " include/linux/autoconf.h or include/config/auto.conf are missing."; \
echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo; \
/bin/false)
리눅스 소스에 ~linux/Documentations/sparse.txt라는 파일이 있습니다. 문서 제목은 "Using sparse for
typechecking"입니다. sparse는 "semantic
parser"에서 따온 이름으로, 그 패키지 안에 들어있는 sparse라는 이름의 프로그램은 static analyzer라고 합니다.
sparse.txt 문서의 내용처럼, 커널 소스에서 "make C=1"이나 "make C=2"라고 명령을 주면 C 소스 파일에 대해
sparse 프로그램을 실행합니다. 그 때 "CHECKFLAGS=-D__CHECKER__ -D__CHECK_ENDIAN__" 옵션을 함께 주면
소스 코드에서 "__attribute__((bitwise))"가 활성화 된 상태로 sparse 프로그램이 이를 분석하게 됩니다. 그래서
"__attribute__((bitwise))" 속성이 일치하지 않는 변수 할당 등을 발견하면 다음과 같은 식의 메시지를 출력합니다.
validation/foul-bitwise.c:9:9: warning: restricted
degrades to integer
validation/foul-bitwise.c:9:15: warning: restricted
degrades to integer
validation/foul-bitwise.c:19:9: error: incompatible types
for operation (-)
validation/foul-bitwise.c:19:9: argument has type
restricted unsigned short [usertype] a
리누스가 sparse를 작성하기 시작한 건 소스 내에서 사용자 메모리 공간에 대한 포인터와 커널 메모리 공간에 대한 포인터가 섞여 쓰이는
문제를 해결하기 위해서였다고 합니다. 컴파일러로는 탐지하기 힘든 코딩 상의 오류이죠. ~linux/include/linux/compiler.h에
그 내용이 들어가 있습니다. 그리고 이후 그걸 확장해서 엔디안 검사까지 하도록 확장된 듯 합니다.
3항 연산자다 (조건 ? then : else)
KBUILD_SRC 가 empty 면 false 로 간주. CURDIR 값을 사용
KBUILD_SRC 가 true 면 KBUILD_SRC 값을 사용
http://www.gnu.org/software/make/manual/make.html
8.4 Functions for Conditionals
There
are three functions that provide conditional expansion. A key aspect of these
functions is that not all of the arguments are expanded initially. Only those
arguments which need to be expanded, will be expanded.
$(if
condition,then-part[,else-part])
The if function provides support for
conditional expansion in a functional context (as opposed to the GNU
make makefile conditionals such as ifeq (see Syntax of Conditionals).
The first argument, condition, first has all preceding and
trailing whitespace stripped, then is expanded. If it expands to any non-empty
string, then the condition is considered to be true. If it expands to an empty
string, the condition is considered to be false.
If the condition is true then the second argument, then-part, is
evaluated and this is used as the result of the evaluation of the entire
if function.
If the condition is false then the third argument, else-part, is
evaluated and this is the result of the if function. If there is no
third argument, the if function evaluates to nothing (the empty
string).
Note that only one of the then-part or the else-part
will be evaluated, never both. Thus, either can contain side-effects (such as
shell function calls, etc.)
$(or
condition1[,condition2[,condition3...]])
The or function provides a
“short-circuiting” OR operation. Each argument is expanded, in order. If an
argument expands to a non-empty string the processing stops and the result of
the expansion is that string. If, after all arguments are expanded, all of them
are false (empty), then the result of the expansion is the empty string.
$(and
condition1[,condition2[,condition3...]])
The and function provides a
“short-circuiting” AND operation. Each argument is expanded, in order. If an
argument expands to an empty string the processing stops and the result of the
expansion is the empty string. If all arguments expand to a non-empty string
then the result of the expansion is the expansion of the last argument.