make 의존성에 대해 알아봅시다.

코딩/C 2022. 12. 28. 02:00

 저번 시간에 make에 대해서 배웠어요. 이번에는 의존성에 대해 배워보도록 하겠습니다. 문서에서는 prerequisites 정도로 설명하는 듯 합니다.

 


 Makefile이 요렇게 있다고 해 보겠습니다. local 환경에서는 12345를 화면에 뿌려준 다음에 test3 디렉토리를 만듭니다. prod 환경에서는 12345를 화면에 뿌려준 다음에 prod3 디렉토리를 만듭니다. 사실 이렇게 써도 별 문제는 없어 보입니다.

 

 make local을 해 보겠습니다. 그러면, 12345를 뿌려준 다음에, test3을 만드는 것을 볼 수 있어요.

 

 그런데, 잘 보면 echo 12345를 뿌려주는 것은 디렉토리를 만드는 작업 전에 일어나고 있어요. 즉, 12345를 출력해 주는 작업은, 디렉토리를 만드는 작업 이전에 수행되어야 합니다. 거꾸로 말하면, 디렉토리를 만드는 작업은 echo 12345 이후에 수행되어야 합니다. 이를 의존 관계라고 해요. 대략 A를 이루기 위해 B가 필요하다 정도로 생각하시면 되겠네요. 이를 A: B로 표기합니다.

 

  다시 Makefile을 봅시다. echo를 이루기 위해 필요한 선결 조건은 없어요. 그런데 local을 보니까 local이라는 목표를 달성하기 위해 echo가 필요해요. 그리고, prod도 목표를 달성하기 위해 echo가 필요해요. echo라는 목표를 보니까, echo "12345"라는 것이 있네요? 이는, 디렉토리를 만들기 전에 12345라는 문자열을 뿌리는 것을 먼저 해야 하기 때문입니다.

 

 

 이제 make prod를 하면, 12345를 뿌려주는 것 먼저 수행이 되고, 디렉토리를 만드는 것을 볼 수 있습니다. 이를 도식화 하면 아래와 같습니다.

 

 

 A를 하기 위해서 B를 해야 한다는 관계는 어렵지 않았어요. 사실 이 정도만 이해해도 무난하지 않을까 싶습니다.

 


 이제 조금 더 재미있는 예제를 보겠습니다. Makefile이 위와 같습니다.

 

 1.txt는 0시 13분에, 2.txt는 1시 30분에 수정되었습니다. make 2.txt를 실행하면 어떻게 될까요?

 

 cat 2.txt가 실행되지 않습니다. 대신, "2.txt"가 up to date라고만 뜹니다. 왜 그럴까요? 문서의 4.1 ~ 4.2부분을 보면 알 수 있습니다.

 

 

 의존 관계를 그려봅시다. 2.txt: 1.txt를 통해, 타겟이 2.txt가 되기 위해 필요 조건이 1.txt임을 알 수 있어요. requirements가 1.txt인 셈인데요. 1.txt는 0시 13분에, 2.txt는 1시 30분에 생성되었기 때문에, 2.txt가 더 최신입니다. target이 out of date 상태일  때 밑에 있는 명령들이 실행되는데, 1.txt보다 업데이트 된 시점이 앞에 있지 않습니다.

 

 고로 아무것도 실행되지 않습니다.

 

 

 그런데, 1.txt가 2.txt보다 더 최신일 경우에는 이야기가 달라집니다.

 

 아까와는 다르게 1.txt가 더 최신이기 때문에, 2.txt: 밑에 있는 명령들이 실행됩니다.

 

 그러면 이것을 어떻게 써 먹을 수 있을까요? 먼저 1.c에는 "ABCDE"를 출력하는 문장만 있어요.

 

 Makefile을 요래 작성해 봅시다. make local을 실행하면 1이 필요한데요. 1을 수행하기 위해서 1.c가 필요합니다. 1: 1.c의 명령어들이 실행되는 경우에, gcc -o 1 1.c가 수행되게 됩니다.

 

 먼저 1.c보다 1이 더 최신이라 해 봅시다. 그러면 1: 1.c에서 target이 필요한 파일들보다 최신이기 때문에 gcc -o 1 1.c가 수행되지 않을 겁니다.

 

 정말 그런지 make local을 볼까요? ./1만 수행됨을 알 수 있어요. 중요한 것은 gcc 명령어가 수행되지 않았다는 점입니다.

 

 

 그런데 1.c를 업데이트 하였습니다. "ABCDE" 대신 "ABCDEFG"를 출력하게끔이요. 편집을 하고 나면, 컴파일을 하지 않는 이상 수정 시각이 1보다 더 뒤에 있을 겁니다. 1: 1.c에서 target보다 requirements가 더 최신이기 때문에, 1은 out of date가 되어버립니다. 고로, 밑에 있는 gcc 명령어가 수행됩니다.

 

 

 출력 결과는 ABCDEFG가 나오게 됩니다.