안녕하세요. 이번 시간에는 이 문서를 보면서, make의 -C 옵션에 대해 알아보는 시간을 가져보겠습니다. 제가 설명할 코드는 4번째 코드입니다.

 


 먼저 man make 페이지를 보면, -C 옵션에 대한 설명이 나와 있습니다. 디렉토리를 바꾼다고 되어 있습니다. 언제? makefile을 읽거나 어떠한 작업을 하기 전에. 이게 무슨 소리일까요?

 

 폴더 구조입니다. 현재 작업 디렉토리 밑에 test1, test2가 있고, test2 밑에 Makefile이 있어요.

 

  test2 밑에 있는 Makefile을 보겠습니다. 이 파일에는 echo test2라는 것이 있어요. 그래서, makefile을 실행하면, test2가 출력됩니다. 작업 디렉토리에서 make -C test2를 해 보겠습니다.

 

보시면, 먼저 test2 디렉토리에 접근하였습니다. 제가 현재 작업하고 있었던 위치였던 /home/cho/test 밑에 있는 test2에 접근하였다는 의미입니다. 여기에서 makefile을 읽어서 실행시킵니다. echo test2가 있었으니, test2를 출력하는 명령을 실행하게 됩니다. 다음에, 디렉토리를 닫습니다. 이를 도식화 시키면 요렇습니다.

 

 원래 작업 디렉토리를 ..라 하겠습니다. 이 디렉토리 밑에 test2가 있었어요.

 

 그런데, make를 실행하기 전에 디렉토리를 test2로 바꾸어 버렸습니다. 그러면, .. 밑에 있는 test2로 작업 디렉토리를 바꿉니다. 그리고 나서, make를 실행하니, test2가 출력됩니다. 이 옵션은 단독으로 쓰이기 보다, 문서에도 나와 있는 것처럼 재귀적으로 호출할 때 많이 쓰입니다. 예를 들자면, 폴더 내에 있는 make를 먼저 수행하고 난 후에 뭔가 실행해야 한다던지.

 


 다시 디렉토리 구조를 봅시다. 작업 디렉토리 밑에 test1, test2 디렉토리가 있습니다. 다음에, test1 밑에 디렉토리 test3이 있어요. 각각의 디렉토리에는 Makefile이 있습니다.

 

공식 문서에 나온 4번째 makefile 입니다. 하나씩 봅시다. 먼저 작업 디렉토리에 있는 makefile은 서브 디렉토리로 test1과 test2를 가져요. 그래서 SUBDIRS를 test1 test2로 할당해 주었어요.  이 두 디렉토리 밑에는 makefile이 있습니다. 다음 2번째 줄에, .PHONY 타겟으로 sub와 $(SUBDIRS)를 넣어주었는데요. SUBDIR이 test1 test2이므로, .PHONY는 sub test1 test2가 됩니다. 이 3개가 파일이 아닌 그냥 작업으로 인식됩니다.

 

 이제, 3번째 줄은 sub: test1 test2가 되고, 5번째 줄은 test1 test2: .. 로 대치가 될 텐데요. 5번째 줄은 이 문서를 보면 무엇을 하는 것인지 유추할 수 있습니다. 타겟 test1은 $(MAKE) ~ 를 수행하고 test2도 마찬가지로 $(MAKE) ~ 를 수행하는 것과 같습니다. 유추 가능한 사실입니다. 고로, $(MAKE) -C $@가 test1, test2에 대해 수행이 될 건데요. $@는 target을 의미합니다. 여기까지 정리하면

 

 요래 되는 셈입니다. test1과 test2는 make -C test1, make -C test2에 의해, 각각 test1에 있는 Makefile, test2에 있는 Makefile을 실행할 겁니다. 이제, test1에 있는 Makefile 내용을 봅시다.

 

 보면, SUBDIRS가 test3이라고 되어 있어요. .PHONY로 sub와 test3을 잡아놓았고요. test1이 수행되기 위해서는 SUBDIRS가 수행되어야 한다고 되어 있어요. 결국, 이 makefile가 있는 위치의 test3의 Makefile을 실행하게 될 겁니다. $(MAKE) -C $@에 의해서요.

 

 다음에, test3 밑에 있는 makefile입니다. test3을 출력하는 것만 있네요.

 

 다음에 test2 밑에 있는 makefile입니다. test2가 출력됩니다.

 

 이제 make sub를 해 볼까요? 그러면, 재귀적으로 test1, test2에 있는 makefile들을 실행함을 볼 수 있습니다. 하위 폴더에 있는 Makefile에 미리 정의를 다 해 둔 탓에 가능했던 셈입니다.