'Program Lang.'에 해당되는 글 72건

  1. 2013.12.31 Find 명령어
  2. 2013.11.04 환경 변수
  3. 2013.05.21 참고자료
  4. 2013.05.18 8. static, shared library makefile
  5. 2013.05.13 6. source와 object 분리
  6. 2013.05.13 5. Makefile Rules
  7. 2013.05.11 1. basic makefile structure syntax
  8. 2013.05.09 3. VPATH(vpath), conditional and include 지시자
  9. 2013.05.09 4. variable and macros
  10. 2012.12.27 9. makefile structure for large project

Find 명령어

Program Lang./Shell Script 2013. 12. 31. 15:56

1. 정의

 

directory hierarchy에서 파일을 찾는데 사용하는 외부 명령어 (Shell Script 기준)

 

2. 개요

 

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [expression]

 

위의 개요에서 복잡한 앞의 option들은 생략하고 expression에서 관해서만 알아본다.

 

3. [expression]

 

이 부분에 올 수 있는 정보는 아래와 같다.

자세한 사항은 GNU Manual을 참조, 차 후 보기 쉽게 하기위해서 그냥 내가 알아볼 수 있도록 정리

 

1) OPTIONS : find 명령어의 전체 동작에 영향을 미친다. 항상 TRUE를 리턴한다.

 

2) TESTS : 성공 여부에 따라서 FALSE/TRUE 리턴

 

3) ACTIONS : 성공 여부에 따라서 FALSE/TRUE 리턴

 

4. TESTS에 대한 간단한 예제

 

find /home -empty -type f

[설명] home 디렉토리 아래 파일들에 대해서 사이즈가 '0'인 파일을 찾아준다 

 

find -name "test.*"

[설명] 현재 디렉토리에서 이름이 test로 시작하는 모든 확장자에 대해서 찾아준다

 

5. ACTIONS에 대한 간단한 예제

 

find . -type f -print -exec file '{ }' \;

[설명] 현재 디렉토리에서 파일들에 대해서 file 명령어를 실행한다.  

 

[위의 예제에서 추가 설명]

 

1) '{ }'는 앞의 find에서 찾은 파일로 대체된다. { }보다는 '{ }'를 사용한 것은 Shell Script에서 해석을 막기 위함이다.

find 명령어는 Shell Script의 내부 명령어가 아닌 외부 명령어이기 때문에 쉘스크립트에 의한 해석을 막아야 한다.

 

2) \; 또한 쉘스크립트에서 해석을 막기위함이다. find 명령어는 ;가 나올때까지 입력 argument로 인식한다. Shell Script로 해석을 막기위해서 escape문자인 \을 사용하였다.  

 

자세한 세부 내용은 GNU Manual 참조바람.

 

'Program Lang. > Shell Script' 카테고리의 다른 글

환경 변수  (0) 2013.11.04
참고자료  (0) 2013.05.21
:

환경 변수

Program Lang./Shell Script 2013. 11. 4. 10:31

1. Shell 변수와 환경 변수의 차이

 

쉘스크립트에서 일반적으로 선언된 변수는 쉘변수라고 하고 지역적인 한계성을 갖는다.

전역적으로 쉘스크립트 동작에 영향을 미치는 변수를 환경변수라고 한다.

환경변수 선언은 export를 사용하여 선언하며 예제는 아래와 같다.

 

예제 - 변수 선언

 

LANG="ISO-8859-1"                     (Shell Variable)

export LANG="ISO-8859-1"            (Shell Envrionment Variable)

unset LANG                                 (변수 제거)

 

2. 환경 변수의 확인

 

Bash Shell              ->   env 명령어

csh Shell                ->   set 명령어

 

# export  [enter]

   환경 변수 내용 출력 ....

 

3. 환경 변수 설정 과정

 

환경 설정 과정은 운영체제나 Shell의 종류마다 다르지만 Bash 기준으로 정리한다.

환경 변수는 profile에 의해 설정되는데 크게 Global과 계정(Session) Profile로 나눈다.

 

모든 계정에 동일하게 적용되는 환경변수는 Global영역에 존재하면 아래 파일에 존재한다.

 

/etc/profile

/etc/bashrc 

 

계정 (Session)은 로그인시에 사용자별로 적용되는 환경변수가 적용되어 있다.

 

.bashrc  


'Program Lang. > Shell Script' 카테고리의 다른 글

Find 명령어  (0) 2013.12.31
참고자료  (0) 2013.05.21
:

참고자료

Program Lang./Shell Script 2013. 5. 21. 14:48

1. Shell Script 참고 자료

 

http://wiki.kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/index.html

 

2. Chapter 중요 포인터 요약

 

2.1. 초급 과정

 

  ▶ 변수 값 할당 시 주의 사항 : 공백이 없도록 한다.  

  ▶ "{$변수}"와 "$변수"의 차이점 : 동일하다.

  ▶ quoting 의미가 무엇인가? : "$변수", '$변수', `$변수` 의 차이와 의미

  ▶ 각 괄호의 의미와 차이점 : [ ], { }, ( ) 

  ▶ echo의 사용법 : echo -e, echo -n 의 의미 정도

  ▶ escape 문자의 의미와 사용법

 

2.2. 중급 과정

 

  ▶ Shell 내부 명령어 (Bultin Command)와 외부 명령어의 차이점

  ▶ 동일 명령가 내부와 외부로 Shell Script에서 구분지어주는 방법

  ▶ 외부 명령어 중에 find/grep/head/tail/wc 용법 정도는 주의깊게 보자

  ▶ 파일디스크립터의 의미와 재지향의 의미

 

2.3 고급 과정

 

  ▶ 정규 표현식의 의미

  ▶ sed/awk의 용법

 

다 중요한 부분이지만 처음 읽을 때 주의 깊게 봐야할 부분을 그냥 정리한 것이다.

 

 

 

'Program Lang. > Shell Script' 카테고리의 다른 글

Find 명령어  (0) 2013.12.31
환경 변수  (0) 2013.11.04
:

8. static, shared library makefile

Program Lang./Makefile 2013. 5. 18. 14:11

1. Makefile Rule for static library build

 

static library는 archive library라고도 불리고, 빌드를 위한 Makefile Rule은 아래와 같다.

 

libname.a : libname.a 을 구성할 object 파일 목록들 기술

[ TAB ] $(AR) $(ARFLGS) $@ @^

또는

[ TAB ] $(AR) $(ARFLGS) $@ @?                        # 변경이 있는 object만을 반영하기 위해서는 $? 사용

 

여기서 $(AR)은 ar 명령어를 나타내며, 사용법과 옵션은 아래와 같다. $(ARFLGS)의 기본값은 rv이다.

 

ar option archive object-file...

 

option 

설명 

 r

 오브젝트를 삽입, 이미 같은 이름이 있으면 대체한다. 정적라이블러리를 만든는 표준방법

 t

 아카이브의 내용을 테이블로 출력, 자세한 출력은 v 옵션을 추가로 설정

 d

 아카이브에서 지정한 오브젝트를 삭제

 

마지막으로 archive library는 자신이 포함하고 있는 심볼에 대해서 index정보를 가지고 있어야 한다. 현재 GNU같은

최신 make는 자동으로 ar 명령어가 생성하지만 그렇지 않은 make는 아래와 같은 추가 작업이 필요하다.

 

라이블러리이름(확장자 a) : archive library를 구성하는 object member들 기술

[ TAB ] $(RANLIB) $@

 

정적 라이블러리 생성 룰과 index 생성 룰을 하나로 합쳐서 만들면 더 좋겠죠... 

 

2. Makefile Rule for shared library build

 

정적 라이블러리가 빌드과정에서 모든 라이블러리를 실행파일에 포함시키는 구조라면 동적 라이블러리는 빌드 중에는

라이블러리 사용에 대한 정보만 포함하고 실제 로딩은 실행파일 실행 중에 수행한다. 따라서 동적 라이블러리는

이를 만족하기 위해서 추가적으로 몇가지 단계가 필요하다. 두 라이블러리 간의 차이점과 사용법은 해당 부분 참조 바람.

 

단계별로 살펴보면 다음과 같다.

 

1) 위치 독립적인 코드 생성 : -fPIC 컴파일 옵션으로 object 파일 생성

 

gcc -g -c -fPIC -\all bar.c foo.c

 

2) 공유 라이블러리 생성 : -shared 컴파일 옵션 추가

 

gcc -g -shared -o libdemo.so bar.o foo.o 


 

3) 동적 라이블러리를 Alias를 이용해 생성: -\, soname, 옵션

 

gcc -g -shared -\l, -soname, libdemo.so.1 -o bar.o foo.o

 

2), 3)은 동일하게 동적 라이블러리를 생성하는 방법이지만 3)은 좀 더 관리를 효율적으로 하기위해서 사용한다.

여기서 일일이 모든 것을 기술하면 지문이 지저분해지므로 라이블러리 이용편을 참조

 

3. 예제 Rule 

 

아래 예제는 정적과 동적 라이블러리를 만들어내는 rule이고, 동적 라이블러리 생성 시에는 -fPIC 옵션이 들어가야한다.

 

$(static_lib) : $(objects)

@echo "static library building : "\$@\""

@test -d $(lib_dir) || mkdir -p $(lib_dir)

@rm -rf $@

@$(AR) $(ARFLGS) $@ $?  

 

$(shared_lib) : $(objects)

@echo "shared library building : "\$@\""

@test -d $(lib_dir) || mkdir -p $(lib_dir)

@rm -rf $@

@$(CC) -shared --\l,-soname,$@.0 -o $@.0.0.0 $?

@ln -f $(notdir $@.0.0.0) $@

@ln -f $(notdir $@.0.0.0) $@.0

 

추가적으로 동적 라이블러리는 그 관리 및 사용상의 특징으로 세가지의 파일이 필요하다.

위 동적 라이블러리 생성 rule에서 $@.0.0.0 형태의 동적 라이블러리만 만들어진다.

하지만 실제 실행 시에는 -soname에 명시된 이름을 실행 파일에서 찾게된다. 따라서 이를 위해 링크를 생성해줘야 한다.

마지막으로 빌드 중 링크과정에서 확인하는 라이블러에 대해서도 링크를 걸어줘야 한다.

아래 매크로(함수)는 그런 기능을 수행하는 것으로 install Target에서 호출하면 일을 덜 수 있다.   

 

make_symlink = test -L $2 -a $1 == "`readlink $2`" || (rm -rf $2; ln -v $1 $2)

 

$(call make_symlink, libcurl.so.7.31.0, libcurl.so)                    # 빌드 중 링크 과정에서 필요한 라이블러리 생성

$(call make_symlink, libcurl.so.7.31.0, libcurl.so.7)                 # 실행 중 필요한 Allias 라이블러리 생성

'Program Lang. > Makefile' 카테고리의 다른 글

6. source와 object 분리  (0) 2013.05.13
5. Makefile Rules  (0) 2013.05.13
1. basic makefile structure syntax  (0) 2013.05.11
3. VPATH(vpath), conditional and include 지시자  (0) 2013.05.09
4. variable and macros  (0) 2013.05.09
:

6. source와 object 분리

Program Lang./Makefile 2013. 5. 13. 14:27

1. 개요

 

3장의 VPATH 설명 부분에서 소스 파일은 소스 디렉토리에 헤더 파일은 헤더 파일로 분리하였다.

Makefile에서 make가 실행되어 소스 파일을 찾는 부분은 현재 make가 실행되는 위치에 모두 있어야 한다.

하지만 VPATH라는 내부 규칙을 사용함으로써 디렉토리를 용도에 맞게 분리할 수 있었다.

 

2. 개선

 

3장의 VPATH 예제에서 문제점은 소스 파일 디렉토리인 src 폴더에 Command가 성공적으로 실행되면

오브젝트 파일이 모두 src 폴더에 존재한다는 것이다. 딱히 문제되지는 않지만 SVN 같은 툴을

써서 소스의 변경사항을 commit할 시 이들이 같이 존재하면 상당히 번거롭다.

 

아래 예제는 오브젝트 파일이 obj 폴더에 별도로 만들어지도록 하였다. 차 후 Dependency 파일 또한 만들어야

하는데 이렇게 분리하여 관리하는 것이 바람직하다.

 

3. 예제

 

exam3.zip

 

Pattern Rule의 Target이 기존 Pattern Rule에 비해 어떻게 바뀌었는지 보자.

또한 object 파일을 만들때 기존에는 소스파일의 확장자를 단순히 오브젝트 파일의 확장자를 변경하는

내부 매크로 함수를 사용하였느나, 디렉토리 또한 Prefix로 붙어야 해서 다른 함수를 사용하였다.

즉 object 변수에는 obj폴더가 앞에 붙어서 오브젝트 이름이 생성되어 pattern rule에 전달되고

pattern rule도 이를 지원하기 위해서 바뀌었다.

 

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

obj_dir = obj
include_dir = include

VPATH = src
CFLAGS += -I $(include_dir)

sources = 
sources += bar.c foo.c main.c

objects = $(foreach src,$(sources),$(obj_dir)/$(src:.c=.o))

all : $(objects) exec

exec : $(objects)
	gcc -o exec $^			# Using Automatic Expanded Variable
	
clean :
	rm -rf $(obj_dir) *.exe
	
$(obj_dir)/%.o : %.c
	echo "Starting Pattern Rules ..."
	@test -d $(obj_dir) || mkdir -p $(obj_dir)
#	$(CC) -MMD -MF $*.d $(CFLAGS) -o $@ -c $<
	$(CC) $(CFLAGS) -o $@ -c $<


 

'Program Lang. > Makefile' 카테고리의 다른 글

8. static, shared library makefile  (0) 2013.05.18
5. Makefile Rules  (0) 2013.05.13
1. basic makefile structure syntax  (0) 2013.05.11
3. VPATH(vpath), conditional and include 지시자  (0) 2013.05.09
4. variable and macros  (0) 2013.05.09
:

5. Makefile Rules

Program Lang./Makefile 2013. 5. 13. 08:05

1. Rule의 종류

 

  • Explicit Rules

 

- Rule의 구성에 생략되는 부분이 없으며, 각 대상을 명확하게 지정한다. 참 애매하긴 하지만

  앞에서 살펴본 것처럼 일반적으로 wildcard나 내부 변수를 사용하지 않는 경우이다.

 

  • Pattern Rules

 

- 명확하게 Target이나 Prerequisite에 대한 파일이름 대신에 Wildcard를 사용한 어떤 패턴 형태이다.

  위의 Explicit Rule과 반대되는 경우라고 보면 된다.

 

  • Implicit Rules

 

- Pattern Rule이나 Suffix Rule이긴 하나 make 내부변수나 database를 이용하여 정의한 Rule이다.

  Suffix Rule은 파일의 상관관계를 이용하여 자동으로 의존관계를 확장하는 Rule로 Pattern Rules

  이 나오기 전에 많이 사용하던 방식이다.

 

  • Static Pattern Rules

 

- Target 파일에 대한 리스트가 한정적으로 지정되어 있을 경우에 해당한다.

 

Rule을 위에서처럼 나누기는 했지만 makefile에서 Rule은 일반적으로 위의 Rule이 섞어있는 구조가

대부분이다. 앞으로 Explicit Rule 중심으로 살펴보면서 Target과 Prerequisite을 어떻게 다른 Rule로

확장해 가는지 보는 것이 이해가 빠를 것으로 보인다.

 

2. Suffix Rule

 

Implicit Rule을 정의하는 구형 방식이다. 하지만 여전히 많은 makefile에서 사용되므로 간단히 소개한다.

GNU makefile에서 Suffix Rule을 Pattern Rule로 대체되었다.

이름에서 유추되듯이 파일 확장자 규칙을 이용하여 Rule을 확장함을 알 수 있다.

 

.c.o :

$(COMPILE.c) $(OUTPUT_OPTION) $< 

 

Pattern Rule로 위의 Suffix Rule을 다시 쓰면 아래와 같다. 다만 Target과 Prerequisite를 선언하는 방식이 다르다.

 

%.o : %.c

$(COMPILE.c) $(OUTPUT_OPTION) $< 

 

위의 예제는 double suffix rule에 해당하고 single-suffix rule은 일반적으로 실행파일을 생성시 사용한다.

 

.p :

$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@ 

 

동일한 Pattern Rule은 아래와 같다.

 

%: %.p 

$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@ 

 

Suffix Rule은 일반적으로 알려진 파일 확장자 규칙을 사용한다. 파일 확장자 규칙에 등록은 .SUFFIXES 지정자를

통해서 이루어지고 이를 수정하면 자신에 맞는 구성을 할 수 있다.

 

.SUFFIXES : .out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l

 

.SUFFIXES :                                    # make --no-builtin-rules (or -r)와 동일 : 확장자가 등록 해제  

 

3. Implicit Rules

 

Implicit Rule은 built-in pattern rule이다. 즉 make에서 지원하는 rule 확장 규칙이다.

implicit rule을 사용하고자 하면 command 부분을 생략하면 된다. make가 target에 가장 적합한 rule을 찾아서 빌드한다.

 

make에서 지원하는 built-in pattern rule은 아래와 같은 명령어로 확인할 수 있다.

 

make -p or make --print-data-base

 

impilicit rule을 사용 시에는 Target이 원하는 rule에 의해서 빌드되도록 주의를 기울여야 한다.

또한 implicit rule에 적용된 변수들을 제정의할 때도 주의를 기울여야 한다.

 

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

CC = gcc

OUTPUT_OPTION = -o $@ 

 

위 implicit rule에 정의된 CFLAGS 변수에 대한 내용을 잘못 수정하면 원하는 동작을 할 수 없을 수 있으니

주의를 기울여야 한다.

 

아래 예제는 1장에서 다루었던 기본 Makefile 구조를 내부 확장 규칙을 사용하는 Implicit Rule로 바꾼 것이다.

Target 인 all 밑에 아무 command가 존재하지 않는데 소스파일에서 오브젝트 파일이 생성된다.

내부 확장 규칙을 사용하여 빌드가 된 것이다. 내부 매크로인 subst와 자동 확장 변수는 다음에 소개된 장을

참조하고 여기서는 주의를 기울일 필요없다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

sources = 
sources += bar.c foo.c main.c

objects = $(subst .c,.o,$(sources))

all : $(objects) exec

exec : $(objects)
#	gcc -o exec $(objects)
	gcc -o exec $^			# Using Automatic Expanded Variable

clean :
	rm -rf *.o *.exe


 

4. Pattern Rules

 

아래의 예제는 위의 Impilicit Rule Makefile에서 소스를 오브젝트로 빌드하는 내부 규칙 대신에

새로운 Pattern을 적용하였다. Pattern Rule을 어떻게 사용하는지 확인할 수 있다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

sources = 
sources += bar.c foo.c main.c

objects = $(subst .c,.o,$(sources))

all : $(objects) exec

exec : $(objects)
#	gcc -o exec $(objects)
	gcc -o exec $^			# Using Automatic Expanded Variable
	
clean :
	rm -rf *.o *.exe
	
%.o : %.c
	echo "Starting Pattern Rules ..."
	@test $(dir $@) || mkdir -p $(dir $@)
#	$(CC) -MMD -MF $*.d $(CFLAGS) -o $@ -c $<
	$(CC) $(CFLAGS) -o $@ -c $<


 

'Program Lang. > Makefile' 카테고리의 다른 글

8. static, shared library makefile  (0) 2013.05.18
6. source와 object 분리  (0) 2013.05.13
1. basic makefile structure syntax  (0) 2013.05.11
3. VPATH(vpath), conditional and include 지시자  (0) 2013.05.09
4. variable and macros  (0) 2013.05.09
:

1. basic makefile structure syntax

Program Lang./Makefile 2013. 5. 11. 15:35

1. makefile란

 

make 유틸리티는 소스간에 dependency와 timestamp 관계를 이용하여 빌드를 자동으로 해주는 유틸리티이다.

이 유틸리티에서 사용하는 자동 스크립터가 makefile이다.

 

$ make [Target]                       /* -C 옵션 : 스크립트가 위치한 디렉토리 지정, -f 옵션 : 기본 이외의 파일 지정 */

 

쉘에서 위처럼 make 명령어를 수행하면 기본값으로 현재 디렉토리에서

makefile, Makefile 또는 GNUMakefile 의 이름을 갖는 자동 스크립트 파일이 존재하는지 검사하여 실행한다.

 

만약 기본값을 바꾸고 싶으면 옵션을 이용하여 변경할 수 있다.

 

2. makefile 기본 구조

 

makefile은 아래와 같이 Target, Prerequisite, Command의 묶음으로 이루어져 있고, 이를 Rule이라고 한다.

Rule의 동작은 Target을 생성하기 위해서 Command를 수행한다. Command를 수행하기 전에 먼저 Prequisite의 

존재 여부나 변경 여부를 검사한다. 만약 Prerequisite가 존재하지 않거나 변경이 있으면 Prerequisite를 만드는

Rule 찾아서 먼저 수행한다. Prerequisite를 만드는 Rule또한 아래와 같은 기본 구조로 이루어져 있다.

 

하나의 Rule에는 아래와 같이 Target. Prerequisite, Command가 여러개로 구성될 수 있다.

이 경우에는 각 Target은 동일한 Prerequisite와 Command 동작을 수행함을 알 수 있다.  

 

[상기 사항] Command 영역은 쉘상에서 수행되며, 실제 명령어 수행은 새로운 쉘인 Sub-Shell에서 수행한다.  

 

Target1 Target2 Target3 : Prerequisite1 Prerequisite2

[ tab ] command1                                                                                /* Shell Command 영역 */

[ tab ] command2 

 

3. 용어 정리

 

  • Default Rule

 

- makefile가 Rule의 집합으로 이루어져 있다. 가장 최상위에 존재하는 Rule을 Default Rule이라 한다.

 

  • Default Target

 

- make 명령어를 쉘상에서 실행 시, Target를 지정하지 않으면 스크립트 상의 최상위 Target이 실행된다.

  이를 Default Target이라고 한다.

 

4. 예제

 

exam1.zip

 

예제 파일은 makefile의 Rule의 기본 구조와 의존관계처리를 어떻게 처리하는지 정도만 알아보는 구조이다.

main.c파일은 실제 실행코드가 들어있고 bar.c와 foo.c 파일을 단순히 자신의 이름을 출력하는 함수를 가지고 있다.

더 형식적이고 일반적인 구조는 더 진행하면서 알아보도록 한다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

exec : bar.o foo.o main.o
	gcc -o exec bar.o foo.o main.o

#bar.o : bar.c
bar.o : bar.h bar.c
	gcc -c bar.c

foo.o : foo.h foo.c
	gcc -c foo.c	
	
main.o : bar.o foo.o
	gcc -c main.c

clean :
	rm -rf *.o *.exe


위 예제에서 bar.o Target를 생성하는 Rule에서 bar.h 파일이 Prerequisite에 존재하지 않게하고

bar.h을 수정하였을 경우, make 동작은 할 일이 없다는 메세지를 출력한다. 즉 헤더파일도 의존관계에 포함시켜야

한다는 것이다. 이에 대한 자세한 내용은 앞으로 알아볼 것이다.  

 

5. 마무리

 

이 장에서 중요한 것은 기본적인 용어와 makefile의 구조이다. Rule에 대한 정의를 이해하는 것이 중요하다.

 

6. reference

 

● GNU make 문서

http://www.gnu.org/software/make/manual/make.html


● GNU make 한글판 버전

     http://www.viper.pe.kr/docs/make-ko/make-ko_toc.html


● 참고 사이트

http://wiki.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make.html
http://wiki.kldp.org/KoreanDoc/html/gcc_and_make/gcc_and_make-3.html

 

● OREILLY Open Book

http://oreilly.com/catalog/make3/book/

 

'Program Lang. > Makefile' 카테고리의 다른 글

6. source와 object 분리  (0) 2013.05.13
5. Makefile Rules  (0) 2013.05.13
3. VPATH(vpath), conditional and include 지시자  (0) 2013.05.09
4. variable and macros  (0) 2013.05.09
9. makefile structure for large project  (0) 2012.12.27
:

3. VPATH(vpath), conditional and include 지시자

Program Lang./Makefile 2013. 5. 9. 13:23

1. VPATH, vpath 란?

 

make가 Target과 Prerequisite를 찾을 위치를 현재 디렉토리 뿐만 아니라 VPATH에 명시된 위치에서 

추가적으로 찾아보도록 지시할 수 있다. VPATH는 Target과 Prerequisite에 대해서 찾을 위치를 추가적으로 명시하는

것이지 command line에 있는 파일의 위치는 명시하지 않는다.

 

첫번째에서 소개한 예제를 아래와 같이 소스 파일은 src 디렉토리에 header파일은 include에 Makefile과 main.c파일

은 exam 상위 폴더에 위치하도록 수정하고 Makefile을 수정하였다.

 

예제 파일 : 

exam2.zip

 

 

아래 Makefile에서 주석처리된 부분을 풀면 VPATH를 활성화하고 VPATH에 대한 동작을 확인할 수 있다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

#VPATH = src

exec : bar.o foo.o main.o
	gcc -o exec bar.o foo.o main.o

bar.o : src/bar.c include/bar.h
#bar.o : bar.c include/bar.h
	gcc -I include -c src/bar.c

foo.o : src/foo.c include/foo.h
#foo.o : foo.c include/foo.h
	gcc -I include -c src/foo.c	
	
main.o : bar.o foo.o
	gcc -I include -c main.c

clean :
	rm -rf *.o *.exe

 

VPATH는 찾을 디렉토리만을 설정한다. 따라서 어떤 소스파일을 찾기 위해서 VPATH를 모두 찾아봐야 한다.

소스의 리스트가 적으면 그리 큰 문제가 되지 않지만 소스파일이 많으면 부하가 걸리는 문제가 있다.

이를 좀 개선한 것이 vpath 구문이다. 사용법과 수정된 Makefile은 아래와 같다.

 

vpath pattern directory-list

 

아래에서 header의 위치까지 포함시키면서 Prerequisite에서 include폴더의 명시를 제거할 수 있다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

vpath %.c src
vpath %.h include

exec : bar.o foo.o main.o
	gcc -o exec bar.o foo.o main.o

#bar.o : include/bar.h src/bar.c
bar.o : bar.c bar.h
	gcc -I include -c src/bar.c

#foo.o : include/foo.h src/foo.c
foo.o : foo.c foo.h
	gcc -I include -c src/foo.c	
	
main.o : bar.o foo.o
	gcc -I include -c main.c

clean :
	rm -rf *.o *.exe



마지막으로 command line를 더 Makefile의 일반적인 표현으로 수정하려면 makefile variable 편에서

Automatic variable을 숙지한 후 더 간단한 makefile을 만들 수 있다.

 

2. Conditional Processing

 

Makefile에서 코드를 선택적으로 포함시키거나 배제할 수 있다. 형식은 아래와 같다.

 

ifdef variable-name                    # variable-name : $( )로 정의되면 안된다.  

ifndef variable-name

ifeq test                                    # test : (a, b), "a" "b", 'a' 'b' 가 될 수 있다.

ifneq test 

 

예제는 아래와 같다.

 

libGui.a : $(gui_objects)

$(AR) $(ARFLAGS) $@ $<

ifdef RANLIB

$(RANLIB) $@

endif

 

 

3. Include Directive (Include 지시자)

 

makefile 하나에 모든 rule을 기술할 수 있다. 하지만 공통으로 사용되는 makefile은 별도로 분리하여 필요할 때

현재 makefile에 포함시켜 사용하면 구조적으로 이해하기 쉽고 일반적으로 대형 프로젝트에서는 그렇게 한다.

 

사용법은 아래와 같다. 자세한 예제는 생략하고 차 후 어느정도 형식을 갖쳐진 makefile에서 소개할 것이다.

 

include [상위위치] definitions.mk                                     # makefile 상에서

 

make --include-dir [찾을 디렉토리 위치] (-I)                     # command 상에서 include 디렉토리 위치 지정법  

 

include 지시자는 C언어의 #include문과 유사하게 동작하며, make에서 rule 처리 과정 중에 include를 만나면

그 makefile까지 포함하여 rule에 대한 전반적인 2단계 스캔을 수행한다. 이 부분은 rule 소개 부분을 참조 바람.

 

 

'Program Lang. > Makefile' 카테고리의 다른 글

5. Makefile Rules  (0) 2013.05.13
1. basic makefile structure syntax  (0) 2013.05.11
4. variable and macros  (0) 2013.05.09
9. makefile structure for large project  (0) 2012.12.27
7. Automatic Dependency Generation  (0) 2012.12.26
:

4. variable and macros

Program Lang./Makefile 2013. 5. 9. 09:01

1. Variables (변수)

 

makefile에서 사용자 변수를 지정할 수도 있고 환경변수나 make 내부 변수를 사용할 수 있다.

 

1.1. 변수 사용 규칙

 

makefile은 대소문자를 구분한다. 일반적으로 환경변수나 make 내부 변수를 재정의하고자 할 경우에는

대문자를 사용한다. makefile 내에 사용자 정의 변수를 선언하고자 하는 경우에는 소문자를 사용하는 것이 일반적이다.

 

# make built-in 변수 재 정의

CC         := gcc

MKDIR    := mkdir -p

 

#internal variable 정의

source = *.c

objects = $(subst .c,.o,$(source)) 

 

1.2. 변수 유형 (Variable Types)

 

변수의 유형은 크게 simply expanded와 recursively expanded 변수로 분류한다.

 

  • simply expaned variable (:=)

 

- := 할당자를 사용한다. 할당자 오른쪽 내용은 해당 라인을 읽음과 동시에 확장된다.

 

  • recursively expanded variable (=)

 

- = 할당자를 사용한다. 할당자 오른쪽에 정의된 내용은 실제 변수가 사용되기 전까지 확장을 연기한다.

 

MAKE_DEPEND := $(CC) -M                                            # simply expanded variable

MAKE_DEPEND = $(CC) -M                                            # recursively expanded variable

 

위의 예제에서 simply expaned 변수에서 CC가 정의되지 않을 경우, MAKDE_DEPEND는 <space> -M으로 확장한다.

space는 아무 데이터가 없다는 뜻이다. 하지만 recursively expanded 변수에서는 변수를 읽을 당시에는 선언되지

않았더라도 변수를 실제 사용하기 전에 선언되었다면 정상적으로 gcc -M으로 확장할 것이다.

 

추가적으로 변수를 할당하는 방식에 따라 두 가지 할당 방식이 있다.  

 

  • conditional variable assignment operator (?=)

 

- 왼쪽 변수에 초기값이 설정되어 있지 않을 경우에만 오른쪽에 할당된 값을 할당한다.

 

  • append assigment operator (+=)

 

- 이 할당자는 기존 할당내용에 추가적으로 내용을 할당한다

 

2. 매크로 (Macro)

 

변수가 한라인 정의를 하는 구조라면 매크로는 여러줄로 명령어나 해야할 일을 정의할 수 있다.

매크로의 시작은 define이라는 지정자를 통해서 이루어진다. 자세한 내용은 생략하고 사용예만

소개하고 마무리한다.  

 

define free-space

$(PRINTF) "Free disk space"

$(DF) . | $(AWK) 'NR == 2 {print $$4}'

endef                                                                # end of define 매크로 정의  

 

3. 변수 및 매크로 확장 규칙

 

위에서 변수의 유형과 할당 방식에 따라서 확장 규칙이 다양하다. 언제 변수와 매크로 또는 지시자들이 확장되는지를

요약한다.

 

make는 두번에 걸쳐서 makefile을 스캔한다. 첫번째는 변수와 매크로 또는 include 지시에 명시된 makefile에 대해서

모든 변수와 매크로를 make 내부적으로 데이터베이스화하고 저장한다.

두번째 스캔에서는 실제 업데이트되어야 할 Target과 Prerequisite를 확인하고 command를 수행한다.

 

아래 표는 변수 및 매크로가 언제 확장되거나 확장을 지연하는지에 대해서 요약하였다.

또한 예제를 통해서 이를 확인해 본다.

 

 Definition

Expansion of a 

Expansion of b 

 a = b

 Immediate

 Deferred (recursively expanded variable)

 a ?= b

 Immediate

 Deferred

 a := b

 Immediate

 Deferred

 a += b

 Immediate

 Deferred or Immediate

 define a

 Immediate

 Deferred

 b...

 

 Deferred

 b...

 

 Deferred

 b...

 

 Deferred

 endef

 

 Deferred

 

BIN, PRINTF, DF와 AWK의 정의가 뒤에 나오지만 Makefile을 실행하면 정상적으로 동작한다.

이는 매크로가 실제 사용될 때까지 모든 변수에 대한 정의는 연기되고 실제 사용될 때 확장되기 때문이다.

각 변수는 simply expanded로 구성되어 있는데 recursively expanded 변수로 정의해도 동작은 정상적이다.

 

#***********************************************************************#
# ----------------------------------------------------------------------
#  Copyright(c) 2012-2013 by hee-soon kim 
#
# All rights are reserved
# 
# ----------------------------------------------------------------------#
#
#  FILE NAME    : Makefile
#  VERSION      : 1.0
#  AUTHOR       : heesoon,kim(김희순), chipmaker.tistory.com)
#  DATE         : 2012/12/21
#
#***********************************************************************#

OUTPUT_DIR := /tmp

$(OUTPUT_DIR)/very_big_file:
	$(free-space)

define free-space
$(PRINTF) "Free disk space"
$(DF) . | $(AWK) 'NR == 2 {print $$4}'
endef

BIN 	:= /usr/bin
PRINTF	:= $(BIN)/printf
DF		:= $(BIN)/df
AWK		:= $(BIN)/awk


 

4. Target Specific Variable

 

변수의 효력이 특정 타겟에만 유효하도록 지정하고 싶을 경우에 사용하는 방식이다.

예제를 통해서 알아본다. 아래 코드를 보면 어떤식으로 정의하는지 이해할 수 있을 것이다.

 

gui.o : gui.h

$(COMPILE.c) -DUSE_NEW_MALLOC=1 $(OUTPUT_OPTION) $<

 

[Target Specific Variable]로 변경

gui.o: CPPFLAGS += -DUSE_NEW_MALLOC=1

gui.o : gui.h

$(COMPILE.c) $(OUTPUT_OPTION) $<

 

 

5. 변수의 정의는 어디서 가능한가?

 

  • File

 

- makefile 내에서 아니면 include 지시자에 의해 포함된 다른 makefile로부터 가능하다.

 

  • Command Line

 

- make를 실행하는 쉘명령어 프롬프트상에서 가능하며 여기서 지정한 값은 기존 파일에서 지정한 값을

  override한다. 이를 금하고 싶으면 override 지시자를 변수앞에 지정한다.

 

  • Enviroment

 

- 쉘의 환경변수를 변수로 사용할 수 있으며, 다른 것으로 선언할 수 있다.

 

6. export or unexport 지시자

 

현재 makefile에서 선언된 변수를 다른 makefile에서도 사용가능하도록 하고자할 때 많이 사용한다.

이 지시자는 export로 지정한 변수를 환경변수에 등록하여 모든 makefile에서 참조하도록 할 수 있다.

중요한 내용이고 makefile은 단순한 구조를 갖는 것이 아니고 tree 구조의 복잡한 구조를 가질 수 있다.

이 때 export의 사용은 매우 유용하다.

 

7. Automatic Variables

 

내부적으로 정의되어 command script에서 Target이나 Prerequisite에 대한 기술을 반복하는 것을

쉽게 해당 변수로 대체할 수 있다.

 

 Variable

설명 

$@ 

 Target을 나타내는 파일 이름

$% 

 현재 Target이 라이블러리 일때, .o파일에 대응하는 이름, gnu makefile에서는 사용하지 않음

$< 

 첫번째 Prerequisite  (확장자 규칙에서 사용가능)

$?

 현재 Target보다 최근에 변경된 Prerequisite List를 정의 (확장자 규칙에서 사용불가)

$^ 

 모든 Prerequisite에 대한 목록 (중복 목록을 출력할 수 있다, 확장자 규칙에서 사용불가)

$+ 

 $^과 유사하다. 중복을 출력하지 않는다.  

$* 

 Target 파일이름에서 확장자를 제외한 파일이름을 표시

 

8. Standard make Variables

 

make는 자신의 상태를 관리하거나 보여주기위해서 아래와 같은 표준 변수를 내부적으로 관리한다.

몇가지 변수는 큰 makefile를 만들 때 유용하다.

 

 Variables

설명 

 MAKE_VERSION

 make의 버전정보를 가지고 있다.

 CURDIR

 현재 작업 디렉토리 표시 (--directory (-C) 옵션을 사용하지 않을 경우)

 MAKEFILE_LIST

 make가 빌드를 위해 읽은 makefile list 표시

 MAKECMDGOALS

 command line상에서 지정한 target를 표시

 .VARIABLES

 makefile을 읽는 동안 정의된 변수 목록을 출력

 

 

:

9. makefile structure for large project

2012. 12. 27. 10:20

보호되어 있는 글입니다. 내용을 보실려면 비밀번호를 입력하세요.