웹사이트 검색

GNU Make를 사용한 오픈 소스 소프트웨어 개발의 'Makefile'에 대한 간략한 소개


GNU Make는 재컴파일할 특정 코드 베이스 부분을 결정하고 코드 베이스에서 해당 작업을 수행하는 명령을 실행할 수 있는 개발 유틸리티입니다. 이 특정 make 유틸리티는 명령을 실행하여 셸에서 컴파일을 수행할 수 있는 경우 모든 프로그래밍 언어와 함께 사용할 수 있습니다.

GNU Make를 사용하려면 프로그램의 여러 파일 간의 관계를 정의하는 몇 가지 규칙 세트와 각 파일을 업데이트하는 명령이 필요합니다. 이는 'makefile'이라는 특수 파일에 기록됩니다. 'make' 명령은 'makefile' 데이터베이스와 파일의 마지막 수정 시간을 사용하여 결정합니다. 모든 파일을 다시 컴파일해야 합니다.

Makefile의 내용

일반적으로 'makefiles'에는 암시적 규칙, 명시적 규칙, 변수 정의 등 5가지 종류가 포함됩니다. , 지시어설명.

  1. 명시적 규칙은 하나 이상의 파일(타겟이라고 함, 나중에 설명함)을 만들거나 다시 만드는 방법과 동일한 작업을 수행할 시기를 지정합니다.
  2. 암시적 규칙은 이름을 기반으로 하나 이상의 파일을 만들거나 다시 만드는 방법을 지정합니다. 대상 파일 이름이 대상과 유사한 이름을 가진 하나의 파일과 어떻게 관련되어 있는지 설명합니다.
  3. 변수 정의는 나중에 대체할 변수의 문자열 값을 지정하는 줄입니다.
  4. 지시문은 Make파일을 읽는 동안 특별한 작업을 수행하도록 하는 명령입니다.
  5. '#' 기호는 makefiles 내부의 주석의 시작을 나타내는 데 사용됩니다. . '#'으로 시작하는 줄은 무시됩니다.

Makefile의 구조

make에 시스템을 다시 컴파일하는 방법을 알려주는 정보는 makefile이라는 데이터베이스를 읽어서 나옵니다. 간단한 makefile은 다음 구문 규칙으로 구성됩니다.

target ... : prerequisites ... 
	recipe 
... 
...

대상은 프로그램에서 생성된 출력 파일로 정의됩니다. 가짜 표적일 수도 있으며 이에 대해서는 아래에서 설명합니다. 대상 파일의 예로는 실행 파일, 객체 파일 또는 clean과 같은 위조 대상이 있습니다. 설치, 제거

전제 조건은 대상 파일을 생성하기 위한 입력으로 사용되는 파일입니다.

레시피는 전제조건에 따라 대상 파일을 생성하기 위해 make가 수행하는 작업입니다. 다른 문자를 접두사로 정의하기 위해 '.RECIPEPREFIX' 변수를 지정하지 않는 한 makefiles 내부의 각 레시피 앞에 탭 문자를 넣어야 합니다. 레시피에.

샘플 메이크파일

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f main.o end.o inter.o start.o

위의 예에서는 최종 실행 파일을 생성하기 위해 4개의 C 소스 파일과 두 개의 헤더 파일을 사용했습니다. 여기서 각 '.o' 파일은 makefile 내부의 대상이자 전제 조건입니다. 이제 마지막 대상 이름 clean을 살펴보세요. 이는 대상 파일이 아닌 단순한 작업일 뿐입니다.

일반적으로 컴파일 중에는 이것이 필요하지 않으므로 다른 규칙에서는 전제 조건으로 작성되지 않습니다. 파일을 참조하지 않고 단지 작업만 수행하는 대상을 포니 대상이라고 합니다. 다른 대상 파일과 마찬가지로 전제 조건이 없습니다.

GNU Make가 Makefile을 처리하는 방법

기본적으로 make는 'makefile'의 첫 번째 대상으로 시작하고 '으로 호출됩니다. 기본 목표'. 우리의 예를 고려해 보면 첫 번째 목표로 최종이 있습니다. 전제조건에는 최종을 생성하기 전에 업데이트해야 하는 다른 개체 파일이 포함되어 있기 때문입니다. 이러한 각 전제조건은 자체 규칙에 따라 처리됩니다.

소스 파일이나 헤더 파일이 수정되었거나 객체 파일이 전혀 존재하지 않는 경우 재컴파일이 발생합니다. 필요한 개체 파일을 다시 컴파일한 후 makefinal 을 다시 연결할지 여부를 결정합니다. 최종 파일이 존재하지 않거나 개체 파일이 이 파일보다 최신인 경우 이 작업을 수행해야 합니다.

따라서 inter.c 파일을 변경하면 make를 실행할 때 소스 파일을 다시 컴파일하여 업데이트합니다. 개체 파일 inter.o을 만들고 final을 연결하세요.

Makefile 내에서 변수 사용

이 예에서는 아래와 같이 최종에 대한 규칙에서 모든 객체 파일을 두 번 나열해야 했습니다.

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o

이러한 중복을 피하기 위해 makefile 내부에서 사용되는 개체 파일 목록을 저장하는 변수를 도입할 수 있습니다. OBJ 변수를 사용하여 샘플 makefile을 아래와 유사한 것과 유사하게 다시 작성할 수 있습니다.

OBJ = main.o end.o inter.o start.o
final: $(OBJ)
	gcc -o final $(OBJ)
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f $(OBJ)

소스 디렉터리 정리 규칙

makefile 예시에서 본 것처럼 컴파일 후 원치 않는 개체 파일을 제거하여 소스 디렉터리를 정리하는 규칙을 정의할 수 있습니다. clean이라는 대상 파일이 있다고 가정해 보겠습니다. make는 위의 두 가지 상황을 어떻게 구별할 수 있나요? 여기에 가짜 표적이라는 개념이 있습니다.

가짜 대상은 실제로 파일 이름이 아니라 makefile<에서 명시적인 요청이 있을 때마다 실행되는 레시피의 이름일 뿐입니다.. 가짜 대상을 사용하는 주된 이유 중 하나는 동일한 이름의 파일과의 충돌을 피하기 위해서입니다. 또 다른 이유는 성능을 향상시키기 위해서입니다.

이를 설명하기 위해 예상치 못한 반전 하나를 공개하겠습니다. clean 레시피는 make 실행 시 기본적으로 실행되지 않습니다. 대신 make clean 명령을 실행하여 동일한 기능을 호출해야 합니다.

.PHONY: clean
clean:
	rm -f $(OBJ)

이제 자신만의 코드 베이스를 위한 makefile을 만들어 보세요. 여기에 궁금한 점이 있으면 언제든지 의견을 남겨주세요.