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의 다른 이름으로 지었습니다.