'make'에 해당되는 글 4건

  1. 2011.06.08 [MAKE] Functions for Transforming Text
  2. 2011.06.08 [MAKE] Conditional Parts
  3. 2011.06.08 [MAKE] How to Use Variables
  4. 2010.06.04 [MAKE] Target

[MAKE] Functions for Transforming Text

CS/Shell/Perl/Python 2011. 6. 8. 16:43
원문 : GNU make

8.4 Functions for Conditionals

 
조건 표현을 제공하는 세 가지 함수가 있다. 모든 인자가 초기에 확장되지 않는다는 것이 이 세 함수의 중요한 면이다. 인자 중 확장되기를 원하는 인자만이 확장된다.
  1. $(if condition, then-part [,else-part])
    if함수는 함수적 문맥에서 조건적 확장에 대한 지원을 제공한다.
    첫 번째 인자인 condition은 먼저 모든 시작과 끝의 공백 문자를 제거하고, 그 이후에 확장된다. 만약 확장이 non-empty 문자열이라면 그 조건은 참으로 간주되며, 그렇지 않은 경우 거짓으로 간주된다.
    만약 조건이 참이라면 두 번째 인자인 then-part가 평가되고, 이것이 if 함수 전체 평가의 결과로 사용된다.
    만약 조건이 거짓이라면 세 번째 인자인 else-part가 평가되고, 이것이 If 함수 전체 평가의 결과로 사용된다. 만약 세 번째 인자가 없다면, if 함수는 아무것도 평가하지 않는다.
    주의할 것은 오직 the-part나 else-part만 평가되고, 두 부분이 모두 평가되지 않는다는 것이다. 따라서 side-effect가 발생할 수 있다.
     
  2. $(or condition1 [, condition2 [, condition3 ...]])
    or 함수는 "short-circuiting" OR 연산을 제공한다. 각 인자는 순서대로 확장된다. 만약 인자가 non-empty 문자열로 확장된다면 처리는 멈추고 그 확장의 결과가 결과 문자열이 된다. 만약 모든 인자가 확장되었고 모두가 거짓(empty)이라면, 확장의 결과는 빈 문자열이다.

  3.  $(and condition1 [, condition2 [, condition3 ...]])
    or 함수는 "short-circuiting" AND 연산을 제공한다. 각 인자는 순서대로 확장된다. 만약 인자가 empty 문자열로 확장된다면 처리는 멈추고 그 확장의 결과가 결과 문자열이 된다. 만약 모든 인자가 non-empty string으로 확장되었다면, 확장의 결과는 마지막 인자의 확장이 된다.
.
:

[MAKE] Conditional Parts

CS/Shell/Perl/Python 2011. 6. 8. 15:18
원문 GNU make
 

7.1 Example of a Conditional 


다음 예제는 CC변수가 gcc인 경우에 make가 라이브러리들 중 하나의 셋을 사용하게 하고, gcc가 아닌 경우에는 다른 라이브러리 셋을 사용하게 한다.

libs_for_gcc = -lgnu
normal_libs =

foo: $(objects)
ifeq ($(CC),gcc)
    $(CC) -o foo $(objects) $(libs_for_gcc)
else
    $(CC) -o foo $(objects) $(normal_libs)
endif

 
 혹은, 다음과 같이 변수를 조건부로 할당하고, 변수를 명시적으로 사용할 수도 있다

libs_for_gcc = -lgnu
normal_libs =

ifeq ($(CC),gcc)
    libs=$(libs_for_gcc)
else
    libs=$(normal_libs)
endif

foo: $(objects)
    $(CC) -o foo $(objects) $(libs) 

 

7.2 Syntax of Conditionals


syntax는 else가 없는 다음의 가장 간단한 형태부터 else를 포함한 두가지 형태가 있다.

conditional-directive
text-if-true
endif

conditional-directive
text-if-true
else
text-if-false
endif

conditional-directive
text-if-true
else
text-if-false
else
text-if-false
endif


조건을 테스트하는데는 다음의 4가지 지시자가 있다
  1. ifeq
    • iffeq (qrg1, arg2)
    • ifeq 'arg1' 'arg2'
    • ifeq "arg1" "arg2"
    • ifeq "arg1" 'arg2
    • 'ifeq 'arg1' "arg2"
      arg1과 arg2에 있는 변수의 참조를 모두 확장하여 그들을 비교한다. 만약 일치한다면 text-if-true 가 적용된다.
       
  2. ifneq
    • ifneq (qrg1, arg2)
    • ifneq 'arg1' 'arg2'
    • ifneq "arg1" "arg2"
    • ifneq "arg1" 'arg2'
    • ifneq 'arg1' "arg2"
      arg1과 arg2에 있는 변수의 참조를 모두 확장하여 그들을 비교한다. 만약 일치하지 않는다면 text-if-true 가 적용된다.
       
  3. ifdef variable-name
    name은 변수에 대한 레퍼런스가 아니라 변수의 이름을 나타낸다.

    bar = true
    foo = bar
    ifdef $(foo)
        frobozz = yes
    endif 

    $(foo)는 확장되어 bar가 되고, bar는 참조가 아니라 이름으로 간주된다. 


    만약 variable-name이 non-empty 값이 아니라면 text-if-true 가 적용된다.

    ifdef는 변수를 확장하여 그 값이 비어있는지는 확인하지 않는다(그 이름이 정의 되어 있는지만 확인). non-empty인지 확인하기 위해서는 ifeq($(foo),)를 사용한다.

    bar =
    foo = $(bar)
    ifdef foo
        frobozz = yes
    else
        frobozz = no
    endif

    sets ‘frobozz’ to ‘yes’, while:
    foo =
    ifdef foo
        frobozz = yes
    else
        frobozz = no
    endif

    sets ‘frobozz’ to ‘no’.

     
  4. ifndef variable-name 
    만약  vraiable-name이 empty 값이라면, text-if-true 가 적용된다.

7.3 Conditionals that Test Flags


findstring 함수와 함께 MAKEFLAGS 변수를 사용하여 -t 와 같은 make command flags를 테스트하는 조건을 쓸 수 있다. 
이것은 touch가 파일을 갱신하는데 충분하지 않을 때 유용하다.
findstring 함수는 한 문자열이 다른 부분 문자열로 나타나는지 확인한다. 만약 '-t' 플래그에 대해서 테스트하길 원한다면, 첫번째 문자열로 't'를 사용하고 비교할 다른 문자열로 MAKEFLAGS의 값을 사용한다.
다음은 아카이브 파일을 갱신하는 것에대해 마킹하는것을 종료하기 위해 'ranlib -t'를 사용하는것을 어떻게 정리하는지를 보여준다.

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
    +touch archive.a
    +ranlib -t archive.a
else
    ranlib archive.a
endif

'+' 접미어는 명령행 라인이 '-t' 플래그를 사용했음에도 불구하고 실행될 수 있게 하기 위해 "recursive" 하다는 것을 표시한다. (Section 5.7 Recursive Use of make 참고)
:

[MAKE] How to Use Variables

CS/Shell/Perl/Python 2011. 6. 8. 06:52
원문 : GNU make

6.1 Basics of Variable References


변수 이름에는 대문자를 사용하는 것이 관행이다.
하지만, makefile 안에서 internal purpose 을 수행하는 것은 소문자를 사용하고,  암묵적인 규칙을 제어하는 파라매터나 컴맨드 옵션에서 사용자가 오버라이드 해야만 하는 파라메터에 대해서는 대문자로 예약할 것을 것을 권장 한다.

$(foo) 나 ${foo} 와 같이 변수 이름을 () 나 {}로 감사고 $를 붙여서 참조할 수 있다.

6.2 The Two Flavors of Variables


GNU make 에서는 변수가 값을 갖도로 하는 네 가지 방법이 있다.
  1. recursive expanded variable 
    이 종류의 변수는 '='를 통해서 정의하거나(Section 6.5 [Setting Variables] 참고), define 지시자를 통해서 정의될 수 있다.
    만약 다른 변수에 대한 참조를 포함하고 있다면, 이 참조는 이 변수가 치환될 때마다 확장된다.

    foo = $(bar)
    bar = $(ugh)
    ugh = Huh?

    all:;echo $(foo)
    에서 $(foo)는 $(bar)로 확장되고, 이것은 다시 $(ugh)로  확장되어, 최종적으로 Huh? 로 확장될 것이다.


    이 종류의 변수는 모든 다른 make에서도 지원한다. 하지만

    CFLAGS = $(include_dirs) -O
    include_dirs = -Ifoo -Ibar

    CFLAGS = $(CFLAGS) -O 

    와 같이 한 경우, 변수 확장에 의해 무한 루프를 돌게 된다.

  2. expanded variable
    변수가 정의될 때 어떤 다른 변수나 함수에 대한 참조를 확장하여 한번만 스캔 되고 확장된다. 즉, 이 변수가 정의 되었을 때의 값을 가진다.

    x := foo
    y := $(x) bar
    x := later
    는,
    y := foo bar
    x := later 
    와 같다.  


  •  ?=를 이용해서 변수가 정의되어 있지 않을때만 정의할 수 있다.

    FOO ?= bar 는

    ifeq ($(origin FOO), undefined)
        FOO = bar
    endif

    와 동일하다. 


     만약 bar 가 정의되어 있지 않았을 때 FOO = bar 와 같이 한다면, FOO는 empty value로 정의된 상태가 된다.

  •  +=를 이용하여 이미 정의된 변수의 값에 추가로 문자를 더할 수 있다.

    objects = main.o foo.o bar.o utils.o
    objects += another.o


    +=를 사용하는 것은 :=를 다음과 같이 사용하는 것과 유사하다. 

    objects = main.o foo.o bar.o util.o
    objects := $(objects) another.o 

     
    만약 +=로 덧붙일 변수가 이전에 정의되어 있지 않았다면, +=는 =(recursively-expanded variable)과 동일하게 동작한다. 

6.3 Advanced Features for Reference to Variables


  • substitution reference
    지정한 대치값으로 변수의 값을 치환한다.  $(var:a=b) 혹은 ${var:a=b}와 같은 형식으로 사용되며, var 변수에 있는 a로 끝나는(다음에 whitespace가 나오는 a) 모든 a를 b로 치환한다.

    foo := a.o b.o c.o
    bar := $(foo:.o=.c)

    는 bar 를 a.c b.c c.c 로 치환한다.

    이는, 사실상 patsubst(Section 8.2 [Functions for String Substitution and Analysis] 참고) 함수 확장의 축약형이다. patsubst 함수의 모든 기능을 사용하기 위해서는 $(var:%a=%b)와 같이 %를 덧붙임 형태를 사용해야 한다. 

    foo := a.o b.o c.o
    bar := $(foo:%.o=%.c) 

    는 $(patsubst .o,.c,$(var))와 동일하다. 


  • computed variable name (nested variable reference)
     변수들은 변수의 안에 있는 이름으로 참조될 수 있다. 이를 computed variable name 혹은 nested variable reference라고 한다. 예를 들어

    x = y
    y = z
    a :=$($(x))

    에서 $($(x)는 $(y)가 되어, 결국 z가 된다.


    혹은 재귀적으로

    x = $(y)
    y = z
    z = Hello
    a := $($(x))

    에서 $($(x)) 는 $($(y))가 되고, 이것은 $(z) 가 되어, 결국 Hello가 된다. 


    Nested variable 참조는 변경된 참조나 함수 실행(Chapter 8 [Functions for Transforming Text] 참고) 등을 포함할 수 있다. 예를 들어 subst 함수를 사용하여

    x = variable1
    variable2 := Hello
    y = $(subst 1,2,$(x))
    z = y
    a := $($($(z))))

    $($($(z)))는 $($(y))가 되고, y는 variable2의 값을 가지게 되기 때문에,  $(variable2)가 되어, 결국 Hello를 정의하게 된다. 


    computed variable name은 하나의 변수 참조로 이루어질 필요는 없다. 예를 들어

    a_dirs := dira dirb
    1_dirs := dir1 dir2

    a_files :=filea fileb
    1_files :=file1 file2

    ifeq "$(use_a)" "yes"
        a1 := a
    else
        a1 := 1
    endif

    ifeq "$(use_dirs)" "yes"
        df := dirs
    else
        dif := files
    endif

    dirs := $($(a1)_$(df))

    $(a1) 이 a를 정의하고 $(df)가 dirs를 정의한다면, a_dirs가 되어 dirs 는 $(a_dirs)가 되어 결국,
    dirs := dira dirb
    를 정의하게 된다.

     
    computed variable name은 치환 참조에서도 사용될 수 있다.

    a_objects := a.o b.o c.o
    1_objects := 1.o 2.o c.o

    sources := $($(a1)_objects:.o=.c)
    는 a1이 어떤것을 가리키느냐에 따라

    sources := a.c b.c c.c
    혹은
    sources :=1.c 2.c 3.c
    가 될 수 있다. 


    또한, computed variable name을 변수 대입의 왼편이나 define 지시자에서 사용할 수 있다.

    dir = foo

    $(dir)_sources := $(wildcard $(dir)/*.c)

    define $(dir)_print = 
     
    lpr $($(dir)_sources)

    endef

    이는 foo_sources와 foo_print를 정의한다. 



:

[MAKE] Target

CS/Shell/Perl/Python 2010. 6. 4. 10:29
Internal Macro
원문 : KLDP

$*
: 확장자가 없는 현재의 목표 파일(Target)

$@
: 현재의 목표 파일(Target)

$<
: 현재의 목표 파일(Target)보다 더 최근에 갱신된 파일 이름

$?
:현재의 목표 파일(Target)보다 더 최근에 갱신된 파일이름

: