티스토리 뷰

개발자 배배/Linux

[Linux] Makefile 활용하기

사연있는 배배 2018. 4. 10. 14:34

일반적으로 리눅스 상에서 두가지 방법의 컴파일 방법을 사용합니다. 

 1. gcc     : gcc 등의 직접 command를 사용해 컴파일 하거나, 

 2. make : make를 이용한 Makefile 컴파일


1번은 간단하게 한 두개 컴파일 할 때 사용하면 좋고, 

2번은 컴파일할 규칙을 미리 정해놓는 방식을 사용하므로, 많은 수의 file을 컴파일 할 때 유용합니다. (SHELL 명령어 집합이라고 보면 좋습니다)


그리고 일반적으로 Open source library를 내려 받으면, 직접 컴파일해서 사용하기 보다 제공되는 Makefile을 이용합니다.

그래서 Makefile을 사용하는 방법, 간단한 변경을 위해 포스팅 해보려 합니다.




1. Makefile의 구조 분석하기 


Makefile == (make를 이용한) compile 규칙명세서


: 위에서 언급 했듯, Makefile은 다중 file의 compile을 가능하게 하는 규칙을 명세해놓은 파일입니다.

그리고 그 과정의 편의를 위해 Macro를 제공합니다.


아래는 vim에디터로 Makefile을 열어서 본 것. (소스 출처는 아래)


        CC = gcc

CXX = g++

CFLAGS = -pipe -Wall -W -O2 -DNO_DEBUG

CXXFLAGS = -pipe -Wall -W -O2 -DNO_DEBUG

INCPATH = -I/usr/local/include/mysql

LINK = g++

LIBS = -L/usr/local/lib/mysql -lmysqlclient -lcrypt


# FILE

SOURCES = main.cc \

sql.cc


OBJECTS = main.o \

sql.o


TARGET = myprg


# Implict rules

.SUFFIXES:.cc .c


.cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<

.c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<


# build rule


all: $(TARGET)

$(TARGET): $(OBJECTS) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)


clean: -rm -f $(OBJECTS) $(TARGET) \

-rm -f core


# complie

main.o: main.cc

sql.o : sql.cc


< 명령어 들의 3가지 형태 >

1) [ Macro명 = Macro값 ]

: '='는 macro를 설정할 때 사용하며, 매크로의 사용은 shell과 비슷하게, $(Macro명) 으로 사용합니다

여러 줄에 걸쳐서 써야할 경우 \(backslash)로 이어짐을 표시합니다

(예를 들어, 'CC = gcc'를 정의 했다면, 이후 CC라는 매크로 명은 실행 될 때 gcc로 대체되어 실행될 것.)



2) [ target file : dependencies 

recipe


1. target file : 실제 만들고자 하는 file입니다. 

2. dependencies : tartget file을 만들고자 할 때 필요한 재료들이라고 보시면 편합니다. 

필요한 재료들이 없다면, target file을 만들어 낼 수 없습니다. 


3. recipe : 위에서 make all 명령어를 실행하면, 위에서 all: ~~ 이라고 명시된 부분에 의해 컴파일이 수행되는데, 

이때, ~~에 해당하는 실제 수행내용을 recipe라고 합니다. 

(recipe는 시작할때 무조건 tab으로 띄워줘야 하는 것이 원칙입니다.)


3) [ make시  build 명령어 : tartget file ]

: target file에 대한 명령이 아닌 build 명령어를 나타내는 명세도 있습니다. 

(실행은 'make all' 등과 같이 make (build 명령어) 으로 하게 됩니다.)




2. Makefile 사용하기 

: 그렇다면 현재 분석 중인 jsmn의 Makefile을 참고해, make로 컴파일을 진행해 보도록 하겠습니다. 


1) Makefile 확인


(-> jsmn 프로젝트도 clone 해보면, Makefile을 제공하는 것을 볼 수 있다.)



2) Makefile 들여다보기


(-> 위는 vim Makefile로 내용을 직접 들여다본 모습. )


: 여기서는 Macro 설정은 따로 보이지 않네요. (아마 config.mk 파일에 명시되어 있을 것으로 보입니다.)

그리고 한가지 더 눈여겨 봐야 할 점은, test의 모드가 여러가지 라는 점입니다. 


make하거나 make all하면 모든 명령이 실행되기 때문에, 모든 test문들이 다 생성될텐데요, 

특정 test문만 만들고 싶다면, 해당 target file이 있는 것만 option을 주면 됩니다. 

(소스 내에 #ifdef JSMN_STRICT 등과 같은 구문을 선별적으로 실행하는 거죠.)


역시 일반적으로 make all, make clean은 제공하네요. 



3) 실제 사용 - sample코드 실행해보기 

: 위의 Makefile 명세에서 실제 돌려볼 수 있는 건, simple_example과 jsondump입니다. 

그래서, 


1.  make all을 해서 target file인 libjson.a를 먼저 생성한 후,  

(참고로 .a 확장자는 library를 의미하며, 사실 make libjsmn.a 처럼 명시해줘도 상관 없다.)

2. make simple_example

    make jsondump  등을 해줘서 아래와 같이 생성합니다. 




그 중 simple_example을 실행해 보겠습니다. 

(아래 결과는 박혀있는 key string값을 조금 수정해서 나온 결과입니다.)








3. Makefile 변경 - 입맛 대로 사용하기 (전처리 명령어 사용)

: jsmn 프로젝트의 Makefile을 변경해 새로운 기능을 추가시켜보자. 

simple.c를 print할 때, debug를 돕도록 각 token의 값을 다 보여주는 debug_mode를 새로 추가한다고 해보자. 


1) simple.c 수정 

 : 먼저 simple.c에 debug print를 위한 전처리 명령을 넣어준다.



2) Makefile 수정 

: 아래와 같이 debug_example이라는 새로운 target을 추가했다. 

이는 simple_example으로 작성된다. 


설명) 

기존에 정의되어 있는,


%.o: %.c jsmn.h

$(CC) -c $(CFLAGS) $< -o $@


에다가, D_OPTION이라는 새로운 변수를 써서, 거기에 -DDEBUG_MODE를 대체해 주게 했다. 


debug_example: D_OPTION = -DDEBUG_MODE

%.o: %.c jsmn.h

$(CC) $(D_OPTION) -c $(CFLAGS) $< -o $@


3) 결과는 다음과 같다  

make debug_example 을 해주면 아래와 같이, D_OPTION = -DDEBUG_MODE에서 정의해 놓은 것처럼 -DDEBUG_MODE가 대체되어 들어가게 되는 것을 볼 수 있다.




이때 주의해야할 점은, target file인 debug_example 실행파일이 그대로 생기는건 아니라는 점이다. 


simple_example실행 파일이 생성된다. 

-> simple_example를 debug_mode 옵션으로 컴파일 한것! 


따라서 ./simple_example을 해주면 아래와 같이, DEBUG_MODE가 적용된 output이 나오는 것을 확인 할 수 있다. 

















참고) 

https://www.joinc.co.kr/w/Site/C/Documents/UsedMake

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함