MINZKN의 블로그 http://www.minzkn.com/
BLOG main image

전체 (421)
minzkn™ (63)
Programming (276)
사용법/팁 (26)
타국에서 (15)
사진 (1)
퍼온글 (39)
조사 (0)
낙서장 (0)
서식/Template (0)
비밀글 (0)
Total : 270632
Today : 100
Yesterday : 188
6명이 RSS를 구독하고 있습니다.
Make 기초 사용법
Programming/이론/개요/접근/정리 | 2007/05/08 12:14
2007/05/08 12:14 2007/05/08 12:14
span class=postbody원래 의도는 무지 자세히 써보자는 취지에서 적기 시작했는데 br / 하다가 보니 저 역시 모르는 무지의 경우가 많더군요. br / 그래서 고작 요정도로 마무리 해버렸습니다. br / 맨날 문서 제대로 끝까지 작성하는것이 없는거 같네요. 저는 게으름뱅이 입니다. br / br / 또한 좋은 참고자료로는 a href=http://www.gnu.org/ target=_blankhttp://www.gnu.org/a 에서 찾아보시면(GNU make) 좀 방대한 물량의 문서도 접할수 있으니 참고하세요. br / br / 1.1 시작하기전에 br / 프로그래밍을 배우려면 우선 make의 기본용법이라도 알고 시작하자는 주장을 해봅니다. 그 만큼 매우 중요한 유틸리티입니다. 나름대로 간편한 문법과 가독성이 높은 문법 때문에 요즘 대부분의 거대한 공개 프로젝트들은 make를 널리 사용하고 있습니다. 꼭 프로그래밍의 세계에 입문을 하고자 하시는 분들께서는 make의 사용법을 적어도 기본문법이라도 알고 계셔야 합니다. 그래서 필자는 간략하게나마 도움이 되고자 이렇게 문서로 남깁니다. 부디 멋진 GNU 개발자가 되시길 바랍니다. br / br / 1.2 Make 의 목적 br /우리가 일반적으로 개발하고 관리하는 하나의 프로젝트는 C source를 컴파일하여 Object 파일을 만들고 이러한 Object 몇개를 묶어서 링크(Link)과정을 거쳐서 최종 목적인 실행파일을 생성합니다. 이때 사용하는 명령은 다음과 같겠죠. 아~ 무지 길다~! br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codebash# cc -O2 -Wall -Werror -fomit-frame-pointer -c -o test.o test.c br / bash# ls br / test.c test.o br / bash# ld -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o test.o br / bash# ./test br / Hello world ! br / bash# _/td /tr/tbody/tablespan class=postbody br / br /소스의 내용을 조금만 수정해도 이 과정은 반복되어야 합니다. 참~~~ 번거로운 일이 우리의 앞길?막고 있는듯한 느낌입니다. 그래서 이를 쉽게 간략화 해주는 유틸리티가 탄생했는데 make 가 바로 그것입니다. 실제로 make의 몇몇 기능만 사용하면 위의 문제는 쉽게 해결되지만 그 밖에 대규모 프로젝트에서 겪을수 있는 불편함을 해소해줄수 있다는 점이 보다 매력으로 다가올것입니다. br / br / 1.3 기본규칙 br / make는 크게 Target, Depend, Command, Macro 로 구성되어 있습니다. 우선 기본적으로 Target, Depend, Command 의 구성을 살펴보겠습니다. br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codelt;Targetgt;: lt;Dependgt; ?... [[;] lt;Commandgt;] br / lt;탭문자gt;lt;Commandgt;/td /tr/tbody/tablespan class=postbody br / br /여기서 Target은 생성하고자 하는 목적물을 지칭하며 Depend 는 Target을 만들기 위해서 필요한 요소를 기술하게 됩니다. 그리고 Command 는 일반 Shell 명령이 옵니다. 이때 Command는 Depend 의 파일생성시간(또는 변경된 시간)을 Target과 비교하여 Target 보다 Depend의 파일이 시간이 보다 최근인 경우로 판단될때에만 실행됩니다. 물론 이것에 대한 예외적인 규칙이 있습니다만 일단 무시하고 받아들이세요. 이제 간단히 다음과 같이 Makefile 이라는 파일명으로 다음과 같이 작성하여 make의 행동을 기술합니다. 단, 주의할것은 Command 는 반드시 앞에 lt;TABgt;문자가 와야 합니다. 물론 예외상황이 있기는 하지만 나중에 그에 대한 내용을 다루기로 하고 일단 ld, cc 명령 앞에 반드시 lt;TABgt;문자로 입력하세요. br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codetest: test.o br / nbsp; nbsp; nbsp; nbsp; ld -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o test.o br / br / test.o: test.c br / nbsp; nbsp; nbsp; nbsp; cc -O2 -Wall -Werror -fomit-frame-pointer -c -o test.o test.c/td /tr/tbody/tablespan class=postbody br / br / 이제 명령프롬프트상에서 make test 라고만 입력하면 다음과 같이 실행됩니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codebash# make test br / cc -O2 -Wall -Werror -fomit-frame-pointer -c -o test.o test.c br / ld -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o test.o br / bash# _/td /tr/tbody/tablespan class=postbody br / br /엇? 그런데 다시 실행해보시면 놀랍게도 이런 메세지가 나올겁니다. 이것이 바로 make 의 중요한 기능중에 한가지 입니다. 바로 똑같은 작업은 다시 해봤자 어차피 결과가 같을것이라는 예상때문에 더이상 같은 작업을 하지 않는 것이지요. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codebash# make test br / make: `test'는 이미 갱신되었습니다. br / bash# _/td /tr/tbody/tablespan class=postbody br / br / 그러면 간단히 다음과 같이 test.c 의 변경날짜를 바꿔봅시다. 그리고 다시 한번 make test명령을 수행해봅시다. 어떻습니까? 이번에는 다시 명령을 수행하는것을 보실수 있을겁니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codebash# touch test.c br / bash# make test br / cc -O2 -Wall -Werror -fomit-frame-pointer -c -o test.o test.c br / ld -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o test.o br / bash# _/td /tr/tbody/tablespan class=postbody br / br /이제 천천히 분석해보자면 Target 보다 Depend의 변경시간이 최근이라면 Command 를 수행한다고 하였습니다. 그래서 test 라는 Target이 test.o 에 의존관계를 갖고 있는데 test.o는 다시 Target으로 기술되어 있고 여기에 test.c가 의존관계로 기술되어 있습니다. 때문에 test.c가 최근에 변경되어 test.o보다 변경된 날짜가 최근이 되면 test.o를 새로 생성하게 됩니다. 또한 test.o는 test보다 최근에 변경된것으로 보이므로 test는 test.o에 의해서 새로 생성되는 결과를 가져옵니다. 결국 소스가 변경되지 않으면 make는 아무것도 안하지만 소스가 변경되면(변경된 날짜가 갱신되면) test는 새롭게 빌드되는 것입니다. br / br /이제 대충 의존관계 성립을 어떻게 기술하는지 보았습니다. 하지만 이렇게 작성하면 오히려 더 불편하다고 불만을 토하는 분들이 속출할것입니다. 그렇습니다. 실제로는 저렇게 작성하는 경우는 별로 쓰이지 않습니다. 조금더 세련되게 작성하도록 Macro 의 사용이 준비되어 있으니 불만은 이제 그만 하세요. br / br / 1.4 Macro br /매크로는 다음과 같이 = 문자의 왼편에는 Macro의 대표이름(Label)을 기술하고 오른편에는 그 내용을 적습니다. 이때 = 문자에 인접한 양쪽의 공백(Space)문자는 무시됩니다. 이것은 매우 기본적인 Macro를 예기하는것이며 이 밖에도 몇가지 확장된 Macro 가 있습니다. 하지만 일단 그것은 나중에 예기하도록 하겠습니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codelt;Macro namegt; = lt;Macro 내용gt;/td /tr/tbody/tablespan class=postbody br / br / 자! 이제 간단히 다음과 같이 조금 개선해서 Makefile을 작성해보겠습니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / test: test.o br / nbsp; nbsp; nbsp; nbsp; $(LD) $(LDFLAGS) -o test $(STARTUP) test.o br / br / test.o: test.c br / nbsp; nbsp; nbsp; nbsp; $(CC) $(CFLAGS) -o test.o test.c/td /tr/tbody/tablespan class=postbody br / br /여기서 하나만 살펴본다면 CC = cc 라고 매크로 선언을 보면 CC라는 매크로명은 cc라는 명령어로 정의됩니다. 이것을 사용하기 위해서는 $기호뒤에 괄호(과 )을 두고 그 안에 매크로 이름을 넣어 사용합니다. 즉, $(CC) 는 cc로 해석됩니다. 하지만 아직도 이것이 너무 복잡하다는 불만을 가지신분이 계실겁니다. make는 그래서 기본 확장자 규칙이라는 방법도 지원하고 있습니다. br / br / 1.5 기본 확장자 규칙 br /우리는 보통 C source를 목적파일로 컴파일합니다. 이것은 확장자가 통상 .c에서 .o를 만들어 내는 규칙이 생성될법 합니다. make는 이점에 착안하여 다음과 같은 확장자 규칙을 이용할수 있습니다. 물론 이것은 한가지 방법일 뿐이며 이 밖에도 몇가지 방법이 있습니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code.c.o: br / nbsp; nbsp; nbsp; nbsp; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br /이제 여기서 새롭게 등장한 $@와 $^, $lt; 의 의미를 예기할때가 왔습니다. 이것은 make의 기본 정의된 Macro중에 한가지 입니다. $@ 또는 $(@)는 바로 Target 을 말합니다. 그리고 $lt;는 열거된 Depend중에 가장 왼쪽에 기술된 1개의 Depend를 말하며 $^는 Depend 전체를 의미합니다. 이것은 앞으로도 make를 사용하는데 있어서 굉장히 많은 부분 기여하는 매크로이므로 눈여겨 보셔야 할 부분입니다. 이 밖에도 $? 로 있는데 이것은 Target과 Depend의 변경날짜를 비교하여 Depend의 변경날짜중에 최근에 변경된것만 선택하는 매크로입니다. $?는 주로 라이브러리의 생성 및 관리시에 사용되는데 나중에 시간되면 설명하겠습니다. br / br / 위의 기술은 확장자 .c를 가진 파일을 확장자 .o를 가진 파일로 생성하는 공통적인 확장자 규칙을 예로 작성한 것입니다. 한번 사용해볼까요? br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / test: test.o br / nbsp; nbsp; nbsp; nbsp; $(LD) $(LDFLAGS) -o $@ $(STARTUP) $^ br / br / .c.o: br / nbsp; nbsp; nbsp; nbsp; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br / 이게 .c.o 는 .c 를 .o로 만들어 보자는 내용입니다. 그리고 $lt;는 .c 에 취해지는 소스파일명인 test.c로 대체됩니다. 또한 $@는 Target인 test.o로 대치될것입니다. br / br / 1.6 가짜 target br /이제 지금까지 작성한 Makefile을 사용해보면 한가지 불편한 점을 느낀 분들이 계실겁니다. test.c로 test.o를 만들고 test.o로 test를 만들도록 작성하였지만 소스파일의 수정이 없는 경우 항상 make는 더이상의 컴파일 및 링크과정을 하지 않는 점입니다. 때문에 간혹 다시 깨끗히 빌드하고 싶을때 touch test.c를 수행하거나 rm test.o test 를 수행해야 합니다. 이것 역시 매우 불편합니다. 이를 해소하고자 다음과 같이 작성될수 있겠습니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / RM = rm -f br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / clean: br / nbsp; nbsp; nbsp; nbsp; $(RM) test.o test br / br / test: test.o br / nbsp; nbsp; nbsp; nbsp; $(LD) $(LDFLAGS) -o $@ $(STARTUP) $^ br / br / .c.o: br / nbsp; nbsp; nbsp; nbsp; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br /새로운 Target 인 clean이 보입니다. 그런데 Target clean에 대한 Depend가 없습니다. 이렇게 Depend 가 없으면 clean에 기술된 명령 $(RM) test.o test는 항상 실행되며 이것은 실제로 clean이라는 파일이 없습니다. 때문에 이것을 가짜 Target 이라고 합니다. 이제 make clean 하시고 make test하시면 항상 다시 빌드하는것을 볼수 있습니다. 하지만 만약 clean이라는 실행파일이 존재한다면 우리가 원하지 않는 결과가 나올법도 합니다. 물론 거의 대부분 clean이라는 실행파일을 만들지 않겠지만 우리는 여기서 make에서 Target clean는 가짜 Target 이라고 명확히 전달할 필요가 있습니다. 물론 불필요한 경우가 대부분의 경우지만 그래도 습관적으로 명시해주는게 좋습니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / RM = rm -f br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / .PHONY: all clean br / br / all: test br / br / clean: br / nbsp; nbsp; nbsp; nbsp; $(RM) test.o test br / br / test: test.o br / nbsp; nbsp; nbsp; nbsp; $(LD) $(LDFLAGS) -o $@ $(STARTUP) $^ br / br / .c.o: br / nbsp; nbsp; nbsp; nbsp; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br /자! 여기서 새로운 Target 인 .PHONY 가 보입니다. 이것은 make구문에서 예약된 Target 중에 하나이며 .PHONY에 명시된 Depend 는 모두 가짜 Target으로 보게 됩니다. 그리고 여기서 all이라는 Target이 추가되었습니다. 이것은 매우 관습적인 Target 으로 보통 최상단에 all과 clean이 위치하게 됩니다. 꼭 이렇게 해야 하는게 아니고 통상적인 관습이므로 반드시 따를 필요는 없습니다. 다만 다른 사람들도 함께 작업하는 프로젝트에서 통일성을 부여하기 위해서 이렇게 많이들 작성하게 됩니다. 위의 예제에서 Target all은 실제로 all이라는 파일을 생성하는것이 아니고 단지 무엇이 최종 Target이다 라는 암시적인 가짜 Target이 되며 clean은 무엇을 깨끗이 정리하겠다 라는 암시적인 가짜 Target이 됩니다. 이제 우리는 make test대신에 make all을 사용하게 될수 있습니다. 이때 all의 Depend로 test가 빌드될것입니다. 또한 clean은 관련된 파일을 정리하는것으로 용도가 정해집니다. 이때 .으로 시작하는 Target을 제외하고 가장 처음 나오는 Target은 make lt;targetgt; 에서 lt;targetgt;을 생략해도 무관하게 됩니다. 때문에 .PHONY를 제외한 all이 가장 처음 나오는 Target이고 이제부터는 make all이 아니고 그냥 make만 입력해도 된다는 겁니다. br / br / 1.7 응용 br / 이제 다음과 같이 4개의 파일을 작성하여 하나의 프로젝트를 작성하였다고 합시다. br / br / hello.c br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code#include lt;stdio.hgt; br / void HelloWorld(void) br / { br / fprintf(stdout, Hello world.\n); br / }/td /tr/tbody/tablespan class=postbody br / br / test.c br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code#include lt;stdio.hgt; br / #include hello.h br / int main(void) br / { br / HelloWorld(); br / return(0); br / }/td /tr/tbody/tablespan class=postbody br / br / hello.h br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeextern void HelloWorld(void);/td /tr/tbody/tablespan class=postbody br / br / Makefile br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / RM = rm -f br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -v -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / BUILD = test br / OBJS = test.o hello.o br / br / .PHONY: all clean br / br / all: $(BUILD) br / clean: ; $(RM) *.o $(BUILD) br / test: $(OBJS) ; $(LD) $(LDFLAGS) -o $@ $(STARTUP) $^ br / br / # 의존관계 성립 br / hello.o: $($@:.o=.c) $($@:.o=.h) Makefile br / test.o: $($@:.o=.c) hello.h Makefile br / br / # 확장자 규칙 (컴파일 공통 규칙) br / .c.o: ; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br /자! 이제 이 4개의 파일로 어떤 임의의 프로젝트를 만들었습니다. 엇? 근데 조금 이상한 부분이 보이죠? 하지만 이것은 매우 잘 동작하는 Makefile입니다. 이제 make clean 후에 make 명령을 입력하면 조용히 컴파일을 하게 될겁니다. 그리고 make 가 어떤 확장을 보이는지 궁굼하다면 make -p 명령을 통해서 -p옵션을 사용할수 있습니다. 꽤 많은 메세지를 확인할수 있을겁니다. 앞으로도 -p를 이용하면 make 가 어떤 확장을 보이는지 확인가능하니 낚시하는 법을 배운셈입니다. br / br /위에서 $($@:.o=.c) 라는 이상한 문자열이 좀 마음에 안들겁니다. 하지만 이것은 매우 함축적인 매크로이며 많이들 애용하고 있는 겁니다. 대략 다음과 같은 형식을 사용합니다. $(lt;문자열gt;:lt;우측으로부터 매칭될 문자열gt;=lt;치환될 문자열gt;) 이것은 즉, $@ 부분은 자신의 Target인 hello.o 또는 test.o를 말합니다. 그리고 거기서 우측으로부터 .o가 발견되면 .c로 치환하라는 뜻입니다. 즉, $(hello.o:.o=.c) 또는 $(test.o:.o=.c)로 확장되고 여기서 다시 각각 hello.c 와 test.c로 치환되어 결국 해당 소스를 지칭하게 되는 셈입니다. br / br /그리고 Command 부분이 lt;TABgt;이 쓰이지 않고 한줄에 ;(세미콜론)으로 분리되어서 해당 라인에 직접 Command 가 쓰이는 것을 확인하실수 있을겁니다. 무지 거대한 Makefile을 간략히 보이게 하기 위해서 이렇게도 사용할수 있다는 것을 예로 보인것입니다. br / br /의존관계를 성립하는 부분은 Command 가 없는것을 볼수 있는데 이것은 비슷한 다른 Target에서 Command 가 결합되어 수행될수 있고 여기서는 .c.o: ; ... 부분의 Command 가 결합됩니다. 여기서 의존관계를 최대한 자세하게 기술하였는데 만약 hello.h 가 변경된다면 hello.o와 test.o는 다시 빌드될것입니다. 또한 Makefile 도 수정되면 다시 빌드될것이라는 것이 예상됩니다. 이처럼 의존관계를 따로 기술하는 이유는 차후에 여러분들이 사용하시다보면 이유를 알게 될겁니다. 의존관계라는게 서로 굉장히 유기적으로 걸리는 경우가 많기 때문에 보다 보기 편하게 하는 이유도 있고 차후에 의존관계가 변경되었을때 쉽게 찾아서 변경을 할수 있도록 하는것도 한가지 이유입니다. br / br / 아주 조금만 공통적인 의존관계를 정리해서 작성한다면 다음과 같이도 작성할수 있습니다. 바로 Target이 한번에 2개 이상이 정의될수도 있다는 겁니다. br / br / br / /spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=codeCC = cc br / LD = ld br / RM = rm -f br / CFLAGS = -O2 -Wall -Werror -fomit-frame-pointer -v -c br / LDFLAGS = -lc -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 br / STARTUP = /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o br / br / BUILD = test br / OBJS = test.o hello.o br / br / .PHONY: all clean br / br / all: $(BUILD) br / clean: ; $(RM) *.o $(BUILD) br / test: $(OBJS) ; $(LD) $(LDFLAGS) -o $@ $(STARTUP) $^ br / br / # 의존관계 성립 br / $(OBJS): $($@:.o=.c) hello.h Makefile br / # test.o hello.o: $($@:.o=.c) hello.h Makefile br / br / # 확장자 규칙 (컴파일 공통 규칙) br / .c.o: ; $(CC) $(CFLAGS) -o $@ $lt;/td /tr/tbody/tablespan class=postbody br / br / 1.8 마지막으로 br /조금씩 make문법을 익힐때마다 왠지 암호화 같은 냄새가 나지만 결국 나중에 사용하다 보면 굉장히 유용합니다. 일단 주의할것은 되도록이면 Depend 는 최대한 자세히 걸어주면 좋다는 점을 강조하면서 이만 마치겠습니다. 비록 이 문서는 모든 make문법을 다루지는 못하였지만 매우 기본적인 make의 기능을 익히는데 목적을 가지고 작성하였고 사실상 훨씬 많은 기능이 있다는 점을 꼭 염두해두시고 연구해보세요./span
크리에이티브 커먼즈 라이센스
Creative Commons License

태그 : ,
트랙백0 | 댓글0
이 글의 관련글(트랙백) 주소 :: http://blog.minzkn.com/trackback/271

이름 :
비밀번호 :
홈페이지 :
  비밀글로 등록
내용 :
 



[PREV] [1] ... [302][303][304][305][306][307][308][309][310] ... [421] [NEXT]
위치로그 : 태그 : 방명록 : 관리자 : rss
장인정신’s Blog is powered by Tattertools.com / Designed by Lefttoe.Net
네. 이제 결혼했습니다.
  06/27 - 장인정신
네. 거기 맞아요. 그때 만나...
  06/27 - 장인정신
결혼하시나봐요~ 축하드립니다~
  06/25 - MasterQ
저희집 바로 옆으로 지나가셨...
  06/25 - MasterQ
아우~ 정말 소중한 자료 감사...
  03/09 - 착한청년
신기전
Savvy의 블로그
network+is+unreachable-으로...
blogring.org
서버의 Local IP 가져오기, 단상
엘레노아의 작업로그

Creative Commons License

이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.