본문 바로가기
Tools for Dev

Make 에 대한 모든 것

by leanu 2023. 5. 9.

 

목차

 
 
  • make 소개
  • Makefile 기본편
    • 기본구조
    • Makefile.win (CYGWIN)
  • Makefile 응용편
    • Macro
    • Dependency
    • Command
    • Operation
 
 
make 소개

 
make 정의(by man) : GNU make utility to maintain groups of programs. The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them.
 
make 명령시 참조 파일 : 현재 디렉토리 내의 GNUmakefile, Makefile, makefile. Makefile을 권장함
 
make -f <파일명> : 특정파일을 Makefile 처럼 인식하여 make 명령을 수행할 때 사용. 와이즈넛에서는 윈도우 빌드시 Makefile.win 을 읽기 위해 해당 명령을 사용.
 
 
Makefile 기본편 - 기본구조

 
 
<target>: <dependency>
      <command>
 
  • target : command 수행 결과를 담는 곳. 모드, 파일, 패턴, 변수 등 다양하게 올 수 있음. dependency 로 지정된 대상이 변화가 없으면 target은 수행되지 않는다.
  • dependency : target 수행시 의존성을 검사하는 대상 target. 다른 target, 파일등등 target처럼 다양하게 사용 가능. 값이 없어도 됨.
  • command : target에 대한 실제 수행 명령을 담는 부분. 반드시 tab 으로 구분되어야 함. bash 명령어 참조
 
여기서 잠깐 : mode
 
  • 표준 모드 : all , clean , install, test
    • all : 현제 디렉토리 내의 모든 것을 빌드. ( 모드를 입력으로 주지 않으면 all 부터 시작함 )
    • clean : 빌드 생성물을 모두 삭제.
      • tip : clean 으로 모든 생성물을 잘 제거했는지 확인 ( VCS로 확인 가능 : subversion / git 등 )
    • install : 빌드 생성물 중 설치 대상 파일들을 설치 디렉토리에 설치함.
    • test : 현 디랙토리 내의 테스트를 위한 빌드 (및 수행)를 진행함.
 
Makefile 기본편 - Makefile.win (CYGWIN)

  • 모든 경로는 (환경변수 포함) dos 경로로 지정되어야 함.
    • unix 경로( /cygdrive/d/home/user/program )는 오동작을 일으킴. dos 경로 ( "c:/cygwin64/home/user/program" ) 으로 지정되어야 함.
    • unix 경로를 dos 경로로 바꾸려면 cygpath.exe 를 이용함
      • 예 : cygpath -d $PWD
  • 컴파일 전 build_system/confs 아래 해당 빌드옵션.env 파일을 환경변수로 정의해야 한다.
    • 예 : 빌드 정보가 ia64-w64-msvc90-64 인 경우 컴파일 전 아래의 명령을 수행해야 함
 
$ source ia64-w64-msvc90-64.env
 
 
 
 
 
Makefile 응용편 - Macro

 
  • 명령어 수행 결과를 변수에 넣기 $(shell 명령어)
 
TEST_SRC = $(shell ls t_*.java)
 
 
  • internal macro
    • $* : 확장자 제거한 target 파일
    • $@ : 만들어질 파일 이름 (target)
    • $< : dependency 로 주어진 파일 중 변경된 파일명
    • $? : dependency 로 주어진 모든 파일 set

  • suffix replace macro
    • OBJS = ${SRCS: .c=.o} 
      • SRCS 의 모든 파일에 대한 .c 확장자를 .o로 대치하여 OBJS 에 저장
 
<Makefile>
 
SRCS = aaa.c bbb.c ccc.c
OBJS = ${SRCS: .c = .o}
 
all : xxx
 
xxx : $(SRCS)
    @echo "================== xxx ==================="
    @echo "target ===== $@"
    @echo "newer sources = q $?"
    @echo "newer sources = g $<"
 
%.c:
    @echo "target ==== $@"
    @echo "asterisk ==== $*"
<출력>
 
$ make
target ==== aaa.c
asterisk ==== aaa
target ==== bbb.c
asterisk ==== bbb
target ==== ccc.c
asterisk ==== ccc
================== xxx ===================
target ===== xxx
newer sources = q aaa.c bbb.c ccc.c
newer sources = g aaa.c
target ==== all.c
asterisk ==== all
cc    -c -o all.o all.c
cc: all.c: 그런 파일이나 디렉토리가 없음
cc: no input files
make: *** [all.o] 오류 1
 
 
Makefile 응용편 - dependency

 
target 및 dependency 에서 자주 사용하는 패턴
  • %.o : *.o 파일을 의미함.  "t_%: t_%.o" 등으로 패턴적용 응용 사용 가능
    • 예) %.o : %.cpp
 
 
Makefile 응용편 - command

아래의 command 는 bash 명령어에 기반한 내용이다. bash의 다양한 명령어를 사용하여 Makefile 을 구축할 수 있다.
 
(참고) Makefile 내에서 명령어 앞에 @를 사용하는 경우 명령어가 출력되지 않음.
 
 
  • 하위 디렉토리 순회
 
DIRS = aaa bbb ccc ddd
 
all:
    @for dir in $(DIRS); do \
        echo "===> $(PWD)/$$dir"; \
        (cd $$dir && $(MAKE) -f $(MAKE_FILE) $@) || exit 1; \
        echo "<=== $(PWD)/$$dir"; \
    done
 
 
 
Makefile 응용편 - operation

 
  • 특정 변수에 대한 확인 : origin
    • 문법 : $(origin variable)
    • return 값
      • undefined : 정의되지 않음
      • default : default 값이 있는경우
      • environment : 환경변수로 정의됨 ( -e 등의 복잡한 부분은 이곳 참조 : http://www.viper.pe.kr/docs/make-ko/make-ko_8.html )
      • file : makefile 에서 정의되었음
      • command line : 명령행에서 정의되었음
      • 등등
    • 보통 ifeq 과 함께 사용
 
ifeq ( $(origin SF1_SRC), undefined )
$(error no environment variable SF1_SRC)
else
 ...
endif
 
 
  • 정렬 및 중복제거 : sort
    • 문법 : $(sort list)
 
SORT = $(sort foo bar lose bar2 lose)
 
all:
    @echo "sort === $(SORT)"
sort === bar bar2 foo lose
 
 
  • wildcard 실제 텍스트 변환 : wildcard
    • 문법 : $(wildcard text)
      • 예: $(wildcard *.cpp)
    • OBJ = *.o 를 하게 되면 OBJ 는 *.o 라는 문자열을 가지게 된다. 만약 현재 경로에 o 파일이 아무것도 없어도 OBJ 는 *.o를 갖게 되어 알수없다는 컴파일 에러를 내게 될 것이다. 그래서 *.o 보다는 wildcard 와 문자열 치환 함수를 통하여 구현하는 것을 권고한다.
 
 
  • 일괄치환 : patsubst
    • 문법  : $(patsubst 원본패턴, 대치할패턴, 텍스트)
    • 보통 wildcard 와 함께 사용하며 특정 경로의 모든 패턴의 파일 리스트에 대한 확장자 변경을 할때 사용한다.
 
DIRS = ./module1 ./module2 ./module3
OBJS = $(patsubst %.cpp, %.o, $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp)))
 
 
 
  • 다른 Makefile 내용 포함 : include
    • 보통 Makefile.win 에서 Makefile 과 그 내용이 동일할때(java compile 등) 사용함.
 
<$(SF1_SRC)/src/isc/qp/qpapi/java/Makefile.win 내용>
 
include $(SF1_SRC)/src/isc/qp/qpapi/java/Makefile
 
 
 
 
 
 
 
References

 

 

댓글