- 연혁

C 프로그래밍에서, 프로그램은 종종 여러 소스 파일과 헤더 파일에 걸쳐 분할하여 조직, 재사용성 및 컴파일 속도를 향상시킵니다. 그러나, 이 모듈성은 도전을 소개합니다: 헤더 파일 변경이 있을 때, 모든 소스 파일이 다시 컴파일되어야 합니다. 이 수동으로 오류 ‐ 프로네 및 시간 조정이 됩니다. Makefiles, make] 빌드 인코딩 자동화 도구, 이 문제를 해결하는 것은 자동의 변화에 대한 새로운 프로세스를 생성하는 방법을 설명합니다. 이 문서는 C 프로그래밍에 대한 새로운 프로세스를 생성하는 방법을 설명합니다.

Makefiles는 무엇입니까?

Makefile은 프로젝트 구축을위한 규칙의 집합을 정의하는 일반 텍스트 파일입니다. make 유틸리티는 이러한 규칙을 읽고, 파일 타임스탬프를 확인하고, 날짜까지 프로젝트를 가져야 할 명령 만 실행합니다. 핵심 아이디어는 간단합니다: 각 규칙에는 target (생산하는 파일), [[LTLT:3]][LT:[LT:7]]]]]]]]]]]]]]][LT:7]][LT:[LT:7]]]]]]]]][[]]]]]]]]]]]]]]][[[[]]]]]]]]]]]]]]]]]]][[[[[[[[[[[[[FLT:[[[]]]]]]]]

Makefiles는 1970 년대 이후 유닉스의 일부였으며 GNU는 Linux 및 macOS의 de facto 표준입니다. 구문은 대결되지만 대결이 될 수 있습니다. 정점이 오른쪽으로 들어가는 것은 C 개발자가 필요합니다.

관련기관

C 프로젝트에서, 의존성은 ] 파일에 제한되지 않습니다. 각 소스 파일은 하나 이상의 헤더 파일 (예를들면 )을 포함합니다. 헤더가 수정되면, 모든 파일을 다시 컴파일해야 합니다. 마찬가지로, 객체 파일은 해당 ] 파일에 따라 달라집니다. 그리고 최종 실행 가능한 모든 객체 파일에 따라 다릅니다.

익스피리언트 대 임플란트 종점

초기의 Makefiles에서 프로그래머는 모든 우선 순위를 수동으로 나열했습니다. 즉, 헤더를 잊어 버리고 stale 빌드를 잊어 버리고, 너무 많은 트리거 불필요한 재컴파일을 나열하면서. Worse는 프로젝트가 성장함에 따라 수동 목록은 불확실하게됩니다. 현대 솔루션은 컴파일러가 의존성을 자동적으로 생성하고, 임의로 돌리기, 기계 검사된 예비 부품으로 전환합니다.

잘 만들어진 Makefile은 첫 번째 클래스 관심사로 의존성을 다룹니다. 목표는 재건이 필요없는 것을 다시 구축하지 않고 항상 모든 것을 재구성하는 것은 결코 없습니다. 이것은 ]correctness]]효율]]의 본질입니다.

Makefile의 기본 구조

일반적인 Makefile은 변수 정의, 규칙 및 phony 대상을 포함합니다. 여기에는 과 ]과 프로젝트의 최소하지만 기능 예입니다.

CC = gcc
CFLAGS = -Wall -Wextra -O2

main: main.o utils.o
 $(CC) $(CFLAGS) -o main main.o utils.o

main.o: main.c
 $(CC) $(CFLAGS) -c main.c

utils.o: utils.c
 $(CC) $(CFLAGS) -c utils.c

clean:
 rm -f main main.o utils.o

이 Makefile에는 4개의 대상이 있습니다: ] (실행), 2개의 객체 파일 및 phony 대상 ]. 대장 후의 의존성 선은 make 대상을 재구성하기 전에 검사하기 전에 검사하는 파일입니다.

Phony 대상

또는 ]은 파일을 나타내는 것은 아닙니다. make]를 filename과 혼란으로부터 방지하기 위해 phony로 선언해야 합니다.

.PHONY: clean all

이없이 가 존재하면 ]make가 업데이트되고 레시피를 건너려고 생각할 것입니다.

관련 기관

위의 수동 Makefile은 심각한 결함이 있습니다. ]의 의존도가 정확하지만 헤더에 대해 무엇을? 변경 사항, ] (포함) 다시 구축되어야하지만 규칙은 ]에 달려 있다고합니다. 수정은 컴파일러가 실제 의존성 목록을 생성 할 수 있도록합니다.

GCC의 자동적 의존성 발생

GCC(Clang)은 ]] 플래그의 가족을 사용하여 종속 정보를 생성할 수 있습니다. 대부분의 프로젝트의 가장 실용적인 조합은 ]:

  • ] - 컴파일 중에 의존성 파일 (])를 작성하고, 사용자 정의 헤더를 나열합니다 (시스템 헤더).
  • – 종속성 파일의 이름을 지정합니다.
  • - 각 헤더에 대한 phony 대상을 추가하고, 헤더가 제거될 때 오류를 방지합니다.

다음은 Makefile에 자동 의존성 추적을 통합하는 방법 :

CC = gcc
CFLAGS = -Wall -Wextra -O2 -MMD -MP
SRCDIR = src
OBJDIR = obj
SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(OBJS:.o=.d)

all: myprogram

myprogram: $(OBJS)
 $(CC) $(CFLAGS) -o $@ $^

$(OBJDIR)/%.o: $(SRCDIR)/%.c
 @mkdir -p $(OBJDIR)
 $(CC) $(CFLAGS) -c $< -o $@

-include $(DEPS)

.PHONY: all clean
clean:
 rm -rf $(OBJDIR) myprogram

설명:

  • 는 소스 디렉토리의 모든 파일을 수집합니다.
  • 객체 파일 경로로 변환합니다.
  • ]는 종속 파일 목록(예: ).
  • 패턴 규칙 각 ] 파일을 컴파일하고 ]] 때문에, ] 파일을 부작용으로 생성합니다.
  • 라인 생성 된 파일을 읽고 실제 Makefile prerequisites로 전환합니다. dash (])는 [[FLT가 존재하지 않는 오류를 억제합니다.(예: 1)) 파일이 아직 (예: 첫 번째 빌드).

이제 이 수정되면 ]의 다음 invocations ]가 ]]] 파일이 ]]가 ]가 우선적으로 처리되기 때문에 다시 컴파일됩니다.

고급 기술

처리 규정된 종점 안전

헤더가 삭제되면 ] 파일은 여전히 참조 할 수 있습니다, make] 을 실패한 대상 오류. 플래그는 각 종속 헤더에 대한 빈 phony 규칙을 추가하여이 주소. 헤더가 사라지면 make 단순히 가짜 규칙을 실행 (무엇이 아무것도) 그리고 계속.

Source Change 후의 Dependency Files를 포함

한 번의 미묘한: 소스 파일이 추가되거나 ]를 제거하면 해당 파일이 재생되어야 합니다. 파일이 객체 파일의 사전 예약이므로 make는 변경된 타임스탬프와 재 컴파일을 공지합니다. 파일을 재생합니다. 이 재발은 자동으로 빌드됩니다.

주문만 사용

때로는 건물 전에 존재하는 디렉토리가 필요하지만, 재건을 트리거하기 위해 타임스탬프를 원하지 않습니다. ]order‐only prerequisites] (])의 역할입니다. 위의 패턴 규칙에서 우리는 조리법 내부에 사용; 대안은:

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
 $(CC) $(CFLAGS) -c $< -o $@

$(OBJDIR):
 mkdir -p $@

이 디렉토리는 컴파일 전에 생성되지만 디렉토리 자체로 변경됩니다 (예 : 내부의 새로운 파일) recompilation을 트리거하지 않습니다.

종업원 수급

  1. 1일 자동 종속성 발생을 사용합니다.] 단 하나 파일 프로젝트에도 좋은 습관입니다. 그것은 아무것도 비용이 든다 미래 실수를 방지합니다.
  2. 소스 파일에서 분리되는 의존성 파일들을 수정합니다.] ] 또는 ] 디렉토리에 넣어 주세요. 이 청소를 쉽고 소스 트리를 깎아줍니다.
  3. ] 생성 된 ] 파일을 포함 해서 생성된 규칙을 작성한다.] 지시어는 괜찮지만 패턴 규칙이 make] 파일을 읽기 전에 객체 파일을 빌드하는 방법을 먼저 알고 있다.
  4. 설정을 위한 폰키 대상을 사용합니다. ], ], , ]]는 일반적입니다. 로 항상 선언합니다.
  5. 컴파일러 플래그, 소스 디렉토리 및 파일의 목록에 대한 파일 형식의 변수를 실행합니다.] 이것은 프로젝트 전반에서 makefile 재사용할 수 있으며, 사용자 정의하기 쉬운 만듭니다.
  6. ]디바이저 헤드러 변경으로 Makefile을 테스트합니다.] 헤더를 수정하고 을 실행하고 영향을받는 객체 파일만 다시 컴파일합니다. 전체 재건축이 발생하면, 뭔가가 의존성 추적으로 잘못됩니다.
  7. Makefile을 간단히 정리하지만 필요한 것보다 더 간단하지 않습니다.] ]과 같은 고급 기능을 가진 ‐engineering은 고통스러운 벌레잡기를 만들 수 있습니다. 이 문서에서 보이는 패턴으로 시작; 그것은 수십 개의 파일로 잘 스케일합니다.

외부 자료

이해를 깊게하려면이 권한 참조를 참조하십시오.

관련 기사

Makefiles와 C 프로그램 의존성을 관리하는 것은 고급이 아니지만 단일 파일을 파기하는 프로젝트의 필요성입니다. 패턴 규칙을 결합함으로써, ]로 자동 의존성 발생, 생성 된 파일의 주의적인 포함, 당신은 빠른 및 정확하고 정확한 빌드 시스템을 만들 수 있습니다. 이 기법은 수동 추적을 제거하고 빌드 시간을 줄이고, stale 객체 파일에 의해 발생되는 하위 버그를 방지합니다. 내부 파일에서 적절한 결과를 다시 작성하면됩니다. ]]는 이러한 설명서를 다시 작성하고 적절한 결과를 다시 작성할 수 있습니다.