make 스크립트를 작성할때 컴파일 옵션을 주다보면 헤더나 라이브러리를 많이 링크하는 경우가 종종 생긴다.
예를 들어 다음과 같이 GTK 라이브러리를 사용한다고 하면
all: test test: CFLAGS += -I /usr/include -I /usr/local/include -I /usr/local/include/gtk-2.0 -I /usr/local/lib/gtk-2.0/include -I /usr/local/include/atk-1.0 -I /usr/local/include/cairo -I /usr/local/include/gdk-pixbuf-2.0 -I /usr/local/include/pango-1.0 -I /usr/local/include/glib-2.0 -I /usr/local/lib/glib-2.0/include -I /usr/local/include/freetype2 -I /usr/local/include/libpng14 test: LDFLAGS += -L /usr/lib -L /usr/local/lib test: LDLIBS += -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl test: test.o |
라이브러리관련 옵션 LDFLAGS 은 그럭 저럭 몇개 안되니 그나마 봐줄만 하다. 그러나 CFLAGS 와 LDLIBS 는 어떤가? 이걸 그대로 보고만 있을건가?
물론 역슬래시(\)를 사용하여 다음과 같이 깔끔하게 정리할 수 있기는 하다.
all: test test: CFLAGS += \ -I /usr/include \ -I /usr/local/include \ -I /usr/local/include/gtk-2.0 \ -I /usr/local/lib/gtk-2.0/include \ -I /usr/local/include/atk-1.0 \ -I /usr/local/include/cairo \ -I /usr/local/include/gdk-pixbuf-2.0 \ -I /usr/local/include/pango-1.0 \ -I /usr/local/include/glib-2.0 \ -I /usr/local/lib/glib-2.0/include \ -I /usr/local/include/freetype2 \ -I /usr/local/include/libpng14 test: LDFLAGS += \ -L /usr/lib \ -L /usr/local/lib test: LDLIBS += \ -lgtk-win32-2.0 \ -lgdk-win32-2.0 \ -latk-1.0 \ -lgio-2.0 \ -lpangowin32-1.0 \ -lgdi32 \ -lpangocairo-1.0 \ -lgdk_pixbuf-2.0 \ -lpango-1.0 \ -lcairo \ -lgobject-2.0 \ -lgmodule-2.0 \ -lgthread-2.0 \ -lglib-2.0 -lintl test: test.o |
보기는 좋다... 그러나 그래도 뭔가 어색하며 각 헤더파일과 라이브러리에 뭔가 주석이라도 달라고 한다면 그야말로 짜증이 밀물처럼 밀려온다. 어떻게 주석을 달아줄 것인가?
make 유틸리티는 이런 문제를 해결할 수 있게 일련의 문자열 처리함수들을 제공한다. 오늘은 위 문제를 해결할 수 있는 획기적인 함수 하나를 소개하려 한다.
바로 addprefix 함수이다.
addprefix 함수의 프로토타입은 다음과 같다.
${addprefix prefix, name...} |
문자열 name 은 여러개가 올 수 있으며 각각의 name 변수안의 문자열들 앞에 prefix 문자열을 붙인다.
예를 들어 INCLUDES 라는 변수가 다음과 같다고 하면
INCLUDES = . /usr/include /usr/local/include |
addprefix 함수를 사용해서 "-I" 문자열을 각 패스앞에 붙이려면 다음과 같이 하면 된다.
${addprefix -I , ${INCLUDES}} 또는 ${addprefix -I , $INCLUDE} |
위 함수가 실행되면 INCLUDE 변수의 값은 다음과 같이 바뀌게 된다.
-I . -I /usr/include -I /usr/local/include |
그럼 이 함수를 이용해서 복잡하기만 했던 CFLAGS 와 LDFLAGS 를 정리해보자.
all: test test: INCLUDES = test: INCLUDES += /usr/include test: INCLUDES += /usr/local/include test: INCLUDES += /usr/local/include/gtk-2.0 test: INCLUDES += /usr/local/lib/gtk-2.0/include test: INCLUDES += /usr/local/include/atk-1.0 test: INCLUDES += /usr/local/include/cairo test: INCLUDES += /usr/local/include/gdk-pixbuf-2.0 test: INCLUDES += /usr/local/include/pango-1.0 test: INCLUDES += /usr/local/include/glib-2.0 test: INCLUDES += /usr/local/lib/glib-2.0/include test: INCLUDES += /usr/local/include/freetype2 test: INCLUDES += /usr/local/include/libpng14 test: CFLAGS += ${addprefix -I , ${INCLUDES}} test: LIBPATHS = test: LIBPATHS += /usr/lib test: LIBPATHS += /usr/local/lib test: LDFLAGS += ${addprefix -L , ${LIBPATHS}} test: LIBS = test: LIBS += gtk-win32-2.0 test: LIBS += gdk-win32-2.0 test: LIBS += atk-1.0 test: LIBS += gio-2.0 test: LIBS += pangowin32-1.0 test: LIBS += gdi32 -lpangocairo-1.0 test: LIBS += gdk_pixbuf-2.0 test: LIBS += pango-1.0 test: LIBS += cairo test: LIBS += gobject-2.0 test: LIBS += gmodule-2.0 test: LIBS += gthread-2.0 test: LIBS += glib-2.0 test: LIBS += intl test: LDLIBS += ${addprefix -l , ${LIBS}} test: test.o |
어떤가? 이 역시 세련되지 않은가?
한가지 주의할 점은 ${addprefix -l , ${CFLAGS}} 와 ${addprefix -l, ${CFLAGS}} 는 다르다는 것이다.
왜 다른지는 숙제로 남겨둔다.
그럼 오늘은 여기까지...