make - 2
make
- 컴파일 도구, 컴파일을 위해 주어진 쉘명령어들을 조건에 맞게 실행하는 프로그램
- 컴파일 작업 단순화를 위해 사용하며, 대규모/공동 프로젝트에서 많이 사용한다(기에는 개인들도 많이 사용한다)
- 이전 컴파일한 내용이 있을 경우 수정된 파일들을 파알하여 수정된 내용들에 대해서만 컴파일 수행
** make 명령어 실행시 파일의 수정유무는 타임스탬프를 기반으로 판단한다
(타임 스탬프의 변경유무를 통해 파일의 변경점을 판단)
make file
- 컴파일 빌드 규칙을 기술한 파일
- 컴파일 명령 및 쉘 명령어들로 구성되어 있으며, 소스파일 간의 의존성(dependency)을 명시한다
: make가 makefile의 내용을 통해 파일 간의 종속성을 자동으로 파악하여 효율적 컴파일을 수행한다(쉘 스크립트와의 차이)
make 명령어 실행법
- make [-f 파일명] [options] [targets]
: makefile 미지정시, 현재경로의 makefile 혹은 Makefile을 사용하여 빌드한다
: target 미지정시 all을 타겟으로 빌드한다
makefile 작성법
- 구성
타겟 : 의존성 목록
(탭)쉘명령어
-> 의존성 목록이 있어야 타겟을 컴파일 한다. 즉, 타겟을 위해 선행적으로 의존성 목록을 컴파일한다
-> makefile는 탭문자 다음에 적힌 문자열을 명령문으로 판단한다
- 묵시적으로 사용하는 타겟들
all
: 최종 타겟, 일반적으로 의존성 목록에 모든 빌드 타겟이 명시되어 있다
clean
: make 명령에 의해 생성된 파일들을 삭제하는 타겟
- 주석
#
- 메크로
변수 정의: 변수=값
변수 사용: $(변수), ${변수}
CC : 컴파일러 프로그램 명시
CFLAGS : 컴파일 옵션 명시
LDFLAGS : 링크를 위한 라이브러리 명시
** 컴파일은 소스파일로 목적파일 생성을 수행, 링크는 목적파일로 바이너리 파일 생성을 수행
- 와일드 카드, 패턴
% : *와 같음
** 아래의 패턴은 명령어 작성시 타겟과 의존성 목록을 가리킬 때 사용이 가능하다
$@ : 타겟이름
$< : 의존성 목록 중 첫번째 파일을 의미
$^ : 의존성 목록 전체를 의미
$? : 타겟보타 최신의 상태를 가지는 의존성 목록을 의미
$+ : $^와 유사하나, 중복된 파일 이름들 까지 모두 포함
- gcc 옵션
** gcc 옵션 참조
- https://jayy-h.tistory.com/9
-I : (대문자 i), 헤더파일 경로 지정
-L : 라이브러리 경로 지정
-l :(소문자 L), 참조할 라이브러리 이름을 명시
ex) 라이브러리 이름이 libtest.a일 경우, gcc옵션 작성시에는 -ltest.a가 된다
(라이브러리 이름작성시에는 lib로 시작해야하며, .a는 적적, .so는 동적라이브러리이다)
-D : 매크로선언
-g : 디버깅 정보 포함(디버깅 툴에서 디버깅 가능)
-W : 컴파일이 가능하지만 존재하는 경고 출력
-Wall : 컴파일시 발생하는 모든 경고 출력
-c : 목적파일 생성
-O : 최적화 레벨 지정
-MD : 컴파일시 생성한 목적파일(메이크파일로 치면 타겟)을 만들기 위해 참조하는 소스파일(메이크파일로 치면 의존파일)과 헤더파일 목록의 정보를 "목적파일명.d"파는 이름으로 파일 생성
(= 목적파일의 종속정을 검사하고 해당 내용을 "목적파일명.d" 파일에 생성 및 저장한다)
* /usr/include/stdc-predef.h : gcc 컴파일러가 컴파일시 묵시적으로 참조하는 헤더파일
** 위의 .d파일을 사용하여 makefile작성시 종속목록 작성을 생략할 수 있다
단, 처음 make 수행시에는 기존에 존재하는 .d파일이 없기 때문에 빌드시 어떠한 .d파일을 포함하지 않는다.
즉, 그 다음 make수행시 .d가 포함된다
ex) makefile에서 아래와 같이 정의
include 목적파일명.d -> 특정 .d파일을 makefile에서 참조
include $(OBJS:.o=.d) -> OBJS에 등록된 변수 값에서, .o를 .d로 치환. 이후 makefile이 목적파일에 대응하는 .d파일을 참조한다
-include 목적파일명.d -> 특정 .d파일을 makefile에서 참조해되, 해당파일이 존재하지 않아도 관련오류 메세지를 출력하지 않는다
- 함수사용
$(wildcard 조건) : 조건에 맞는 파일목록을 추출
$(notdir 파일목록) : 파일목록에서 경로를 제외한 파일이름만을 추출
$(patsubst 현재패턴, 치환패턴, 대상) : '대상'에 정의된 파일목록 중 '현재 패턴'에 해당하는 파일들을 '치환패턴'으로 치환하여 결과 값 반환
- 기타
A = x
: x가 정의될 때까지 대기한 후 x값을 A에 저장
A := x
: 해당 시점의 x변수의 값을 확인하여 A를 선언. 즉, x가 정의되지 않더라도 A를 선언(이 경우 A는 빈값을 가진다)
.PHONY
: 'make 타겟' 명령어 실행 시, 조건에 관계없이 같이 정의된 타겟에 대한 명령어를 무조건 실행
ex) makefile에서
.PHONY : clean
clean :
rm -f $(OBJS) $(TARGETS)
-> 타겟이나 목적파일이 없더라도 일단 해당 rm명령어 수행
** 멀티코어를 사용하여 make하기
make -j 쓰레드개수
- 컴파일 병렬수행 명령, 커널 컴파일과 같이 대용량 컴파일시 활용하면 시간이 절약된다
- 쓰레드개수는 통상적으로 코어개수+1(혹은 코어개수의 120%수준으로)로 지정하여 수행하는 것이 가징 속도가 빠르다
- 만약 리눅스 환경에서 코어개수를 모를 경우
make -j $(nproc)
- $(nproc)는 현재 시스템환경에서 사용가능한 코어개수를 의미
** 응용
makefile에서
.c.o:
$(CC) -c -o $@ $<
의미: makefile에 존재하는 c파일($<)을 o파일로 컴파일
-> 인터넷을 찾아보니 .c.o는 구식 접미사 규칙(오래된 문법)으로서 같은 의미로는 %.o: %.c 이다
$<를 $^로 변경해도 문제가 없을 것으로 판단된다
'Study > utilities' 카테고리의 다른 글
vscode 배우기 (0) | 2023.03.24 |
---|---|
cmake - 3(강의정리) (0) | 2023.02.21 |
cmake - 2 (0) | 2021.09.08 |
cmake - 1 (0) | 2021.09.01 |
make - 1 (0) | 2021.08.22 |