사진: Unsplash의Ilya Pavlov
리눅스 환경에서 프로젝트를 진행하는 경우 makefile 을 작성하는 경험을 하게됩니다.
직접 작성하지 않더라도 한번 쯤 사용하게 되지요.
오늘은 makefile에 대한 개념을 설명하고 어떻게 활용할 수 있는지 알려드리겠습니다.
makefile
소프트웨어 프로젝트를 빌드하고 컴파일하는 데 사용되는 스크립트 파일
Makefile은 주로 C, C++, 그리고 다른 컴파일 가능한 프로그래밍 언어의 프로젝트에서 자주 사용됩니다. Makefile은 프로젝트의 의존성과 빌드 규칙을 정의하여 빌드 프로세스를 자동화합니다.
gcc 또는 g++ 을 이용한 빌드를 구성할 때 각종 옵션들을 makefile에 정의함으로써 개발자의 실수를 방지하고 기능을 자동화 가능합니다.
Makefile은 주로 `make`라는 빌드 도구와 함께 사용되며, `make`는 makefile을 읽어들여 프로젝트를 빌드하는 데 필요한 작업을 수행합니다.
구성요소
makefile의 구성요소는 다음과 같습니다.
1. 목표(Targets): Makefile은 하나 이상의 목표를 정의합니다. 목표는 주로 빌드하려는 실행 파일, 라이브러리 또는 다른 작업을 나타냅니다.
2. 의존성(Dependencies): 각 목표는 해당 목표를 만들기 위해 필요한 파일 또는 다른 목표와의 의존성을 가집니다. 의존성은 Makefile이 어떤 파일 또는 목표를 먼저 만들어야 하는지를 나타냅니다.
3. 규칙(Rules): 규칙은 목표와 의존성 간의 관계를 설명하며, 해당 목표를 만들기 위해 실행되어야 하는 명령어를 정의합니다. 규칙은 탭으로 시작하는 명령어 블록으로 구성됩니다.
format
기본적인 makefile의 구성은 아래와 같습니다.
target 에는 빌드의 결과가 되는 파일을, prerequisites 에는 의존성, recipe에는 규칙을 작성함으로써 원하는 빌드를 구성합니다.
target … : prerequisites …
recipe
…
아래는 makefile의 예시입니다.
makefile 내용은 test.cc 파일을 g++로 빌드하여 a.out 실행파일을 만들어 내는 과정을 명시하고 있습니다.
warehouse@warehouse-VirtualBox:~/Desktop$ cat makefile
test.o :test.cc
g++ test.cc
warehouse@warehouse-VirtualBox:~/Desktop$ cat test.cc
#include <iostream>
using namespace std;
int main ()
{
cout<< "Hello world!" << endl;
return 0;
}
makefile의 활용
makefile은 리눅스 명령어 make를 통해 활용 가능합니다. 앞의 makefile 예시를 통해 빌드하면 아래와 같은 결과를 확인할 수 있습니다.
warehouse@warehouse-VirtualBox:~/Desktop$ ls
makefile test.cc
warehouse@warehouse-VirtualBox:~/Desktop$ make
g++ test.cc
warehouse@warehouse-VirtualBox:~/Desktop$ ls
a.out makefile test.cc
warehouse@warehouse-VirtualBox:~/Desktop$ ./a.out
Hello world!
위 실행 예시와 같이 makefile은 코드를 빌드하는데 활용할 수 있습니다.
여기까지는 아주 기본적인 내용이었구요, 한가지 질문을 던져보겠습니다.
makefile은 코드 빌드에만 사용이 가능할까요?
보통 질문에는 의도가 있고 이유는 모르겠지만 정답이 No 인 경우가 많지요?
네 맞습니다. makefile은 빌드 외에도 다양한 활용이 가능합니다.
하나의 예시로 make시 파일의 내용을 바꾸어 복사본을 만드는 동작의 예시를 보여드리겠습니다.
warehouse@warehouse-VirtualBox:~/Desktop$ cat test.cc
#include <iostream>
using namespace std;
int main ()
{
cout<< "Hello world!" << endl;
return 0;
}
warehouse@warehouse-VirtualBox:~/Desktop$ cat makefile
copy : test.cc
cp test.cc test.copied.cc
sed -i 's/world/makefile!/g' test.copied.cc
test.o :test.cc
g++ test.cc
warehouse@warehouse-VirtualBox:~/Desktop$ make
cp test.cc test.copied.cc
sed -i 's/world/makefile!/g' test.copied.cc
warehouse@warehouse-VirtualBox:~/Desktop$ cat test.copied.cc
#include <iostream>
using namespace std;
int main ()
{
cout<< "Hello makefile!!" << endl;
return 0;
}
test.cc를 복제하여 test.copied.cc 파일을 만들고 내용을 'sed' 명령어를 통해 변경하였습니다.
위 예시처럼 리눅스 환경에서 프로젝트를 진행 시 makefile을 어떻게 구성하냐에 따라서 빌드 시 동작을 다양하게 구현 가능하며, 파일을 옮기거나 test를 수행하는 등 여러 작업의 수행이 가능합니다.
참고자료 :
https://www.gnu.org/software/make/manual/make.html#Introduction
'CS' 카테고리의 다른 글
리눅스 개발하면서 C++ 디버깅 방법 - gdb breakpoint(중단점) 활용 (0) | 2024.03.04 |
---|---|
[C++] gdb이용하여 thread 분석하기 (0) | 2024.03.02 |
비전공자를 위한 프로그래밍 개념 - 프로세스와 스레드 (0) | 2024.02.24 |
알아두면 회사에서 인정받는 리눅스 명령어, ls (0) | 2024.02.19 |
리눅스에서 C++ 프로그래밍을 위한 gcc, g++ 의 개념과 활용 (0) | 2024.02.18 |