반응형
외부 파일에 함수를 만들어 놓고 별도 컴파일 한 후에 최종 실행 파일을 만들 때 이것을 같이 묶어서 컴파일 하는 것을 C 프로젝트에서 많이 사용하게 된다. 이 기초적인 작업의 샘플을 여기에 쉽게 써 보겠다.
두개의 파일을 작성한다. 하나는 func.c 이고 또 하나는 call.c 이다. func.c 에는 함수만 들어 있고 call.c 에는 main함수가 들어 있어 실행이 가능하게 된다.
먼저 func.c 를 다음과 같이 작성했다.
#include <stdio.h>
long func_a();
long func_a() {
printf("here is func_a!\n");
return 0;
}
함수 이름 앞에는 return type 으로 long 을 지정 했다. 만일 static long func_a() 라고 선언하게 되면 외부에서 이 함수를 호출 할 수 없게 되므로 주의한다.
[cbs]cc func.c
[cbs]ls -al func*
-rw-rw-rw- 1 csh cbsdev 85 9월 19일 16:22 func.c
-rw-rw-rw- 1 csh cbsdev 1071 9월 19일 16:24 func.o
[cbs]
컴파일이 제대로 잘 되었으면 func.o 라는 바이너리 파일이 생성되었을 것이다.
다음에 이 함수를 호출하는 call.c 를 다음과 같이 작성하였다.
#include <stdio.h>
extern long func_a(); /* 외부파일에 있는 함수라는 뜻으로 extern을 붙임 */
main() {
func_a(); /* 이 func_a 라는 함수는 외부파일인 func.c 속에 있음 */
printf("here is main!!\n");
};
이 call.c 를 컴파일 한다. 실제적으로 컴파일은 두번에 걸쳐서 실행된다. call.c 를 컴파일 하여 call.o 를 만드는 1차 컴파일과 call.o 와 func.o 를 묶어서 실제 실행되는 실행파일을 만드는 2차 컴파일이 필요하다.
[cbs]cc call.c
[cbs]ls -al call*
-rw-rw-rw- 1 csh cbsdev 111 9월 19일 16:28 call.c
-rw-rw-rw- 1 csh cbsdev 1115 9월 19일 16:31 call.o
[cbs]
1차 컴파일할 때 비록 func_a() 라는 함수가 call.c 파일 속에 작성이 되어 있지 않지만 프로그램 시작머리에 extern long func_a(); 라고 기술해 놓았기 때문에 컴파일러는 알아서 외부 어딘가에 있다고 믿고 오류 없이 컴파일을 통과시켜 주게 된다.
call.o 가 만들어 진 것을 확인하고 다시 2차 컴파일을 다음과 같이 한다.
[cbs]cc -o call call.o func.o
[cbs]ll call*
-rw-rw-rw- 1 csh cbsdev 111 9월 19일 16:28 call.c
-rw-rw-rw- 1 csh cbsdev 1115 9월 19일 16:31 call.o
-rwxrwxrwx 1 csh cbsdev 5331 9월 19일 16:32 call
[cbs]
call 의 속성이 rwxrwxrwx 로 생성되었고 실행이 가능하다. 실제로 실행을 해 보면 다음과 같은 결과를 얻을 수 있다. 2차 컴파일에서 cc 다음에 있는 -o 옵션은 생성될 실행 파일의 이름을 지정하는 것이다. 이것을 생략하면 a.out이라는 이름으로 실행파일이 생성된다. 그 뒤에 link 할 object 파일들을 주욱 나열해 주면 같이 실행파일에 묶여진다.
[cbs]call
here is func_a!
here is main!!
[cbs]
즉 func.c 속의 func 함수를 먼저 호출하고 main 함수 속에 있는 printf 문이 수행되었음을 최종 확인할 수 있겠죠..
그럼 깍두기로 다음과 같이 해 보자. 컴파일 할 때 일일이 하지 않고 뒤에 .c 파일을 주욱 나열해 주면 한꺼번에 컴파일을 하고 link 까지 해 주게 된다. 편하실 대로 하세요.
[cbs]cc -o call call.c func.c
call.c:
func.c:
[cbs]call
here is func_a!
here is main!!
[cbs]
call.c:
func.c:
[cbs]call
here is func_a!
here is main!!
[cbs]
프로그램 동작은 동일하게 하는군요.
그리고 만약에 func.c 나 call.c 에 func_a 라는 함수가 없을 경우에는 0711-317 ERROR: Undefined symbol 오류를 컴파일할 때 만나게 된다. 대부분의 경우 함수이름을 대소문자를 잘못 쓰거나 해서 언뜻보기에 비슷하지만 잘못 쓰는 경우가 흔히 있다. 특히 알파벳 엘(l) 자를 숫자 일(1)로 잘못 쓰거나 대문자 아이(I) 와 소문자 엘(l) 을 잘못 쓰거나 하면 위의 에러를 흔히 만나게 된다.
여하튼 이렇게 cc 컴파일 할 때 옵션도 많아지고 링크해야할 바이너리도 점점 많아지면 일일 컴파일 명령을 다 기억하기 어렵게 된다. 이러한 컴파일 명령 스트링을 자동으로 만들어주는 파일이 make 파일인 것이다.
반응형
'컴퓨터활용 > 유닉스' 카테고리의 다른 글
shell 에서 SQL을 수행하는 예제 (0) | 2008.10.11 |
---|---|
정적 라이브러리, 공유 라이브러리, 동적 적재 라이브러리 (0) | 2008.10.01 |
strcpy 의 위험성 (0) | 2008.09.11 |
전각 문자를 반각 문자로 변환하는 C 프로그램 (0) | 2008.07.14 |
대소문자로 변환 쉘 (1) | 2008.07.02 |