C

거믄마루 2012. 11. 2. 10:02

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}} 는 다르다는 것이다.

왜 다른지는 숙제로 남겨둔다.


그럼 오늘은 여기까지...