본문 바로가기

프로그램 언어

[ C / C++ ] make , Makefile

make

기존 gcc / g++를 이용해서 프로그램을 빌드할 때, 빌드를 할 때마다 SHELL(터미널 창)에 명령어를 입력하기 힘들어서 Makefile에 이렇게 빌드를 하면 된다.라고 명시해 놓음으로써 빌드하기 간편하게 만들어 준다.

Makefile

Makefile이란 make가 현재 경로에서 참고하여 실행하는 파일으로, 어떻게 빌드할지 적혀있는 파일이다. 파일 이름은 무조건 Makefile로 통일되어야 한다.

make와 Makefile을 사용하기 전 기존 gcc / g++로 했던 방식을 간단하게 살펴보자

일단 파일 구조가 다음과 같고 , 각각의 코드가 다음과 같을 때,

파일 구조
src  |- main.cpp
     |- function1.cpp
     |- function2.cpp
     |- my_header.h

 

my_header.h
#include <iostream>
void function1();		//함수 원형 선언
void function2();
function1.cpp
#include "my_header.h"
#include <iostream>

void function1(){
    using namespace std;
    cout<<"HELLO I'M FUN1"<<endl;
}
function2.cpp
#include "my_header.h"
#include <iostream>

void function2(){
    using namespace std;
    cout<<"HELLO I'M FUN2"<<endl;
}
main.cpp
#include "my_header.h"
int main(int argc,char** argv){
    function1();
    function2();
    return 0;
}

 

여기서 기존 g++로 빌드 하는 방법은 다음과 같다.

g++ -c -o function1.o function1.cpp
g++ -c -o function2.o function2.cpp
g++ -c -o main.o main.cpp
g++ -o run main.o function1.o function2.o

이렇게 빌드 하면 파일 구조가 다음과 같이 된다.

src  |- main.cpp
     |- function1.cpp
     |- function2.cpp
     |- my_header.h
     |- function1.o
     |- function2.o
     |- my_header.h
     |- main.o
     |- run

위와 같이 빌드하게 되면 여러 object file을 생성해야 하는뿐더러 파일이 많아지면 많아질수록 과정이 복잡해 진다.

이러한 절차를 간단하게 하기 위해 Makefile을 작성하고 make를 사용해보자.

Makefile 문법

Makefile에는 매크로 정의 , 타겟절 , 의존성 , 명령어가 있다.

먼저, 위의 빌드 과정을 Make file로 바꾼 예시로 다음을 보자.

CC = g++
CFLAGS = -W -Wall
SRC = function1.cpp function2.cpp main.cpp
OBJ = main.o function1.o function2.o 
PROG = run

all : ${PROG}
${PROG} : ${OBJ}
	${CC} -o ${PROG} ${OBJ}
	rm *.o
${Obj} : ${SRC}
	${CC} ${CFLAGS} -c -o function1.o function1.cpp
	${CC} ${CFLAGS} -c -o function2.o function2cpp
	${CC} ${CFLAGS} -c -o main.o main.cpp
clean :
	rm *.o run

여기서 처음 4줄은 매크로 정의이다. C / C++ 에서 #define과 같이 = 오른쪽에 있는 걸 대신해서 왼쪽을 사용한다는 걸 의미한다. 매크로의 사용법은 아래와 같이 ${매트로} 또는 $(매크로)로 사용한다.

* 매크로 선언시 앞에 공백이나 tab이 존재하면 안된다.

* 매크로에는 특수기호 ,""#$등이 들어갈수 없다.

아래 ${Obj} : ${SRC} 와 같은 문법은 : 왼쪽에 있는 걸 만드려면 오른쪽에 있는 것들이 필요하다 라고 알려주는 의존성 항목이다. 의존성이 갖춰지면 그 아래 tab (space x)으로 구분된 명령어들을 실행한다.

all 과 clean 은 SHELL에서 make를 할때 추가 적인 옵션으로 make all 과 make clean을 할 때 시행하는 명령어가 적혀있으며, all은 빌드에 필요한걸 모두 실행 , clean은 실행파일과 빌드 과정중 발생한 object file 제거 같은 역할을 적어 넣는다.

이렇게 Makefile을 작성한 후 make를 하게 되면 다음과 같이 작동하는 것을 확인할 수 있다.

make를 했을 때 터미널 창

또한 만들어진 실행파일이 정상적으로 작동하는 걸 확인할 수 있다.

정상 실행된 실행 파일

내부 매크로

Make file에는 내부 매크로가 존재하며 다음과 같다.

$@        //현재 타겟 파일 이름
$*        //확장자를 제외한 목표파일의 이름
$<        //현재 필수 조건 파일 중 첫 번째 파일 이름
$?        //최근 변경된 필수 조건 파일 이름
$^        //현재 모든 필수 조건 파일들

 

 

 

포스팅 끝

틀린거나 궁금한거 댓으로 알려줘요

'프로그램 언어' 카테고리의 다른 글

[CMake] CMake 간단한 설명 + 예제  (2) 2021.02.18
[ C / C ++ ] 프로그램하기전 지식  (1) 2021.01.30