[Embedded] 리눅스 Build System
리눅스의 C언어 빌드 시스템에 대해서 알아보자.
리눅스 C언어 빌드 과정
main.c와 그 안에서 사용되는 blue.c, pink.c 파일들을 만들었다고 해보자.
그렇다면 우리는 아래와 같은 명령어를 사용한다.
gcc -c main.c blue.c pink.c
gcc ./main.o ./blue.p ./pink.o -o ./bluepink
rm -r ./*.o
이 과정을 통해서 bluepink라는 파일이 만들어지는 것인데,
파일을 컴파일하고 실행할 때마다 사용하려면 매우 불편하다.
그렇다면 이를 어떻게 자동화해줄 수 있을까?
Build System
make 빌드 시스템을 이용해서 빌드를 진행할 것이다.
기존 빌드 시스템은 한 파일만 바뀌어도 전체 파일들 모두 다시 빌드를 해주어야했는데
make 빌드 시스템은 오직 바뀐 파일만 다시 컴파일을 해주기 때문에 더 빠르다.
리눅스 환경에서 설치는 아래와 같은 명령어로 할 수 있다.
sudo apt install make -y
그리고 파일이름은 반드시 파일 형식도 붙이지 않고 Makefile 이라고 해야한다.
대소문자도 똑같이 말이다.
위에서 bluepink를 만들 때 빌드 시스템을 make에 적용한 스크립트는 아래와 같다.
bluepink: blue.o pink.o main.o
gcc blue.o pink.o main.o -o bluepink
blue.o: blue.c
gcc -c blue.c
pink.o: pink.c
gcc -c pink.c
main.o: main.c
gcc -c main.c
매크로
gcc뿐만 아니라 다른 빌드 시스템을 사용하기도 한다.
그렇다면 빌드 시스템을 바꿔줘야하기 때문에 위의 스크립트에서 gcc를 모두 다른 단어로 바꿔야한다.
모든 단어를 바꿀 필요 없이, 매크로를 사용해서 한 부분만 바꾸면 되도록 만들어볼까?
CC = gcc
bluepink: blue.o pink.o main.o
$(CC) blue.o pink.o main.o -o bluepink
blue.o: blue.c
$(CC) -c blue.c
pink.o: pink.c
$(CC) -c pink.c
main.o: main.c
$(CC) -c main.c
위와 같이 바꿔주면 된다.
CC = gcc
해당 부분이 매크로를 적용하는 부분이며, 매크로는 글자가 모두 그대로 복사된다는 점에 주의하라.
그리고 소괄호와 달러기호를 붙임으로써 매크로를 사용할 수 있다.
좀 더 업그레이드 하면 이렇게도 사용이 된다.
CC = gcc
OBJECTS = blue.o pink.o main.o
bluepink: $(OBJECTS)
$(CC) $(OBJECTS) -o bluepink
blue.o: blue.c
$(CC) -c blue.c
pink.o: pink.c
$(CC) -c pink.c
main.o: main.c
$(CC) -c main.c
내부매크로
$@, $^와 같은 내부 매크로에 대해서 알아보자.
- $@ : Target를 나타낸다.
- $^ : 의존성 파일들을 나타낸다.
CC = gcc
OBJECTS = blue.o pink.o main.o
bluepink: $(OBJECTS)
$(CC) $(OBJECTS) -o bluepink
blue.o: blue.c
$(CC) -c blue.c
pink.o: pink.c
$(CC) -c pink.c
main.o: main.c
$(CC) -c main.c
두 기호를 사용해서 나타내면
CC = gcc
OBJECTS = blue.o pink.o main.o
bluepink: $(OBJECTS)
$(CC) $^ -o $@
blue.o: blue.c
$(CC) -c $^
pink.o: pink.c
$(CC) -c $^
main.o: main.c
$(CC) -c $^
여기서 매크로를 추가하면 타깃 파일을 지우는 것 까지 할 수 있다.
CC = gcc
OBJECTS = blue.o pink.o main.o
RESULT = bluepink
bluepink: $(OBJECTS)
$(CC) $^ -o $@
blue.o: blue.c
$(CC) -c $^
pink.o: pink.c
$(CC) -c $^
main.o: main.c
$(CC) -c $^
clean:
rm ./*.o ./$(RESULT)