Search
Duplicate

[한글로 Makefile 가볍게 읽어보기] 02 - 1. Makefile 작성

간단소개
Gnu Makefile 공식문서를 읽어보자
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Makefile
Scrap
태그
makefile
9 more properties

Makefiles 작성

목표

Makefile은 무엇을 담고 있는가?

Makefile은 5가지 종류의 것을 담고 있다.
1.
explicit rule (명시적 규칙)
targets의 규칙이라고 하는 하나 이상의 파일을 remake하는 시기와 방법을 나타낸다.
이 파일은 target이 의존하는 다른 파일들인 target의 전제 조건들이 나열되어 있으며 target을 만들거나 업데이트하는 데 사용할 수 있는 방법도 나와있다.
2.
implicit rule (암묵적 규칙)
파일 클래스를 이름에 따라 remake하는 시기와 방법을 나타낸다.
대상이 target과 유사한 이름을 가진 파일에 어떻게 의존할 수 있는지 설명하고 그러한 target을 만들거나 업데이트하는 방법을 제공한다.
3.
variable definition (변수 정의)
텍스트로 대체할 수 있는 변수의 텍스트 문자열 값을 지정하는 줄
simple Makefile 예제에서 object에 대한 변수 정의를 모든 object files의 목록으로 보여준다.
4.
directive (지시자)
make가 Makefile을 읽으면서 특별한 어떤 것을 하도록 하는 명령
다른 Makefile을 읽는다.
Makefile의 일부를 사용할 것인지 아니면 무시할것인지 결정
여러 줄이 포함된 동사형 문자열에서 변수 정의
5.
주석
makefile 줄에 있는 ‘#’이 주석을 시작한다.
‘ \ ‘에 의해 escaped되지 않는 후행 ‘ \ ‘가 여러 줄에 걸쳐 주석을 계속한다는 점을 제외하고 이 값과 나머지 줄은 무시된다.
앞에 공백이 있을 수 잇는 주석만 포함하는 행은 효과적으로 blank하며 무시된다.
문자 그대로 ‘#’을 원한다면 ‘\#’으로 한다.
주석은 특정 상황에서 특별하게 취급되어 작성 파일의 임의 행에 나타날 수 있다.
변수 참조 또는 함수 호출내에서 주석을 사용할 수 없다. 따라서 #의 모든 인스턴스는 변수 참조 또는 함수 호출 내에서 문자 그대로 처리된다.
레시피 내의 주석은 다른 레시피 텍스트와 마찬가지로 shell로 전달된다.
이것이 주석인지 아닌지는 shell이 해석하는 방법을 따른다.
정의된 지시어 내에서 주석은 변수를 정의하는 동안 무시되지 않고 변수 값에 그대로 유지된다.
변수가 확장되면 변수가 평가되는 컨텍스트에 따라 주석 작성 또는 레시피 텍스트로 처리된다.
긴 줄 나누기
makefiles은 개행을 기반으로 하여 끝을 표시하는 line 기반 문법을 사용한다.
gnu make는 컴퓨터 메모리 양까지 line의 길이를 제한하지 않지만 너무 길어서 표시할 수 없는 line은 래핑이나 스크롤 없이 읽기가 힘들다. 그래서 각 line 중간에 ‘\n’을 사용하여 새 line을 추가하여 읽기 쉽도록 makefile 형식을 지정할 수 있습니다.
SRC = src/test.c \ src/test2.c \ src/test3.c
Makefile
복사
레시피 라인에서 ‘\’ 처리는 달라진다. (splitting Recipe Lines에 설명)
만약 .POSIX special target이 정의된 경우 ‘\ newline’ 처리가 POSIX.2: 에 맞게 수정되고, ‘ \ ‘ 앞의 공백이 제거되지 않으며, 연속적인 ‘ \ newline’이 축약되지 않는다. (즉, recipe와 posix special target은 ‘ \ ‘로 라인 붙이기 효과 적용이 달라진다는 뜻)
white space로 나누지 않고 추가하기
만약 당신이 white space를 사용하지 않고 라인을 나누고 싶다면 아래쪽의 약간의 트릭을 사용할 수 있다.
var = one$\ word
Makefile
복사
make가 ‘ \ line ‘ 을 제거하고 다음 줄을 하나의 공간으로 축약하면 다음과 같다.
var = one$ word
Makefile
복사
그 다음 make 가 변수 확장을 수행합니다. 변수의 reference는 ‘ ‘을 존재하지 않는 ‘$ ‘인 변수로 치환하여 다음과 같이 시행이 됩니다.
var = oneword
Makefile
복사

Makefile에 지정할 이름

기본적으로 make가 makefile을 검색할 때 GNUmakefile, makefile, Makefile순으로 실행을 한다.
보통 당신은 makefile에게 makefile 또는 Makefile이라고 call하는 것을 권합니다. (Makefile은 디렉토리 목록의 시작부분 README와 같이 다른 중요한 파일 바로 근처에 두드러지게 나타나기 때문에 권장된다.)
대부분의 makefile에서의 GNUmakefile을 사용하지 않는 것이 좋습니다.
GNUmakefile은 GNU make와 관련된 makefile이 있고 다른 버전의 make에서 이해할 수 없는 경우 이 이름을 사용해야 한다. 즉, 다른버전의 make 프로그램은 makefile과 Makefile을 찾지만 GNUmakefile은 찾지 않는다.
make가 이러한 이름을 찾지 못하면 make 파일을 사용하지 않습니다. 그때 명령 인수를 사용하여 target을 지정해야하며 make는 기본 제공되는 암시적 규칙만을 사용하여 목표를 다시 만드는 방법을 찾으려고 시도합니다.
makefile에 비표준 이름을 사용하려면 ‘ -f ‘ 또는 ‘ —file’ 옵션을 사용하여 makefile name을 지정할 수 있다. 인수 ‘ -f name ‘ 또는 ‘ —file=name’은 make에서 파일 이름을 makefile로 읽도록 합니다.
둘 이상의 ‘-f’ 또는 ‘ —file’ 옵션을 사용하는 경우 여러 makefile을 지정할 수 있습니다. 모든 makefile은 효과적으로 지정된 순서대로 연결됩니다. ‘ -f ‘ 또는 ‘ —file’을 지정하면 기본값인 makefile, Makefile, GNUmakefile이 자동으로 동작하지 않습니다.

다른 makefile 포함하기

make는 makefile에게 현재 makefile들의 읽기를 중단하고 계속하기 전에 하나 이상의 다른 include를 읽도록 지시합니다.
include filenames…
Makefile
복사
파일 이름엔 쉘 파일 이름 패턴이 포함될 수 있다. 만약 파일 이름이 비어있다면 아무것도 include되지 않고 오류도 출력되지 않습니다.
줄의 시작 부분엔 추가 공간이 허용되고 무시되지만, 첫 번째 문자는 탭 (또는 .RECIPEPREFIX의 값)이 아니어야 합니다. 줄의 탭으로 시작하면 recipe line으로 간주합니다.
include와 파일 이름 사이나 파일이름과 파일이름 사이에는 공백이 필요합니다. 추가 공백은 명령어의 끝과 끝에서 무시됩니다.
줄 끝에 #으로 시작하는 주석이 허용됩니다.
파일 이름에 변수 또는 함수 참조가 포함된 경우 확장이 됩니다.
예를들어 a.mk, b.mk, c.mk를 가지고 있고 bish bash 에서 $(bar)로 확장되면 아래 같이 사용할 수 있습니다.
include foo *.mk $(bar)
Makefile
복사
이것은 아래와 동등합니다.
include foo a.mk b.mk c.mk bish bash
Makefile
복사
make가 include 파일을 처리할 때 담겨있는 makefile 읽기를 잠시 중단하고 나열된 각 파일에서 차례대로 읽습니다. 이 작업이 완료되면 지시문이 나타나는 makefile을 다시 읽습니다.
makefile 지시를 사용하는 한 가지 경우는 다양한 디렉토리의 개별 include 에 의해 처리되는 여러 프로그램이 공통 변수 정의 집합 또는 패턴 규칙을 사용해야 하는 경우입니다.
소스 파일에서 필수 구성 요소를 자동으로 생성하려는 경우도 있습니다. 필수 구성 요소는 main makefile에 포함된 파일에 넣을 수 있습니다. 이 관행은 일반적으로 다른 버전의 make에서 전통적으로 수행되었던 것처럼 main makefile의 끝에 전제조건을 추가하는 것보다 더 깨끗합니다.
지정한 이름이 / 로 시작하지 않고 현재 디렉토리에서 파일을 찾을 수 없는 경우 다른 여러 디렉토리가 검색됩니다. 먼저 “-I” 또는 “-include-dir” 옵션으로 지정한 디렉토리가 검색됩니다. 그 후 존재하는 경우 “prefix/include” (보통 /usr/local/include), “/usr/gnu/include” “user/include” 순으로 디렉토리를 검색합니다.
.INCLUDE_DIRS 변수에는 make가 included files를 검색할 현재 디렉토리 목록이 포함됩니다.
명령줄에 -I 를 추가하면 이러한 기본 디렉토리 검색을 피할 수 있습니다. 이로인해 include 디렉토리는 기본 디렉토리를 포함하여 이미 설정된 make를 잊어버립니다.
디렉토리에서 include된 makefile을 찾을 수 없는 경우는 치명적인 오류가 아니기 때문에 include makefile의 처리는 계속됩니다 일단 makefile을 읽는 것을 마치면 make는 오래되었거나 존재하지 않는 것들을 remake 하려고 시도할 것입니다.
makefile을 다시 만드는 규칙을 찾지 못했거나 규칙을 찾았지만 recipe가 실패한 후에야 잃어버린 makefile을 치명적인 오류로 진단합니다.
make가 존재하지 않거나 다시 만들 수 없는 makefile을 오류 없이 무시하려면 다음과 같이 include 대신 -include 지시어를 사용하세요.
-include filenames…
Makefile
복사
파일 이름 중 하나(또는 파일 이름의 필수 구성 요소)가 없거나 다시 만들 수 없는 경우 오류가 없다는 것을 제외하고는 모든 동작에서 include와 동일합니다.
일부 다른 make와의 호환성을 위해 -include는 sinclude의 다른 이름으로 지었습니다.