-
[linux] Makefile기타/Linux 2022. 1. 18. 21:46반응형
회사에서 Makefile관련해서 알아볼 일이 있어서 정리한다.
아래 링크로 적은 블로그의 글을 옮겨 적으며 이해한거라 자세한 내용은 링크를 참고하면 된다.
make sudo make install
소스코드 디렉토리에 포함되어 있는 Makefile(makefile)이라는 이름의 스크립트 파일을 읽어서 지정된 순서대로 빌드를 수행한다.
요즘은 CMake와 같은 빌드 툴을 통해 Makefile을 자동으로 생성하여 사용하기도 한다.Background
빌드 예제
main.c -> main.o foo.h + foo.c -> foo.o -> app.out bar.h + bar.c -> bar.o
세개의 소스 파일을 각각 컴파일( ''->'' 에 해당하는 과정) 하여 Object파일(*.o)를 생성하고 이를 한데 묶는 링크과정을 통해 실행파일인 app.out을 생성한다.
여기서 foo와 bar에 정의된 함수를 main에서 호출하는 의존성이 존재한다.- Make를 쓰지 않았다면
(1) 다음 세 줄의 명령어를 통해 컴파일한다.
gcc -c -o main.o main.c gcc -c -o foo.o foo.c gcc -c -o bar.o bar.c
-c
: 링크를 하지 않고 컴파일만 하겠다는 의미 (이 옵션을 생략하면 main함수를 찾을 수없다는 에러 출력).(2) 다음 명령으로 object파일을 한데 묶는 링크 과정을 수행한다.
gcc내부적으로 링커(Id)를 실행해서 실행파일을 생성한다.
gcc -o app.out main.o foo.o bar.o
이때 만약에 실수로
gcc -o main.c main.c
이렇게 해버리면 소스파일은 사라지고 빌드된 바이너리만 남게된다. 오타 하나로 열심히 작업한 소스파일을 잃을수도 있다.
쉘 스크립트 ?
쉘 스크립트에 모든 명령을 다 넣어 사용하는 방법도 있지만, 그런 경우 Makefile이 제공하는 Incremental build를 사용할 수 없게된다.
Incremental build
반복적인 빌드 과정에서 변경된 소스코드에 의존성이 있는 대상들만 추려서 다시 빌드하는 기능
main.c 한줄만 바꾸고 다시 빌드할때
gcc -c -o main.o main.c
와gcc -o app.out main.o foo.o bar.o
만 수행할 수 있다. (2줄이 줄어드는셈).Makefile에서는 빌드 대상 별로 의존성을 명시해주면 이에 따라 자동으로 Incremental build를 수행해주므로 매우 편리해진다.
Makefile 작성법
Bash 쉘 스크립트와 비슷하다. 빌드 대상(Target) 이름으로 된 Label 별로 구분된 쉘 스크립트라고 볼 수 있다.
# Makefile app.out: main.o foo.o bar.o gcc -o app.out main.o foo.o bar.o main.o: foo.h bar.h main.c gcc -c -o main.o main.c foo.o: foo.h foo.c gcc -c -o foo.o foo.c bar.o: bar.h bar.c gcc -c -o bar.o bar.c <Target>: <Dependencies> <Recipe> # 반드시 Tab문자로 된 Indent가 있어야한다.
이렇게 Makefile을 작성하고
make
명령을 치면 한번에 app.out이 만들어진다. make 뒤에 target 을 명시하면 해당 target만 만들어진다.
기타
내장규칙
소스파일을 컴파일해서 오브젝트파일로 만들어주는 규칙은 굳이 기술하지 않아도 만들어준다.
대신 target에 대한 dependency는 명시해주어야한다.app.out: main.o foo.o bar.o gcc -o app.out main.o foo.o bar.o main.o: foo.h bar.h main.c foo.o: foo.h foo.c bar.o: bar.h bar.c
recipe가 생략되어도 컴파일이 수행된다.
변수 사용하기
Make 내장 변수
- CC: 컴파일러
- CFLAGS: 컴파일 옵션
- OBJS: 중간 산물 Object 파일 목록
- TARGET: 빌드 대상 (실행파일) 이름
그외 내장 변수
- LDFLAGS : 링커 옵션
- LDLIBS: 링크 라이브러리
자동 변수
- $@: 현재 Target 이름
- $^: 현재 Target이 의존하는 대상들의 전체 목록
- $?: 현재 Target이 의존하는 대상들 중 변경된 것들의 목록
Clean Rule
Clean 매크로는 빌드 결과물과 중간 부산물을 모두 삭제하여 깨끗한 상태에서 다시 빌드할 수 있는 환경을 만들어준다.
clean: rm -f *.o rm -f $(TARGET) --- make clean
출처
make -p : 사용된 변수 출력
make -d : 디버깅
makefile안에서 include를 하면 현재 파일에서 하던 일을 잠시 멈추고 해당 makefile을 찾아 그에 해당하는 일을 모두 수행한 뒤 다시 돌아온다.
'기타 > Linux' 카테고리의 다른 글
[Linux] ec2 용량 늘리기 swapfile (0) 2020.06.15 [Linux] 터미널 큰 파일 링크로 다운로드 (0) 2020.06.15