make
에는 몇 가지 묵시적인 규칙(implicit rules) 가 있다:
n.o
는 $(CC) -c $(CPPFLAGS) $(CFLAGS)
명령에 의해 n.c
로부터 자동적으로 생성될 수 있다.n.o
는 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
명령에 의해 n.cc
혹은 n.cpp
로부터 자동적으로 생성될 수 있다.n
은 $(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBDS)
명령을 실행함으로써 n.o
로부터 자동적으로 생성될 수 있다.묵시적 규칙에 의한 중요한 변수들은 다음과 같다:
CC
: C 프로그램 컴파일을 위한 프로그램; 기본적으로 cc
CXX
: C++ 프로그램 컴파일을 위한 프로그램; 기본적으로 g++
CFLAGS
: C 컴파일러에게 추가적으로 전달해야 하는 플래그들CXXFLAGS
: C++ 컴파일러에게 추가적으로 전달해야 하는 플래그들CPPFLAGS
: C 전처리기에게 추가적으로 전달해야 하는 플래그들LDFLAGS
: 링커의 호출을 상정했을 때 컴파일러에게 추가적으로 전달해야 하는 플래그들CC = gcc # Flag for implicit rules
CFLAGS = -g # Flag for implicit rules.
# Implicit rule #1: blah is built via the C linker implicit rule
# Implicit rule #2: blah.o is built via the C compilation implicit rule, because blah.c exists.
blah: blah.o
blah.c:
echo "int main() { return 0; }" > blah.c
clean:
rm -f blah*
정적 패턴 규칙은 makefile
을 간소화하는 또 다른 방법 중 하나이다:
targets...: target-pattern: prereq-patterns ...
위 makefile
의 정수(精髓)는 주어진 target
이 target-pattern
에 의해 매치되어진다는 것이다. 무엇이든 일치된 것을 stem
이라 부른다. 이러한 stem
은 target
의 prereq
를 생성하기 위해 prereq-pattern
을 통해서 치환되어진다.
objects = foo.o bar.o all.o
all: $(objects)
# These files compile via implicit rules
foo.o: foo.c
bar.o: bar.c
all.o: all.c
all.c:
echo "int main(void) { return 0; } " > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
위와 같이 manual
하게 작성된 makefile
을 정적 패턴 규칙을 통해 더 efficient
하게 작성할 수 있다:
objects = foo. o bar.o all.o
all: $(objects)
# These files compile via implicit rules
# Syntax - targets ...: target-pattern: prereq-patterns ...
# IN the case of the first target, foo.o, the target-pattern matches foo.o and sets the "stem" to be "foo".
# It then replaces the '%' in prereq-patterns with that stem
$(objects): %.o: %.c
all.c:
echo "int main(void) { return 0; }" > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
obj_files = foo.result bar.o lose.o
src_files = foo.raw bar.c lose.c
all: $(obj_files)
$(filter %.o,$(obj_files)): %.o: %.c
echo "target: $@ prereq: $<"
$(filter %.result,$(obj_files)): %.result: %.raw
echo "target: $@ prereq: $<"
%.c %.raw:
touch $@
clean:
rm -f $(src_files)
filter
함수를 통해 위와 같은 rules
를 작성할 수 있다. foo.result
는 obj_files
에 속하지만 obj_files
에 파일들과는 다른 rule
을 적용 받는다.
패턴 규칙은 두 가지 방식으로 볼 수 있다:
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
패턴 규칙은 target
안에 %
를 가진다. 이러한 %
는 비어있지 않은 모든 문자열과 매칭되며 그 외에 문자들은 그것 자체로 매칭된다. prerequisite
내의 %
는 target
에서 %
에 의해 일치된 동일한 stem
을 나타낸다.
# Define a pattern rule that has no pattern in the prerequisites.
# This just creates empty .c files when needed.
%.c:
touch $@
이중콜론 규칙은 정말 드물게 사용되지만 같은 target
에 대해 복수의 rule
을 적용하는 것을 허용한다. 만일 이하의 예시가 단일 콜론이였다면, 경고 메세지가 출력되며 두 번째 명령어만 실행될 것이다:
all: blah
blah::
echo "hello"
blah::
echo "hello again"