Methods Makefile 문법 요약 2018. 8. 25. 23:09

[Makefile이 뭐야]


먼저 make라는 툴이 있는데요.


make는 프로그램을 빌드할 때 리눅스에서 주로 쓰는 자동화 도구입니다.


그리고 그 make 전용의 표준 문법이라는 것으로 빌드 과정을 서술하는 파일이 Makefile이에요.


개발중인 프로그램의 작업 디렉토리에 Makefile이라는 파일명을 하는 스크립트를 저장해 두면,


편리하게도 make가 그것을 해석해서 자동으로 빌드를 수행하도록 할 수 있습니다.


그밖에 추가적으로, 컴파일 언어로 작성된 프로그램의 빌드에 관해서는, 다음 글을 참고해 주세요.


2018/08/25 - [잡담] - 컴퓨터 프로그램의 컴파일과 링킹과 객체지향


[Makefile의 작성법 정리]


Makefile 문법을 떠올리는 데에는, 장황하고 지리멸렬한 설명은 필요가 없습니다. (!)


거두절미하고 바로 예제를 보는 것이 가장 명료한 해설이 될 것입니다.


[Makefile 예제]





[Makefile 문법 해설]


(Makefile 예시 1번)(Makefile 예시 2번)을 봐 주세요.


모든 Makefile은 세 부분으로 구성됩니다.


① 매크로: 안 중요합니다.


② 링크규칙: 가장 중요합니다. ★


③ .PHONY: 안 중요합니다.


중요한 것부터 순서대로 살펴보겠습니다.


[링크규칙]


링크 규칙이라는 이름은 내가 편의로 붙인 것이고, 보통은 그냥 규칙(Rule)이라고 부릅니다.


하지만 그냥 규칙(Rule)이라고 하면 다른 것도 가리킬 수가 있기 때문에, 나는 일단 링크 규칙으로 구분하고 있습니다.


링크 규칙타겟의 컴파일과 링킹을 어떻게 할 것인가를 정의하는 문법입니다.


여기서 타겟(Target)이란 빌드의 결과로 만들고자 하는 (목적) 파일을 뜻하며,


각각의 타겟에 대한 규칙은, 타겟, 의존관계, 명령어의 셋으로 구성됩니다.



(위의 이미지를 이용하여 설명)


- 빨간 상자: 타겟입니다. 타겟은 이름의 뒤에 콜론을 붙여서 구분합니다. (콜론은 '규칙' 문법에서 가장 크게 두드러지는 특징입니다.)


- 파란 상자: 의존관계입니다. 타겟을 만들기 위해서 필요한 재료를 공백으로 구분하여 나열합니다.


- 초록 상자: 타겟을 빌드하기 위한 Bash 명령어입니다.


이 세 가지가, 링크 규칙의 전부입니다.


[make 실행 방법]


makeMakefile에 정의된 이런 링크 규칙들 가운데에서 정확히 하나를 골라서 그 규칙에 적힌 명령어를 실행하는 역할을 합니다.


그렇기 때문에, make의 첫 번째 인자는 타겟(Makefile에 정의된 타겟의 이름)입니다.


명령어는 예를 들면 이런 식입니다.


$ make drawing.o
$ make clean


만약 make를 실행할 때 인자를 지정하지 않으면, 기본값으로 Makefile의 타겟 중 가장 위에 있는 타겟의 규칙을 수행합니다.


위의 링크 규칙 예시를 기준으로 예를 들면 아래 두 명령어는 서로 완전히 동일합니다.


$ make
$ make paint


[매크로]


Makefile의 매크로는, 보통 프로그래밍 언어의 상수 선언과 동일한 개념입니다.


이는 편의상 별명을 지어 주기 위한 용도로 쓰이는 것으로 필수가 아닌 선택 사항입니다.


매크로의 정의 구문은 보통 프로그래밍 언어에서 값을 지정하는 대입 연산 문법과 비슷한데, 예를 들면 이런 식입니다.


CC = gcc
CFLAGS = -W -Wall
TARGET = paint


이렇게 정의된 매크로를 사용하기 위해서는 다음과 같이 달러 사인(문자) 뒤 소괄호나 중괄호로 이름을 감쌉니다.


$(CFLAGS)
${CFLAGS}


위 같은 표기는 make에 의해 아래의 문자열로 치환됩니다.


-W -Wall
-W -Wall


그밖에 :=가 있는데, =가 매크로의 정의 순서에 영향을 받는 반면 :=는 그 영향을 무시하는 효력이 있습니다.


하지만 보통 =를 사용하기 때문에, 매크로를 정의하는 기호는 =뿐이라고 생각해도 무방합니다.


[.PHONY]


(Makefile 예시 2번)이나, (Makefile 예시 1번)clean이라는 타겟은 보면, 그 타겟 규칙의 명령어의 결과로 실제로 생성되지 않는 파일 이름입니다.


그런 것은 보통 더미 타겟이라고 해서, 타겟(그 타겟과 같은 이름의 파일)을 빌드하기 위한 규칙을 정의하지 않고, 단지 임의의 명령어를 실행시키기 위한 목적으로 허울뿐인 가상의 파일 이름을 빌려와서 타겟으로 한 것입니다.


그런데 이렇게 바지사장 같은 가짜 타겟을 정의하는 경우에 문제가 되는 것이, Makefile이 위치해 있고 실행되는 작업 디렉토리 내에 해당 더미 타겟과 같은 이름의 파일이 존재하면, make가 이미 빌드가 끝난 타겟이라고 판단해서 해당 더미 타겟 규칙의 명령어를 수행하지 않는다는 점입니다.


이런 문제를 대비해서 정의하는 것이 .PHONY입니다.


저에게 권한이 있다면 .PHONY는 '허수아비' 정도로 번역하고 싶네요.


.PHONY 구문을 통해서 허수아비 타겟들을 정의해 두면, make는 그 타겟이 허수아비라는 것을 인식하고, 실제로 폴더 내의 파일로 빌드가 되었는지 여부를 고려하지 않습니다.


보통 자주 (관습적으로) 쓰이는 허수아비 타겟은 아래 같은 것이 있습니다.


.PHONY: all build install run clean


$ make all
$ make build
$ make install
$ make run
$ make clean



  • 코코넛냠냠 2018.10.02 22:58 신고 LINK EDIT/DELETE REPLY

    본문에서 가장 중요한 요점을 다시 한 번 정리하면, 각각의 "규칙"은, "타겟", "레시피", 타겟을 빌드하기 위한 "명령어"의 셋으로 구성된다는 것입니다.

    그밖에 참고로, makefile에서 자주 쓰는 매크로가 있는데, 다음과 같습니다.

    CC -> C Compiler -> 어떤 컴파일러로 빌드할지 정하는 매크로입니다. 보통, gcc가 됩니다.
    CFLAGS -> Compiler Flags -> 컴파일 옵션을 정합니다. 보통, 이것을 이용해서 라이브러리 헤더의 인클루드 경로를 지정합니다.
    LDFLAGS -> Loader Flags -> 링커의 옵션을 정합니다. 보통, 이것을 이용해서 라이브러리의 바이너리 경로를 지정합니다.

    LDFLAGS라는 매크로가 이해가 잘 안 되었는데, 링커 -> 로더 -> Loader -> ld 이렇게 유추가 되는 것이더라고요.
    컴파일 과정에서 언급되는 로더, 링커, 링키지 에디터 따위는 전부 같은 것을 가리킵니다.

    ...Linux comes with its own linker, called ld. (The name is actually short for "load", and "loader" was what linkers were originally called, in the First Age of Unix, back in the 1970s.) Wikipedia mentions that there are different theories, one is "loader" one is "link editor".2014. 2. 5.
    history - Why is the Unix linker called "ld" - Software ...
    https://softwareengineering.stackexchange.com/.../why-is-the-unix-linker-called-ld

  • osdev 2020.01.19 17:46 LINK EDIT/DELETE REPLY

    좋은글 감사합니다.

  • ㅇㅇ 2021.03.28 02:48 LINK EDIT/DELETE REPLY

    자세하게 설명해주셨네요. 잘보고갑니다

Top