Integer i = a; // AutoBoxing...
int a = i; // AutoUnboxing
objcopy는 오브젝트 파일을 다른 오브젝트 파일로 복사할 때 사용한는데, 선택적으로 필요한 부분만을 복사할 수 있기 때문에 파일의 사이즈를 줄이는 데 주로 사용되고, 바이너리 포맷을 바꾸는 데도 이용된다.
ex) objcopy hello hello.new
hello 파일을 hello.new로 복사, 기존의 hello와 동일하다.
ex) objcopy -O binary hello hello.new
위 명령은 hello 파일에서 인스트럭션과 데이터만을 뽑아서 hello.new로 만든다. 이렇게 만들어진 hello.new는 ELF 헤더도 붙지 않은 순수한 바이너리 그 자체다. 주로 부트 로더를 만들 때 이런 식으로 사용하는데 이유는 모든 CPU마다 전원이 인가되었을 때 CPU가 인스트럭션을 처음 읽어서 실행할 번지가 정해져 있다. 예를 들면 i386 계열은 0xfffffff0 번지이고 ARM 계열 CPU는 0x0 번지며 MPC860 CPU 같은 경우 0xff00100번지다.
무슨 말이냐하면 i386 계열 CPU는 전원이 켜지는 순간 BIOS의 POST(Power On Self Test) 프로그램이 위치하는 0xfffffff0 번지의 인스트럭션을 제일 처음 읽어서 수행한다.
i386 PC 외의 CPU 같은 경우 처음 수행하는 프로그램은 부트 로더인데 이러한 부트 로더는 인스트럭션이 제일 앞에 와있는 바이너리여야 한다. 즉 ELF 헤더가 붙어서는 안 된다는 이야기다. ELF 헤더는 운영체제에서 필요한 정보지 CPU에서 필요한 정보는 아니다.
ex) objcopy -S hello hello.new
모든 심볼들과 재비치 정보들을 제거하여 hello.new 파일을 만든다. 그래서 바이너리 파일의 사이즈가 확실히 줄어든다.
- 참고 문헌 : 유닉스, 리눅스 프로그래밍 필수 유틸리디
원문: http://kelp.or.kr/korweblog/stories.php?story=02/03/31/9629811
gcc는 예전에는 GNU C Compiler의 약자였으나 지금은 GNU Compiler Collection의 약자로
다양한(?) 언어의 컴파일러들의 집합체이다. gcc는 한마디로 GNU에서 개발된 ANSI C 표준을 따르는 C 언어 컴파일러라고
말할 수 있다. gcc는 ANSI C 표준에 따르기는 하지만 ANSI C 표준에는 없는 여러 가지 확장 기능이 있다. 또한
gcc는 통합개발환경(IDE)을 가지고 있지 않은 command line 컴파일러이다. 옛날 Turbo-C를 주로 사용해 보셨던
분들은 tcc.exe와 비슷하다고 생각하면 된다.
(*) -v 옵션
현재 사용되고 있는 gcc의 버전을 나타내는 옵션이다. 특정 소프트웨어 패키지를 컴파일하기 위해 어느 버전 이상의 gcc를 쓰도록 권장하는 경우가 있는데 시스템에 깔려있는 gcc의 버전을 파악하려고 할때 사용한다.
이제 직접 프로그램 하나를 컴파일하면서 설명하도록 하겠다. 아래는 hello.c의 소스이다.
#include〈stdio.h〉 int main() { printf(“hello gccn”); return 0; } |
#define max(x, y) ((x) 〉(y) ? (x) : (y) /* 마지막에 ")"가 없다!!! */ int myMax(int a, int b) { return max(a, b); } |
int func3(void); /* func3 선언 */ extern int mydata; /* mydata 선언 */ int func2(void) /* func2 정의 */ { …. } int func1(void) /* func1 정의 */ { int i; ….. func2(); ….. func3(); …. i= mydata+3; ….. } -- end of test1.c -- start of test2.c int mydata = 3; /* mydata 정의 */ int func3(void) /* func3 정의 */ { ….. } |
1. 일반적인 옵션
옵션 |
설명 |
-dumpmachine | 컴파일러의 타겟을 출력하고 종료됨 |
-dumpspecs | GCC의 기본 스펙 문자열 표시 |
-dumpversion | 컴파일러의 버전 숫자를 표시 |
--help | 기본적인 사용에 대한 도움말 표시 |
-pass-exit-code | 컴파일 과정에서 실패하는 경우 가장 큰 에러 값을 반환 |
-pipe |
컴파일 과정에서 정보를 주고 받는 방법으로 중간 파일이 아닌 pipe를 사용 |
-print-file-name=lib | 라이브러리 경로를 표시 |
-print-libgcc-file-name | 컴파일러의 라이브러리 경로를 표시 |
-print-multi-directory | libgcc 모든 버전의 루트 디렉토리를 표시 |
-print-multi-lib | 명령 행 옵션과 다수의 라이브러리 디렉토리 사이의 관계를 표시 |
-print-prog-name=prog | prog 프로그램의 경로를 표시 |
-print-search-dirs | 디렉토리 검색 경로를 표시 |
-save-temps | 컴파일 도정에 생성되는 중간 파일을 저장 |
--target-help | 컴파일러의 타겟에서만 쓰이는 명령 행 옵션에 대한 도움말 표시 |
-time | 각 컴파일 과정에서의 수행 시간을 표시 |
-v | 각 컴파일 과정에서 실행되는 프로그램과 인자를 표시 |
-V ver | 컴파일러의 버전 숫자가 ver인 컴파일러를 실행 |
--version | 컴파일러의 버전 정보와 간단한 라이선스 정보를 표시 |
2. 전처리기 옵션
[test.c] #include <stdio.h> Int main(void){ |
옵션 |
설명 |
-Dname | 외부에서 name에 해당하는 #define을 지정 |
-Dname=def | 외부에서 name에 해당하는 매크로를 정의하고 값을 def로 지정 |
-Uname | 외부에서 name에 해당하는 #undef 지정 |
-undef | 공용,표준 매크로를 제외한 모든 매크로의 설정을 해제 |
-include [헤더파일 경로] | 해당 헤더 파일을 모든 소스에 추가 ex) include /root/my.h |
-M or -MM | make 파일을 위한 소스 파일의 종속 항목 출력 |
-nostdinc | 표준 C 헤더 파일을 include 하지 않음 |
-C | 전처리 과정에서 주석을 제거하지 않음 |
-Wp, [옵션 리스트] | 옵션 리스트를 전처리기에 바로 전달 |
3. C 컴파일러 옵션
옵션 |
설명 |
-ansi | ISO C89 기능을 모두 지원하고 C89 표준과 충돌하는 GNU 확장 기능을 끔 |
-no-integrated-cpp | 내장된 전처리기 대신 외부 C 전처리기를 실행 |
-fallow-single-precision | Single-precishion 연산을 double-precision 연산으로 변환하지 않음 |
-fbuiltin | __builtin__ 접두사로 시작하지 않는 내장함수로 인식 |
-fcond-mismatch | 조건문에서 두 번째와 세 번째 인자의 형이 맞지 않는 것을 허용 |
-fno-builtin | __builtin__ 접두사로 시작하지 않는 내장함수는 무시 |
-fhosted | Hosted 환경에서 컴파일 |
-fno-asm | Asm, inline, typeof를 키워드로 사용하지 않고, 식별자로 사용 |
-fno-signed-bitfields | 선언되지 않은 비트 필드를 unsigned형으로 간주 |
-fno-signed-char | Char 형을 signed형으로 간주 |
-fno-unsigned-bitfields | 선언되지 않은 비트 필드를 signed형으로 간주 |
-fno-unsigned-char | Char 형을 unsigned형으로 간주 |
-fshort-wchar | Wchar_t 형을 강제로 shot unsigned int 형으로 간주 |
-fsigned-bitfields | 선언되지 않은 비트 필드를 signed형으로 간주 |
-funsigned-char | Char 형을 unsigned형으로 간주 |
-fwritable-strings | 문자열 상수를 쓰기 가능한 데이터 영역에 저장후 프로그램상에서 쓰기 가능하도록 함 |
-std=value | 사용하는 언어 표준을 value에 설정C89,C99,C9x,iso9899:1990,iso9899:199409,iso9899:1999,gnu89,gnu99) |
-traditional | Traditional (K&R) C에 대한 지원을 함 |
-traditional-cpp | Traditional (K&R) C 전처리기에 대한 지원을 함 |
-trigraphs | C89 trigraphs에 대한 지원을 함 |
-fopenmp | Open Mp를 사용 할 수 있도록 설정 |
-ffreestanding |
Freestanding(unhosted) 환경에서 컴파일 (ffreestanding: 표준 라이브러리가 존재하지 않으며 이 환경에 맞게 작성된 프로그램은 반드시 main 함수에서 시작하지 않을지도 모르는 환경) |
-aux-info file | 하나의 translate unit 안에서 선언된 함수에 대한형과 식별 정보를 file에 저장 (int sum(int a, int b) { return a + b; } ----> int sum(int , int );) |
4. 디렉토리 검색 옵션
옵션 |
설명 |
-B prefix |
서브 프로그램, 라이브러리, 헤더 파일 실행 시 이름에 prefix가 붙은 파일을 실행하도록 설정 |
-I dir |
헤더 파일을 검색하는 디렉토리 리스트 앞부분에 dir을 추가 (dir을 우선적으로 검색) /usr/local/include/tmax2 |
-I- | 사용자 헤더파일 (“aaa.h”) –I- 사용자 or 시스템 헤더파일(<bbb.h>) ex) $gcc /usr/local/include/tmax –I- /usr/local/include/netdev |
-L dir | 라이브러리 파일을 검색하는 디렉토리 리스트 앞부분에 dir을 추가 |
-specs=file | 표준 스펙 파일을 읽은 후에 컴파일러 스펙 파일을 읽는다. |
※ - I 옵션의 기본동작 : 해당 경로의 시스템 헤더와 사용헤더를 모두 찾음 파일을 실행하도록 설정
-I- 앞의 –I옵션 :해당 경로의 사용헤더만 모두 찾음
-I- 뒤의 –I옵션 : 해당 경로의 시스템 헤더와 사용헤더를 모두 찾음
[출처] [GCC] options 1|작성자 로사
함수(functions)는 여러분이 makefile안에서, 작업할 파일들을 알아내거나 아니면 사용할 명령들을 알아낼 수 있도록, 텍스트를 처리하는 것이다. 함수는 dfn{함수 호출(function call)} 안에서 사용한다. 여기에서 함수의 이름과 함수가 작업할 텍스트(매개변수(arguments) 를 제공한다. 함수 처리의 결과는 makefile의 그 호출 위치에 삽입된다. 마치 변수가 대입된 것처럼.
함수 호출은 변수 참조와 닯았다. 이것은 다음과 같이 보일 것이다:
$(function arguments)
또는 다음과 같이 보일 것이다:
${function arguments}
여기서 function는 함수 이름이다; make
의 일부인 이름들 짧은
리스트의 하나. 새로운 함수를 정의하기 위한 준비는 없다.
arguments는 함수의 매개변수들이다. 이들은 함수와 하나 이상의 공백이나 탭으로 분리되며, 한 개 이상의 매개변수들이 있으면 그들은 콤머로 구분된다. 그런 공백문자와 콤머들은 매개변수 값의 일부가 되지 않는다. 함수 호출을 둘러싸는 데 사용한 구분자들은, 괄호들이나 중괄호들은, 짝이 맞는 꼴로만 나타날 수 있다; 다른 종류의 구분자들은 단신으로 나타날 수 있다. 매개변수들 자신이 다른 함수 호출들이나 변수 참조들을 가진다면 모든 참조들에 대해서 동일한 종류의 구분자들을 사용하는 것이 가장 현명할 것이다; `$(subst a,b,${x})' 이 아니라 `$(subst a,b,$(x))' 를 쓰자. 이렇게 하는 것이 좀 더 명확하기 때문이다. 그리고 한가지 종류의 구분자만이 참조의 끝을 찾기 위해서 서로 비교되기 때문이다.
각 매개변수 텍스트는 매개변수 값을 만드는 변수 대입과 함수 호출들에 의해서 처리된다. 이것이(이 결과가) 함수가 작동하는 대상 텍스트이다. 대입은 매개변수들이 나타난 순서대로 행해진다.
콤머들과 일치하지 않은 괄호나 중괄호들은 매개변수가 작성된것과 동일한
텍스트로 나타날 수 없다; 앞에 있는 공백들은 작성된 것과 같은 첫번째
매개변수의 텍스트로 나타날 수 없다. 이런 문자들은 변수 대입을 통해서
매개변수 값들로 넣어질 수 있다. 먼저 그것의 값들이 콤마나 공백
문자들로 구분된 변수 comma
와 space
를 정의한 뒤 이들
변수들을 그런 문자들이 필요한 곳에, 다음과 같이, 대입한다:
comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# bar is now `a,b,c'.
여기서 subst
함수는 foo
의 값 전체에서 각 스페이스를 콤머로
변경하고 그 결과를 이 값에 대입한다.
다음은 문자열들에 대해서 작동하는 함수들이다:
$(subst from,to,text)
$(subst ee,EE,feet on the street)는 `fEEt on the strEEt'를 대입한다.
$(patsubst pattern,replacement,text)
patsubst
함수 호출에 있는 `%' 문자들은 앞에 역슬래쉬
(`\')를 써서 인용될 수 있다. `%'를 인용했을 역슬래쉬들은 더
많은 역슬래쉬들에 의해서 인용당할 수 있다. `%' 문자들이나 다른
역슬래쉬들을 인용하는 역슬래쉬는 패턴에서, 이것이 파일 이름들과
비교되거나 그안에 대입된 줄기를 가지기 전에, 제거된다. `%'
문자들을 인용할 위험이 없는 역슬래쉬들은 아무런 간섭도 하지
않는다. 예를 들어서 `the\%weird\\%pattern\\' 는 `%' 문자
앞에 `the%weird\' 가 있고 뒤에 `pattern\\' 가 있다. 마지막
두 역슬래쉬들은 그들이 어떤 `%' 문자에도 영향을 미치지 않기
때문에 잔류한다.
단어들 사이에 있는 공백문자는 단일 스페이스 문자로 줄어든다; 이에
앞서거나 뒷선 공백문자들은 무시된다.
예를 들어서 다음은,
$(patsubst %.c,%.o,x.c.c bar.c)`x.c.o bar.o' 라는 값을 만든다. 대입 참조(see section 대입 참조(Substitution References) 는
patsubst
의 효과를 얻는 더 단순한 방법이다:
$(var:pattern=replacement)는 다음과 동일하다
$(patsubst pattern,replacement,$(var))두번째 짧은 표기 방법은
patsubst
의 가장 일반적인 사용들 중의
하나를 단순하게 만든다: 파일 이름들의 끝에 있는 접미사(확장자?)를
교체한다.
$(var:suffix=replacement)이것은 다음과 동일하다.
$(patsubst %suffix,%replacement,$(var))예를 들어서, 다음과 같은 오브젝트 파일들의 리스트를 가지고 있다면:
objects = foo.o bar.o baz.o이에 대응하는 소스 파일들의 리스트를 얻기 위해서 다음과 같이 쉽게 작성할 수 있다:
$(objects:.o=.c)이것은 다음과 같은 일반형태를 사용하는 것 대신에 쓸수 있다:
$(patsubst %.o,%.c,$(objects))
$(strip string)
strip
함수는 조건과 함께 사용될 때 아주 유용할 수 있다. 어떤
것을 빈 문자열 `'과, ifeq
또는 ifneq
를 사용해서,
비교할 때 보통 빈 문자열과 일치하는 공백의 문자열을 원할 것이다
(see section Makefile의 조건 부분(Conditional Parts of Makefiles)).
(그래서, ) 다음과 같은 것은 원하는 결과를 얻지 못한다:
.PHONY: all
ifneq "$(needs_made)" ""
all: $(needs_made)
else
all:;@echo 'Nothing to make!'
endif
ifneq
지시어에서 변수 참조 `$(needs_made)' 를 함수
호출 `$(strip $(needs_made))' 로 바꿈으로써 좀 더
엄격(robust)하게 만들 것이다.
$(findstring find,in)
$(findstring a,a b c)`a'와 `' (빈 문자열) 각각을 만든다.
$(findstring a,b c)
findstring
의
실질적인 응용에 대해서는 See section 플래그 검사 조건(Conditionals that Test Flags).
$(filter pattern...,text)
patsubst
함수에서 사용된
패턴과 마찬가지로, `%'을 사용하여 작성된다.
filter
함수는 한 변수 안에서 (파일 이름과 같은) 다른 타입의
문자열들을 분리 제거하는 데 사용될 수 있다. 예를 들어서:
sources := foo.c bar.c baz.s ugh.h는 `foo'가 `foo.c', `bar.c', `baz.s' 그리고 `ugh.h' 에 의존하지만 `foo.c', `bar.c' 그리고 `baz.s' 만이 명령안에서 컴파일러에 대해 지정되어야 한다는 것을 말한다.
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
$(filter-out pattern...,text)
filter
함수의 정확한 반대이다.
예를 들어서, 다음이 주어졌다면:
objects=main1.o foo.o main2.o bar.o다음은 `mains'에 있지 않는 오브젝트 파일들 모두를 담고 있는 리스트를 생성한다:
mains=main1.o main2.o
$(filter-out $(mains),$(objects))
$(sort list)
$(sort foo bar lose)이것은 `bar foo lose'를 리턴한다. 부수적으로
sort
함수는 중복된 단어들을 제거하기 때문에 이것을
소팅 순서에 대해서 신경쓰지 않더라도 이런 목적으로 이 함수를 사용할 수
있다.
다음은 subst
와 patsubst
사용의 현실적인
예제이다. makefile이 VPATH
변수를 사용하여 make
가 종속
파일들을 검색해야 할 디렉토리 리스트를 지정한다고 가정하자
(see section VPATH
: 모든 종속물에 대한 검색 패스(Search Path for All Dependencies)).
이 예제는 C 컴파일러에게 동일한 디렉토리 리스트에서 헤더 파일들을 찾는
방법을 말하는 방법을 보여준다.
VPATH
의 값은 `src:../headers'와 같이 콜론으로 분리되는
디렉토리 리스트이다. 첫번째, subst
함수는 콜론들을 스페이스들로
변경하는 데 사용된다:
$(subst :, ,$(VPATH))
이것은 `src ../headers'를 만든다. 그리고 나서 patsubst
는
각 디렉토리 이름을 `-I' 플래그로 변경하는 데 사용된다. 이것은
변수 CFLAGS
의 값에 더해질 수 있다. 이것은 자동으로 다음과 같이
C 컴파일러에게 전달된다:
override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
이것의 효과는
텍스트 `-Isrc -I../headers'를 CFLAGS
에게 사전에 주어졌던
값에 덧붙이는 것이다. override
지시어는, CFLAGS
의 이저의
값이 명령 매개변수로 주어졌다 하더라도 새로운 값이 할당되도록 하는 데
사용된다 (see section override
지시어).
내장 확장 함수들 몇가지는 특별히 파일 이름들을 또는 파일 이름들 리스트를 분해하는 데 연관이 있다.
다음 함수들 몇가지는 파일 이름에 대해서 특정 변환을 수행한다. 함수의 매개변수는 공백문자로 분리된, 일련의 파일 이름들로 취급된다. (앞뒤에 있는 공백문자들은 무시된다.) 이 일련의 파일 이름들 각각은 동일한 방식으로 변환되고 그 결과는 그들 사이에 단일 스페이스들을 넣어서 묶인 것이 된다.
$(dir names...)
$(dir src/foo.c hacks)는 `src/ ./'라는 결과를 만든다.
$(notdir names...)
$(notdir src/foo.c hacks)는 `foo.c hacks'라는 결과를 만든다.
$(suffix names...)
$(suffix src/foo.c src-1.0/bar.c hacks)는 `.c .c'라는 결과를 만든다.
$(basename names...)
$(basename src/foo.c src-1.0/bar hacks)는 `src/foo src-1.0/bar hacks' 라는 결과를 만든다.
$(addsuffix suffix,names...)
$(addsuffix .c,foo bar)는 `foo.c bar.c'라는 결과를 만들어낸다.
$(addprefix prefix,names...)
$(addprefix src/,foo bar)는 `src/foo src/bar'라는 결과를 만든다.
$(join list1,list2)
dir
과 notdir
함수들의 결과들을 머지(merge)해서
이들 두 함수들에 주어진 파일들의 오리지널 리스트를 만들 수 있다.
$(word n,text)
$(word 2, foo bar baz)`bar'를 리턴한다.
$(wordlist s,e,text)
make
는 그들을 서로 맞바꾼다(swap). 예를 들어서,
$(wordlist 2, 3, foo bar baz)는 `bar baz'를 리턴한다.
$(words text)
$(word $(words text),text)
로
표현될 수 있다.
$(firstword names...)
$(firstword foo bar)는 `foo'라는 결과를 만든다. 비록
$(firstword text)
가 $(word 1,text)
과 같지만 firstword
함수는 그
단순성 때문에 남았다.
$(wildcard pattern)
wildcard
함수의 결과는 패턴과 일치하는 현존하는 파일들의 이름들을 스페이스로
분리한 리스트이다.
See section 파일 이름에 와일드카드 사용(Using Wildcard Characters in File Names).
foreach
함수(The foreach
Function)
foreach
함수는 다른 함수들과 아주 다르다. 이것은 텍스트의 한
조각이 반복적으로 사용되도록 한다. 이때 매번 그것에 대해서 다른 대입이
수행된다. 이것은 쉘 sh
의 for
명령, 그리고 C-쉘
csh
의 foreach
명령과 닮은 것이다.
foreach
함수의 문법은 다음과 같다:
$(foreach var,list,text)
첫번째 두 매개변수들, var와 list는 다른 것이 수행되기 전에 확장된다; 마지막 매개변수 text는 동일한 시간에 확장되지 않는다. 그리고 나서 list의 확장된 각 단어에 대해서 var의 확장된 값을 가지는 변수는 이 단어로 설정되고 그 다음에 text가 확장된다. 아마 text는 그 변수에 대한 참조를 담고 있을 것이다. 그래서 그것의 확장은 매번 다르다.
결과적으로 text는 list에 있는 공백으로-분리된 단어들
개수만큼 확장된다. text의 여러 확장들이 그들 사이에 스페이스들을
넣어서 연결되어 foreach
의 결과를 만든다.
다음 단순한 예제는 변수 `files'를 `dirs' 리스트의 디렉토리들에 있는 모든 파일들의 리스트로 설정한다.
dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
여기서 text는 `$(wildcard $(dir)/*)'이다. 첫번째 반복은
dir
에 대해서 값 `a'을 찾아 넣고서 `$(wildcard a/*)'와
동일한 결과를 생산한다; 두번째 반복은 `$(wildcard b/*)'이라는
결과를 생성한다; 그리고 세번째는 `$(wildcard c/*)'.
이 예제는 다음 예제와 동일한 (`dirs'를 설정하는 것 빼고) 결과를 가진다:
files := $(wildcard a/* b/* c/* d/*)
text가 복잡할 때, 추가의 변수로, 그것에 이름을 주어서 가독성을 증진할 수 있다:
find_files = $(wildcard $(dir)/*)
dirs := a b c d
files := $(foreach dir,$(dirs),$(find_files))
여기서 우리는 변수 find_files
를 이런 식으로 사용하고
있다. 우리는 평범한 `='를 써서 재귀적으로-확장되는 변수 하나를
정의했다. 그래서 그것의 값을 foreach
의 제어하에서 다시
확장되어지는 실제 함수 호출에 따라서 가진다; 단순하게-확장되는 변수는
그렇지 않을 것이다. 왜냐면 wildcard
가 find_files
를
정의하는 순간에 한번만 호출될 것이기 때문이다.
foreach
함수는 변수 var에 대한 항구적인 효과를 가지지
않는다; foreach
함수 호출 이후 이것의 값과 취향은 그들이 이전에
그랬던 것과 동일하다. 다른 list로부터 취해진 다른 값들은 잠시
동안만, foreach
의 실행 동안만, 효력이 있다. 변수 var는
foreach
의 실행동안 단순하게-확장되는 변수이다. var가
foreach
함수 호출 이전에 정의된 것이 아니라면 이것은 그 호출
뒤에도 정의된 것이 아니다. See section 변수의 두 취향(The Two Flavors of Variables).
변수들 이름들을 결과로 가지는 복잡한 변수 표현식을 사용할 때 상당히 조심해야 한다. 왜냐면 많은 이상한 것들이 유효한 변수 이름들이지만 여러분이 의도한 것이 아닐 수도 있기 때문이다. 예를 들어서,
files := $(foreach Esta escrito en espanol!,b c ch,$(find_files))
이것은 find_files
값이 이름이
`Esta escrito en espanol!' (es un nombre bastante largo, no?) 인
변수를 참조하고 있다면 유용하겠지만 이것은 실수일 가능성이
더많다.
origin
함수(The origin
Function)
origin
함수는 변수들의 값에서 나타나지 않는다는 점에서 다른
함수들과 다르다; 이것은 하나의 변수에 대해서 어떤 것을 말하는
것이다. 특별히 이것은 이것이 어디로부터 온 것인가를 말한다.
origin
함수의 문법은 다음과 같다:
$(origin variable)
variable은 질의하고 있는 변수의 이름이다; 그 변수에 대해서 참조하는 것은 아니다. 그러므로 그것을 쓸 때 `$'나 괄호들을 일반적인 경우처럼 쓰지 않을 것이다. (그러나 그 이름안에서 변수 참조를 쓸 수 있다. 상수가 아닌 이름을 원한다면 말이다.)
이 함수의 결과는 그 변수 variable이 정의된 방법을 말하는 문자열이다:
CC
나 기타 등등처럼 일반적인 디폴트
정의를 갖고 있다면 이 값을 가진다. See section 묵시적 규칙에 의해 사용되는 변수(Variables Used by Implicit Rules). 디폴트 변수를 재정의한 것이라면
origin
함수는 추후 정의의 원천(origin)을 리턴할 것이다.
override
지시어로 makefile에서 정의된 것이라면
이 값을 가진다 (see section override
지시어).
이 정보는 주로 어떤 변수의 값을 믿고자 하는가 안하는가를 결정할 때
유용하다 (호기섬을 충족하는 것 말고). 예를 들어서 다른 makefile
`bar'를 포함하는 makefile `foo'를 가지고 있다고
가정하자. 명령 `make -f bar'를 실행한다면, 환경이
bletch
의 정의를 갖고 있다고 하더라도, bletch
가
`bar'에 정의된 것을 원한다. 그러나 `foo'가 `bar'를
포함하기 전에 bletch
를 정의했다면 그 정의를 오버라이드하기를
원하지 않을 것이다. 이것은 override
지시어를 `foo'에서
사용하고 그 정의를 `bar'에서 나중의 정의 이전에 정의함으로써
그렇게 할 수 있다; 불행하게도 override
지시어는 모든 명령행
정의들을 오버라이드할 것이다. 그래서, `bar'는 다음을
포함할 수 있을 것이다.
ifdef bletch
ifeq "$(origin bletch)" "environment"
bletch = barf, gag, etc.
endif
endif
bletch
가 환경으로부터 정의되었다면 이것은 그것을 재정의할
것이다.
bletch
의 이전 정의를 override하고자 하고 이것이 환경으로부터 온
것이라면, `-e'하에서조차, 여러분은 다음과 같이 쓸수 있을 것이다:
ifneq "$(findstring environment,$(origin bletch))" ""
bletch = barf, gag, etc.
endif
여기서 `$(origin bletch)'가 `environment' 또는 `environment override' 를 리턴한다면 재정의가 일어난다. See section 문자 대입과 분석을 위한 함수들(Functions for String Substitution and Analysis).
shell
함수(The shell
Function)
shell
함수는
wildcard
함수 (see section wildcard
함수(The Function wildcard
))를 제외하고, 이것이 make
의 바깥 세상과
통신한다는 점에서, 다른 함수들과 다르다.
shell
함수는 대부분의 쉘에서 역홑따옴표(``')가 수행하는
기능과 동일한 기능을 수행한다: 이것은 command expansion을 한다.
이것은 쉘 명령인 매개변수를 취하고 명령의 결과를 리턴한다는 것을
의미한다. make
가 이 결과에 대해서, 주변 텍스트로 이것을 대입하기
전에, 하는 유일한 처리는 각 개행이나 캐리지-리턴 / 개행 쌍을 단일
공백으로 변환하는 것이다. 이것은 또한 끝에 달린 (캐리지-리턴과) 개행을,
이것이 결과의 마지막이라면, 제거한다.
shell
함수에 대한 호출에 의해서 실행된 명령은 함수 호출이 확장될
때 실행된다. 대부분의 경우 이것은 makefile이 읽힐 때이다.
규칙의 명령안에 있는 함수 호출들은 그 명령이 실행될 때 확장된다는 것이
예외이며, 이것은 다른 모든 것들과 마찬가지로 shell
이라는 함수
호출에도 적용되는 것이다.
다음은 shell
함수의 사용에 대한 몇가지 예제들이다:
contents := $(shell cat foo)
이것은 contents
를 `foo' 파일의 내용으로 설정한다. 각 라인을
분리하는 공백들(개행이라기 보다는)로.
files := $(shell echo *.c)
이것은 files
를 `*.c'의 확장으로 설정한다. make
가
아주 이상한 쉘을 사용하고 있지 않다면 이것은 `$(wildcard
*.c)'과 동일한 결과를 얻는다.
출 처 : http://www.viper.pe.kr/docs/make-ko/make-ko_8.html
정말 간단한거라 감히 여기다 써도 될지 모르겠지만, 전 인터넷에서 이런 정보를 못얻었었기 때문에 올려봅니다ㅋ
일단 전 노트북을 사용하고 있구요, 허브나 스위치는 쓰지 않습니다. 그리구 리눅스는 vmware내에서 구동하고 있구요
노트북은 무선랜을 이용해 인터넷을 하구요, 유선랜은 타겟보드와 연결을 합니다.
근데 유선랜을 연결하면 vmware들어가서 custom방식으로 유선랜을 선택해줘야 tftp나 nfs를 할수있더군요. 이렇게하면 근데 리눅스머신의 인터넷이 안됩니다.
그래서 생각한방법
1. vmware리눅스 머신의 전원을 끕니다.
2. edit로 들어가서 네트워크 어댑터를 하나더 추가합니다.
3. 하나는 NAT방식(vmnet8을 이용하여 호스트에 공유하여 쓰는), 또하나는 custom방식(vmware 네트웍 세팅에서 vmnet0을 만들고 여기다가는 유선랜카드를 설정해줍니다)으로 해줍니다.
4. 리눅스를 켜면, NAT방식의 랜카드가 DHCP로 알아서 ip를 잡는데요, custom방식으로 한거는 ifconfig eth<n> <ip주소> 명령으로 서버 ip를 만듭니다.
5. 타겟보드는 호스트ip로 설정합니다.
6. 이렇게 하면 리눅스 머신은 putty를 이용할수도 있고 인터넷도 할수있으며, 타겟보드와 바로 통신할수 있습니다. ping을 쳐보면 잘갑니다
7. nfs설정하고 마운트 해줍니다. 이건 검색해보면 많이나오네요
아, 참고로 노트북의 윈도우의 유선랜의 ip는 맨 마지막 자리를 다르게 해서 주면 타겟보드, vmware리눅스머신, 노트북의 윈도우 세개가 서로서로 핑을 주고받는걸 볼수있습니다. (물론 서버ip와 호스트ip설정할때도 같은대역대 사용하기~)
이 방법을 쓰면 컴퓨터 한대, 타겟보드 하나로 공유기나 허브같은거 필요없이 어디서나 마음껏인터넷을하며 서로간에 통신도 가능하네요.
정말 보잘것없는 팁이지만, 인터넷에서는 못찾았었어요ㅎㅎ
[출처] VMware 리눅스 환경에서 TFTP,NFS 구동하기|작성자 조화