...네, 사실 제목은 낚시입니다. 그냥 체계적인 Makefile 관리법 정도가 맞겠죠.
그럼에도 불구하고 저 제목을 쓴 이유는, 이 방법을 찾기 위한 푸념을 모 후배가 듣고는 'Makefile을 OOP 하듯이 만들다니' 라고 했기 때문...이라고 하면 좀 그런가 (...)
(본문의 범위는 automake 같은 툴과는 관련없는 내용으로, GNU Make의 동작을 기록하는 Makefile 자체에 대해서만 다룹니다.)
예제 코드는 아래와 같습니다.
$ cat test.c $ cat Makefile |
이 Makefile은 그냥 제가 애용하는 형태로, 참고만을 위해 사용하는 것임을 굳이 밝힙니다. ^^;
#warning 전처리기는 진단(DIagnostic)용으로 사용하는 것인데, Warning만을 발생하고 계속 컴파일을 진행합니다. (preprocessor to issue a warning and continue preprocessing, http://gcc.gnu.org/onlinedocs/gcc-4.9.2/cpp/Diagnostics.html)
Warning을 발생하도록 했으니 빌드 중에 당연히 Warning 메시지가 뜨겠죠.
$ make |
이 때, 코드의 안정성을 높인다든가 하는 이유로 Warning을 없애고 싶다, 그런데 Warning 메시지 외에도 메시지들이 너무 많이 출력되어 일일이 Warning 메시지에 신경쓰기 어렵다 힐 수가 있죠. (제가 그랬습니다 -0-)
그래서 만들어둔걸까요, GCC에는 Warning을 Error로 간주하여 컴파일을 중간에 멈춰버리게 할 수 있는 기능이 있습니다. (-Werror: Make all warnings into hard errors. Source code which triggers warnings will be rejected. https://gcc.gnu.org/onlinedocs/gcc-4.9.2/cpp/Invocation.html#index-Wall-130)
위 코드에서는 "CFLAGS=-Werror" 라고만 기록하면 #warning 을 에러로 잘 잡아줍니다.
$ make |
(예제에서는 에러가 발생하면 무조건 컴파일을 멈추는 옵션인 -Wfatal-errors 도 같이 넣었습니다. 보통은 기본값이 첫 에러에서 멈추도록 되어있어서 쓸모없는 옵션입니다만, 그래도 괜히... ^^;)
여기까지가 서론입니다. 객체지향이고 뭐고 Makefile 관리하는 방법과는 전혀 관련이 없는 내용이죠. -_-;
위의 -Werror 옵션을 프로젝트 전체에 적용하려고 합니다. 그런데 프로젝트 모듈에 따라 Warning 메시지가 너무 많은 경우도 있고, 끌어다 쓰는 오픈소스에 Warning이 너무 많은데다 추후 유지보수를 위해 내가 임의로 수정하기도 어려운 경우도 있을겁니다. 이런 경우에는 Makefile을 각각 만들어줘야겠죠. 저 옵션을 넣은 파일과 넣지 않은 파일로.
근데 모듈이 한두개도 아니고, 추후에 추가할 모듈에도 적용해야 할텐데 이거 빼먹으면 오랜 시간이 지나면 또 Warning 떡칠을 할테고...< 그래서 저 옵션을 기본값으로 넣고 싶은거죠.
이제 최상위 디렉토리에 옵션들을 저장할 파일을 하나 만듭니다. 이 파일에 저장할 옵션은 적용할 Makefile 빌드 옵션들이 되겠습니다. 예를 들면 -Wall 이나 -g 같은 것들이 될 수 있겠죠. (물론 다른 옵션들도 가능합니다. :D)
그러고나면 원래 만들었던 Makefile에 include <파일명>이라는 줄만 추가해주면 됩니다. 그러면 <파일명>에 지정된 파일로부터 변수 등을 읽어오는 방식인거죠. 그럼 include 할 파일 안에 -Werror 옵션을 가진 변수를 만들어 Makefile에 선택적으로 그 변수를 사용하면 끝!
...하지만 그렇게 쉽지가 않은게, include 할 파일 안에 여러 변수들을 담을 수 있다보니, -Werror 옵션 하나 사용 안하겠다고 파일을 안가져올 수도 없고... 물론 별도 파일을 만들어서 적용할 수도 있지만, 관리할 파일이 하나 늘어나는게 번거롭기도 하고요. 그래서 준비했습니다!!
GNU Make에는 꽤 많은 문자열 관련 함수들이 있습니다. (저도 이번 작업 전에는 위의 예제파일 수준으로만 쓰고 있었는데, 엄청나더군요. :O 자세한 내용은 링크 참고 바랍니다.)
그중에 문자열을 걸러주는 함수가 있는데, 바로 filter와 filter-out 입니다.
|
위 내용들을 예제에 적용시키면 아래 내용처럼 됩니다.
$ cat vars $ cat Makefile
|
수정된 부분은 밑줄 표시 했습니다.
NEW_CFLAGS 에는 CFLAGS에서 EXCEPTS의 내용들이 빠진 결과가 저장됩니다. 그리고 이 값이 CFLAGS에 새로 저장하는데, 이것은 저 두 줄 외에는 다른 모듈의 Makefile과의 차이를 최소화하기 위한 작업입니다.
많은 디렉토리들을 이용하여 예제를 작성하는 부분은 생략되었지만,
결과적으로는 1. include를 통해 기본값 지정 2. filter와 filter-out을 사용한(제가 제시한 사례에서는 filter-out만 사용해도 될 것으로 보입니다.) 예외 상황에 대한 처리 정도가 되겠습니다.
'Programming Languages' 카테고리의 다른 글
[추상자료형] 집합(Set) (0) | 2016.09.13 |
---|---|
glibc/open_memstream() 소개 (0) | 2015.04.12 |
Expect cross-compile 문제 해결 (0) | 2013.05.20 |