소프트웨어 컴파일 (Make)

EEEFFEE·2023년 11월 1일

System Programming

목록 보기
2/19

23.11.01 최초 작성
23.11.16 예제 추가

1. gcc 컴파일러

  • c 언어로 작성한 프로그램을 컴파일 하기 위해 C 컴파일러가 필요
  • 리눅스에서 사용하는 대표적인 컴파일러로 gcc가 있음

gcc [옵션] <.c 파일 이름>	

///
-g : 디버그 가능 추가
-o <실행 파일명>: 실행파일 이름 지정해 생성

2. make

  • 각 파일의 종속 관계를 파악해 컴파일 명령이나 쉘 명령을 수행하도록 작성한 파일
  • 반복적인 명령을 효율적으로 수행 가능함
  • 소스파일 일부가 변경되었을 경우 모든 컴파일 과정을 거치지 않고 변경된 내용만 컴파일 함

2.1 make 파일의 구성요소

  • target : 생성할 파일
  • dependency : 생성할 파일에 사용할 소스파일
  • command : 수행할 명령

gcc -c main.c
gcc -c add.c
gcc -c sub.c
gcc -o test main.o add.o sub.o

all: main.o add.o sub.o				//target의 default 이름
	gcc -o test main.o add.o sub.o
main.o: addsub.h main.c
	gcc -c main.c
add.o: add.c
	gcc -c add.c
sub.o: sub.c
	gcc -c sub.c
    
clean:								//생성된 필요없는 파일들 제거
	rm *.o test

2.2 macro

  • make파일의 요소를 변수로 관리하는 기능

CC=gcc
SRC=main.c add.c sub.c
main: ${SRC}
	${CC} -o test ${SRC}

make -p				//미리 정해져 있는 매크로 확인

///
$@					//현재 타겟의 이름
$^					//현재 타겟의 dependency 리스트
ASFLAGS = 			//as 명령어 옵션 세팅
- AS = as
CFlAGS = 			//gcc 옵션 세팅
- CC = cc
CPPFLAGS = 			//g++ 옵션 세팅
- CXX = g++
LDFLAGS = 			//ld 옵션 세팅
- LD = ld
LFLAGS = 			//lex 옵션 세팅
- LEX = lex
YFLAGS = 			//yacc 옵션 세팅
- YACC = yacc

CFLAGS = -Wall -O -g

bin=hello
t1=main
t2=funcs
obj=$(t1).o $(t2).o

all: $(bin)
$(bin): $(obj)
	$(CC) $(obj)  -o $@
clean:
	rm -f $(bin) *.o

3. TLPI Makefile 분석

  1. Makefile
    • DIRS : TLPI 내 모든 폴더를 표기 (먼저 표기된 디렉토리부터 빌드됨)
    • all : DIRS에 표기된 디렉토리로 가서 make실행
    • allgen : DIRS에 표기된 디렉토리로 가서 make allgen실행
    • clean : DIRS에 표기된 디렉토리로 가서 make clean실행

DIRS =	lib \
	acl altio \
	cap cgroups \
	daemons dirs_links \
	filebuff fileio filelock files filesys getopt \
	inotify \
	loginacct \
	memalloc \
	mmap \
	pgsjc pipes pmsg \
	proc proccred procexec procpri procres \
	progconc \
	psem pshm pty \
	shlibs \
	signals sockets \
	svipc svmsg svsem svshm \
	sysinfo \
	syslim \
	threads time timers tty \
	users_groups \
	vdso \
	vmem \
	xattr

BUILD_DIRS = ${DIRS}

all:
	@ echo ${BUILD_DIRS}
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE}) ; \
		if test $$? -ne 0; then break; fi; done

allgen:
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE} allgen) ; done

clean:
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE} clean) ; done

  1. Makefile.inc : 모든 디렉토리에서 빌드에 사용할 변수 및 옵션 표기

    • IMPL_CFLAGS : gcc 옵션 표기
    • ifeq ($(CC),clang) : clang 컴파일러 사용할 때 IMPL_CFLAGS 에 플래그 추가

TLPI_DIR = ..
TLPI_LIB = ${TLPI_DIR}/libtlpi.a
TLPI_INCL_DIR = ${TLPI_DIR}/lib

LINUX_LIBRT = -lrt
LINUX_LIBDL = -ldl
LINUX_LIBACL = -lacl
LINUX_LIBCRYPT = -lcrypt
LINUX_LIBCAP = -lcap

IMPL_CFLAGS = -std=c99 -D_XOPEN_SOURCE=600 \
		-D_DEFAULT_SOURCE \
		-g -I${TLPI_INCL_DIR} \
		-pedantic \
		-Wall \
		-W \
		-Wmissing-prototypes \
		-Wno-sign-compare \
		-Wimplicit-fallthrough \
		-Wno-unused-parameter

ifeq ($(CC),clang)
	IMPL_CFLAGS += -Wno-uninitialized -Wno-infinite-recursion \
			-Wno-format-pedantic
endif

CFLAGS = ${IMPL_CFLAGS}

IMPL_THREAD_FLAGS = -pthread

IMPL_LDLIBS = ${TLPI_LIB}

LDLIBS =

RM = rm -f

  1. pipes/Makefile
    • include ../Makefile.inc : Makefile.inc내용 include
    • GEN_EXE : 모든 target 표기
    • ${EXE} : ${TLPI_LIB} : Makefile.inc 에서 정의한 TLPI_LIB이 dependency (libtlpi.a)

include ../Makefile.inc

GEN_EXE = change_case fifo_seqnum_client fifo_seqnum_server \
	pipe_ls_wc pipe_sync popen_glob simple_pipe

EXE = ${GEN_EXE} ${LINUX_EXE}

all : ${EXE}

allgen : ${GEN_EXE}

fifo_seqnum_client.o fifo_seqnum_server.o : fifo_seqnum.h

clean :
	${RM} ${EXE} *.o

showall :
	@ echo ${EXE}

${EXE} : ${TLPI_LIB}		

0개의 댓글