'2007/01'에 해당되는 글 16건
- 2007/01/31
- 2007/01/31
- 2007/01/31
- 2007/01/30
- 2007/01/20
- 2007/01/17
- 2007/01/17
- 2007/01/17
- 2007/01/17
- 2007/01/17
- 2007/01/17
- 2007/01/17
- 2007/01/16
- 2007/01/16
- 2007/01/16
- 2007/01/12
In the network for an enterprise, a computer server acting as a gateway node is often also acting as a proxy server and a firewall server. A gateway is often associated with both a router, which knows where to direct a given packet of data that arrives at the gateway, and a switch, which furnishes the actual path in and out of the gateway for a given packet.
게이트웨이는 다른 네트웍으로 들어가는 입구 역할을 하는 네트웍 포인트이다. 라우팅의 관점에서 보면, 인터넷은 많은 게이트웨이 노드들과 호스트 노드들로 구성된 네트웍이라 할 수 있는데, 네트웍 사용자들의 컴퓨터들과 웹페이지와 같은 콘텐츠를 제공하는 컴퓨터들이 바로 호스트 노드들이며, 일반 회사의 네트웍 내에서 트래픽을 통제하는 컴퓨터들이나, 인터넷 서비스제공자들의 컴퓨터가 바로 게이트웨이 노드들이다.
한 회사의 네트웍에서는 게이트웨이 노드 역할을 하는 컴퓨터가 프럭시 서버나 방화벽 서버의 역할을 함께 수행하는 경우도 종종 있다. 게이트웨이는 라우터나 스위치 등의 사용을 필요로 한다.
(n.) (1) A node on a network that serves as an entrance to another network. In enterprises, the gateway is the computer that routes the traffic from a workstation to the outside network that is serving the Web pages. In homes, the gateway is the ISP that connects the user to the internet.
In enterprises, the gateway node often acts as a proxy server and a firewall. The gateway is also associated with both a router, which use headers and forwarding tables to determine where packets are sent, and a switch, which provides the actual path for the packet in and out of the gateway.
(2) A computer system located on earth that switches data signals and voice signals between satellites and terrestrial networks.
(3) An earlier term for router, though now obsolete in this sense as router is commonly used.
단일 LAN은 거리적으로 한정되지만 분산된 복수의 LAN을 연결하여 LAN의 집합 또는 대형망을 형성할 수 있다. 같거나 유사한 종류의 LAN은 브리지(bridge)를 사용하여 연결할 수 있고, 다른 종류의 LAN은 게이트웨이(gateway)를 사용하여 연결할 수 있다. LAN에 연결된 장치는 노드(node)라고 부르며, 노드들을 연결하는 케이블로는 연선(撚線) 케이블(twisted pair cable), 동축 케이블, 광케이블 등이 사용된다. LAN의 기본적인 망 구성 형태로는 버스형(bus), 고리형(ring), 방사형(star)의 3종류의 토폴러지가 사용된다.
2개 이상의 노드가 동시에 송신을 시도하는 경우에 충돌을 방지하고 트래픽을 조절하기 위한 매체 접근 제어에는 반송파 동시 공동 이용/충돌 탐지(CSMA/CD), 토큰 버스(token bus), 토큰 고리(token ring)의 3종류가 있다. LAN의 표준화 작업은 IEEE 802 위원회와 미국 표준 협회(ANSI) 산하 X3T 9.5 위원회를 중심으로 진행되고 있으며, 여기에서 제정된 표준이 ISO 8802 및 ISO 9314 계열의 국제 표준으로 채택되었다.
목차.
1. make ( 만든다? )
1.1 make 유틸리티.
1.2 make의 필요성.
2. 간단한 Makefile
2.1 Makefile의 내부구성.
2.2 Makefile 예제
2.3 매크로의 사용
2.4 레이블의 이용
3. 매크로( Macro ) 와 Suffix 규칙
3.1 매크로의 정의 ( What is macro )
3.2 미리 정해져 있는 매크로 ( Pre-defined macro )
3.3 확장자 규칙 ( Suffix rule )
3.4 내부 매크로 ( Internal macro )
4. Makefile 작성시에 알면 좋은 것들.
4.1 긴 명령어를 여러 라인으로 표시하기.
4.2 접미사 규칙의 이용 ( Use suffix rule !! )
4.3 매크로 치환 ( Macro substitution )
4.4 자동 의존관계 생성 ( Automatic dependency )
4.5 다중 타겟 ( Multiple target )
4.6 순환 make ( Recursive MAKE )
4.7 불필요한 재컴파일 막기.
5. make 중요 옵션 정리.
6. Makefile 작성의 가이드라인
7. Makefile 의 실제 예제.
7.1 프로그램 제작에 쓰일 수 는 Makefile
7.2 라이브러리의 제작에 쓰일 수 있는 Makefile
7.3 latex에서 쓰일 수 있는 Makefile
8. make 수행시에 나타나는 에러들
1. make (만든다?)
1.1 make 유틸리티.
영어사전에서 make란 뜻은 누구나 알듯이 '만들다'라는 뜻의 동사이다. 그럼 make 유틸리티는 왜 이름이 make인지 알 필요가 있을 것 같다. man으로 찾아보면 make에 대해 다음과 같이 설명하고 있다.
make - GNU make utility to maintain groups of programs
The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them.
우리말로 하면 make는 프로그램 그룹을 유지하는데 필요한 유틸리티이다. make 유틸리티의 목적은 프로그램 그룹 중에서 어느 부분이 새롭게 컴파일 되어야 하는지를 자동적으로 판단해서 필요한 커맨드(gcc 따위)를 이용해서 그들을 재컴파일 시킨다고 되어 있다.
make는 일련의 프로그램 개발에만 쓰이지 않고, 컴파일러처럼 일종의 명령어 방식으로 처리되는 모든 곳에서 쓰일 수가 있다. 가령 latex와 같은 경우도 .tex 파일에서 .dvi 파일을 만들고 다시 .ps 파일로 만드는 과정을 make를 사용해서 간단하게 만들 수가 있다.
--------------------------------------------------------------------
참고 - 쉽게 말하면 다음과 같은 경우에 make 를 쓰면 유리합니다.
1. 입력파일이 바뀌면 자동적으로 결과파일을 바꿔줬음 좋을 때. 기왕이면 좀 지능적으로 일을 수행하고 말입니다.
2. 위의 latex 파일처럼 자동적으로 프로그램이 수행이 되었으면 좋을 때.(batch의 개념이죠)
make는 위의 두 가지 개념을 모두 포함하고 있다고 봅니다. 보통 리눅스 프로그램에서 make all 하면 자세한 내막은 모르지만 자기가 알아서 다하죠.. 그 다음이 make install 이구요..
--------------------------------------------------------------------
GNU make는 보통 GNUmakefile, Makefile, makefile 중에서 하나가 있으면 그 파일을 읽게 된다. 하지만 일반적으로 Makefile을 추천을 하게 되는데 그 이유는 우선 GNUmake file은 기존의 make에서 인식을 못한다는 단점이 있고, makefile은 보통 소스파일에 묻혀서 잘 안보이게 되기 때문이다.
Makefile은 make가 이해할 수 있도록 일종의 쉘 스크립트 언어 같이 되어 있다.(makefile database라고도 한다) 이 파일에는 결과 파일을 생성시키기 위한 파일들 간의 관계, 명령어 등을 기술하고 있는데 이 강좌의 주된 목적이 바로 Makefile의 작성에 있다.
1.2 make의 필요성
우선은 make의 사용을 프로그램 개발과 유지쪽으로 국한시키기로 한다. 보통 라인수가 많아지면 여러 개의 파일로 나누어(모듈로 나누어) 개발을 하게 된다. 이들은 알게 모르게 서로 관계를 가지고 있는데, 어느 하나를 필요에 의해 바꾸게 되었을 때 그 파일에 있는 함수를 이용하는 다른 파일도 새롭게 컴파일 되어야 한다.
하지만 파일수가 많은 경우 이를 일일이 컴파일을 하게 될 때, 그 불편함과 함께 컴파일 하지 않아도 될 것도 컴파일을 하게 될 수도 있고, 컴파일 해야 할 것도 미처 못하게 되는 경우가 있다. (링크에러의 원인이 되기도 하는데 에러의 원인을 제대로 찾기가 힘이 든다.)
앞에서도 얘기했듯이 이런 상황에서 지능적으로 관계 있는 것만 새롭게 갱신을 할 필요가 있을 때 make 파일은 빛을 발하게 된다.
2. 간단한 Makefile
2.1 Makefile 의 내부구성
Makefile은 기본적으로 아래와 같이 목표(target), 의존관계(dependency), 명령(command)의 3개로 이루어진 기분적인 규칙(rule)들이 계속적으로 나열되어 있다고 봐도 무방하다. make가 지능적으로 파일을 갱신하는 것도 모두 이 간단한 규칙에 의하기 때문이다.
target ... : dependency ...
command
...
...
여기서 목표(target) 부분은 명령(command)이 수행이 되어서 나온 결과 파일을 지정한다. 당연히 목적파일(object file)이나 실행파일이 될 것이다.
명령(command)부분에 정의된 명령들은 의존관계(dependency)부분에 정의된 파일의 내용이 바뀌었거나, 목표부분에 해당하는 파일이 없을 때 이곳에 정의되 것들이 차례대로 실행이 된다. 일반적으로 쉘상에서 쓸 수 있는 모든 명령어들을 사용할 수가 있으며 bash에 기반하는 쉘 스크립트도 지원한다.
--------------------------------------------------------------------
참고 - 참고로 목표부분에는 결과파일만 올 수 있는 것이 아니고, 보통 make clean에서와 같이 간단한 레이블(label) 기능을 제공하기도 한다.
명령 부분은 꼭 TAB 글자로 시작해야 한다. 그냥 스페이스등을 사용하면 make 실행 중에 에러가 난다. 명심하세요. make가 명령어인지 아닌지를 TAB 가지고 구별하기 때문이죠
--------------------------------------------------------------------
2.2 Makefile 예제.
간단한 Makefile을 만들어 본다. 우리가 만들려고 하는 프로그램은 main.c read.c write.c 로 구성되어 있고 모두 io.h 라는 헤더파일을 사용한다고 가정한다. (구성을 간단화 시킵시다.) 이들을 각각 컴파일 해서 test라는 실행파일을 생성시킨다.
% gcc -c main.c
% gcc -c read.c
% gcc -c write.c
% gcc -o test main.o read.o write.o
위의 방식은 make를 쓰지 않고 그냥 명령어를 주는 방식이다. 파일의 수가 작아서 오히려 더 간단하게 보일 수 있으나, 파일이 100개 정도 된다고 가정하면 .... 아찔...
그리고 아래는 위와 똑같은 일을 수행하는 Makefile 의 내용이다.
[예제1]
|
test : main.o read.o write.o gcc -o test main.o read.o write.o main.o : io.h main.c gcc -c main.c read.o : io.h read.c gcc -c read.c write.o: io.h write.c gcc -c write.c |
(대충 알아보시겠어요? , 참 TAB 문자 쓰는거 있지 마세요)
make는 Makefile의 내용을 보고, 내부적으로 어떻게 파일들이 의존하고 있는지 조사한다. 위의 Makefile을 바탕으로 의존관계를 그림으로 나타내보면 아래와 같다.
위의 그림에서 보면 test가 만들어지기 위해서는 main.o read.o write.o가 필요하고, 각각의 목적 파일들은 모두 자신의 소스파일과 io.h에 의존함을 알 수가 있다. 가령 main.c를 고쳤다고 생각한다면 main.o가 컴파일 되서 다시 생기고, test도 다시 링크되어서 갱신된다. 만약 io.h가 바뀌었다고 가정하면 모든 파일들이 컴파일 되어서 목적파일이 생기고, 그것들이 링크가 되어 test가 생긴다. 위와 같이 파일들을 구성한 다음 Makefile을 실행시켜보자. Makefile의 실행은 그냥 make 라고 치면 된다.
% make
gcc -c main.c
gcc -c read.c
gcc -c write.c
gcc -o test main.o read.o write.o <-- OK
--------------------------------------------------------------------
참고 - 그냥 테스트기 때문에 read.c write.c io.h는 모두 내용 없이 파일만 만들어두기로 하고, main.c에 간단히 printf 함수만 적어봅시다. 정말 위와 같이 됨을 실감할 꺼에요.. 신기하게.
--------------------------------------------------------------------
2.3 매크로의 사용
간단한 메크로 기능을 사용해보자. main.o read.o write.o라는 것을 OBJECTS 라는 매크로로 바꾸는 것이 아래의 [예제2]에 나와있다.
[예제2]
|
OBJECTS = main.o read.o write.o test : $(OBJECTS) gcc -o $(OBJECTS) main.o : io.h main.c gcc -c main.c read.o : io.h read.c gcc -c read.c write.o: io.h write.c gcc -c write.c |
위에서 보다시피 매크로는 그냥 프로그램 짤 때와 같이 사용해서 값을 대입한다. 대신 사용할 때는 반드시 $(..) 안에 넣어서 사용한다. 매크로 치환을 위한 특수한 방법이 아닐까.. 히.. 매크로의 사용법은 위와 같이 간단하므로 다양하게 정의해서 사용할 수 있다. 매크로에 대한 자세한 설명은 다음 강좌에서 언급하기로 한다.
2.4 레이블의 사용
목표부분에 해당하는 부분이 그냥 레이블과 같이 사용될 수도 있다고 이미 설명하였다. [예제2]에다가 목적파일들을 모두 삭제하는 명령어를 추가하기로 한다.
[예제3]
|
OBJECTS = main.o read.o write.o test : $(OBJECTS) gcc -o $(OBJECTS) main.o : io.h main.c gcc -c main.c read.o : io.h read.c gcc -c read.c write.o: io.h write.c gcc -c write.c clean : rm $(OBECTS) |
레이블로 사용될 때는 당연히 의존관계 부분은 없어도 된다. 그리고 clean을 실행시키려면 아래와 같이 한다.
% make clean
rm main.o read.o write.o <-- OK
3. 매크로(Macro)와 Suffix 규칙
3.1 매크로의 정의(What is Macro)
앞 강좌에서 매크로에 대해서 대충 언급을 했다. 프로그램을 짜본 사람이나 로터스, 한글, 엑셀 등등의 모든 패키지에서 매크로라는 것을 사용하게 된다. 은연중에 매크로의 정의는 대충 짐작하고 있을 것이다. 이미 알고 있는 바와 같이 매크로는 특정한 코드를 간단화시켜 표현한 것에 지나지 않는다. Makefile에서 사용되는 매크로는 비교적 그 사용법이 간단하기 때문에 금방 익혀서 사용할 정도가 된다.
매크로의 정의는 프로그램을 작성할 때 변수를 지정하는 것처럼 하면 된다. 그리고 매크로를 사용하기 위해서는 $(..)을 이용하면 된다. 아래는 매크로의 간단한 예제이다.
--------------------------------------------------------------------
참고 - 매크로의 사용에서 ${..} $(..) $.. 를 모두 사용할수 있습니다. 그러나 대부분의 책에서는 $(..) 을 사용하라는 군요.
--------------------------------------------------------------------
[예제 4]
|
OBJS = main.o read.o write.o test : $(OBJS) <------(1) gcc -o test $(OBJS) .......... |
강좌 1에서 다루었던 예제와 거의 비슷하다. 매크로는 사실상 복잡한 것을 간단하게 표시한것에 지나지 않는다. (1)번을 매크로를 안 쓰고 표현한다면 아마 아래와 같이 될 것이다.
[예제 5]
|
test : main.o read.o write.o gcc -o test main.o read.o write.o |
--------------------------------------------------------------------
참고 - [예제 5]가 더 쉽지 않느냐고 반문하는 사람은 매크로의 위력을 잘 모르는 사람입니다. 거의 모든 소프트웨어에서 매크로를 지원하는 이유를 한번 잘 생각해봅시다. [예제 4]의 (1) 부분이 이해하기 난해하다고 하실지는 모르겠지만, 대충 형식이 정해져 있기 때문에 조금만 익숙해지면 오히려 더 편할 겁니다.
--------------------------------------------------------------------
make에 관해 설명한 책에 다음과 같은 명언(?)이 나온다.
Macro makes Makfile happy. (매크로는 Makefile을 기쁘게 만든다.)
이 말은 Makefile을 작성함에 있어 매크로를 잘만 이용하면 복잡한 작업도 아주 간단하게 작성할 수 있음을 말해주는 말이 아닐까 생각한다. 매크로에 대해서는 더 이상 말할 것이 없다.(너무 간단하죠?) 이제 남은 것은 여러분들이 자신의 매크로를 어떻게 구성하느냐 이 다. 어떤 것을 매크로로 정의해야 할지는 여러분들의 자유이며, 나중에 전반적인 지침을 설명할 것이다.
3.2 미리 정해져 있는 매크로 (Pre-defined macro)
여러분들보다 머리가 약간 더 좋은 사람들이 make라는 것을 만들면서 미리 정해놓은 매크로들이 있다. 'make -p' 라고 타이핑해보면 make에서 미리 세팅되어 있던 모든 값들(매크로, 환경변수(environment)등등)이 엄청 스크롤된다. 이 값들을 보고 미리 주눅이 들 필요는 없다. 어차피 대부분의 내용들은 우리가 재정의 해주어야 하기 때문에 결론적으로 말하면 우리가 모두 작성한다고 생각하는 것이 맘 편하다.
아래에는 대부분이 UNIX 계열의 make에서 미리 정해져 있는 매크로들 중 몇 가지만 나열해본 것이다.
[예제 6] Predefined Macro
|
ASFLAGS = <-- as 명령어의 옵션 세팅 AS = as CFLAGS = <-- gcc 의 옵션 세팅 CC = cc (= gcc ) CPPFLAGS = <-- g++ 의 옵션 CXX = g++ LDLFAGS = <-- ld 의 옵션 세팅 LD = ld LFLAGS = <-- lex 의 옵션 세팅 LEX = lex YFLAGS = <-- yacc 의 옵션 세팅 YACC = yacc MAKE_COMMAND = make |
--------------------------------------------------------------------
참고 - 직접 make -p를 해서 한번 확인해보세요. 과연 make는 내부적으로 어떤 변수들을 사용하고 있는지 알아봅시다. 매크로는 관습적으로 대문자로 작성되니까 이점에 유의해서 보세요. make는 쉘상에서 정의한 환경변수 값들을 그대로 이용한다는 것을 알고 계시기 바랍니다.
--------------------------------------------------------------------
위에 열거한 매크로는 make에서 정의된 매크로 중 그야말로 일부에 지나지 않는다. 하지만 프로그램을 작상함에 있어 가장 많이 사용하게 될 매크로 들이다. 이들 매크로는 사용자에 의해 재정의 가능하다. 가령 gcc의 옵션 중에 디버그 정보를 표시하는 '-g' 옵션을 넣고 싶다면, 아래와 같이 재정의 한다.
CFLAGS = -g
[예제 6]의 각종 FLAG 매크로들은 대부분 우리가 필요에 의해 세팅해 주어야 하는 값들이다. 왜 굳이 make에서 값도 정의되지 않은 매크로를 우리가 정의해서 써야 하는지 의문을 던질지도 모른다. 우리가 더 좋은 이름으로 매크로를 정의할 수도 있다고 하면서....
여기서 한가지 사실을 생각해봐야 할 것이다. make에서 위에 나온 것들을 왜 미리 정해두었을까?(왜일까요?) make에서 이들 매크로를 제공하고 있는 이유는 내부적으로 이들 매크로를 사용하게 되기 때문이다. 어떻게 이용하는지는 확장자 규칙(Surfix rule)을 설명하면서 해답을 제공할 것이다. 이제 [예제 4]의 Makefile을 매크로를 이용하여 깔끔하게(?) 작성해보자.
[예제 7]
|
OBJECTS = main.o read.o write.o SRCS = main.c read.c write.c <-- 없어도 됨 CC = gcc <-- gcc 로 세팅 CFLAGS = -g -c <-- gcc 의 옵션에 -g 추가 TARGET = test <--- 결과파일을 test 라고 지정 $(TARGET) : $(OBJECTS) $(CC) -o $(TARGET) $(OBJECTS) clean : rm -rf $(OBJECTS) $(TARGET) core main.o : io.h main.c <-- (1) read.o : io.h read.c write.o: io.h write.c |
위의 Makfile 을 동작시켜보자.
% make
gcc -g -c main.c -o main.o
gcc -g -c read.c -o read.o
gcc -g -c write.c -o write.o
gcc -o test main.o read.o write.o <- OK
% make clean
rm -rf main.o read.o write.o test core <- OK
그런데 여기서 한가지 이상한 점을 발견하게 될 것이다. .c 파일을 .o 파일로 바꾸는 부분이 없는데 어떻게 컴파일이 되었을까? 빼먹고 타이핑 못한 것은 아닐까하고 ... 절대아님 !
앞에서 CFLAGS 같은 매크로는 make 파일의 내부에서 이용된다고 하였다. 그렇다면 make 는 과연 어디에서 이용을 할까? 바로 컴파일하는 곳에서 이용을 하는 것이다. 따라서 우리는 CFLAGS를 세팅해주기만 하면 make가 알아서 컴파일을 수행하는 것이다.(얼마나 편리합니까.)
--------------------------------------------------------------------
참고 - 확장자 규칙에서 다시 한번 자세히 설명을 하겠습니다.
--------------------------------------------------------------------
(1)에 해당하는 부분은 어떤 파일이 어디에 의존하고 있는지를 표시해주기 위해서 꼭 필요하다. .c 파일을 컴파일하는 부분은 일괄적인 루틴으로 작성할 수 있기 때문에 이들 파일간의 의존관계(dependency)를 따로 표시해주어야 한다.
--------------------------------------------------------------------
참고 - 파일간의 의존관계를 자동으로 작성해주는 유틸리티가 있습니다. 이것은 다음 번 강좌에서 다루기로 합니다.
--------------------------------------------------------------------
3.3 확장자 규칙 (Suffix rule)
확장자 규칙이란 간단히 말해서 파일의 확장자를 보고, 그에 따라 적절한 연산을 수행시키는 규칙이라고 말할 수 있다. 가령 .c 파일은 일반적으로 C 소스코드를 가르키며, .o 파일은 목적파일(Object file)을 말하고있다. 그리고 당연히 .c 파일은 컴파일 되어서 .o 파일이 되어야 하는 것이다.
여기서 한가지 매크로가 등장하게 된다. .SUFFIXES 라고 하는 매크로인데 우리가 make 파일에게 주의 깊게 처리할 파일들의 확장자를 등록해 준다고 이해하면 될 것이다.
.SUFFIXES = .c .o
위의 표현은 .c 와 .o 확장자를 가진 파일들을 확장자 규칙에 의거해서 처리될 수 있도록 해준다. .SUFFIXES 매크로를 이용한 예제를 살펴보자.
[예제 8]
|
.SUFFIXES = .c .o OBJECTS = main.o read.o write.o SRCS < |