안녕하세요.

오늘은 정적 라이브러리를 생성해 심볼 충돌을 방지하는 방법에 대하셔 간략하게 적어 보겠습니다. 

먼자 다음과 같이 3개의 .c 파일이 있다고 가정합니다.

#include <stdio.h>
void test(void)
{
printf("test() in a.c\n");
}

#include <stdio.h>
void test(void)
{
printf("test() in b.c\n");
}

void test(void);
int main(void)
{
test();
return 0;
}

정말 간단하죠?

아래와 같이 컴파일 후 정적 링크 합니다. 

$ gcc -c a.c
$ gcc -c b.c
$ gcc -c main.c
$ gcc -o main a.o b.o main.o

다음과 같이 실패 합니다.

b.o: In function `test':
b.c:(.text+0x0): multiple definition of `test'
a.o:a.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

어떻게 하면 이런 충돌을 방지할 수 있을까요?

다음과 같은 방법이 있습니다. 

ar을 이용하여 정적 라이브러리를 생성하면 심볼 충돌을 방지할 수 있습니다. 
이유는 링커와는 달리 오브젝트 파일로 아카이브를 생성하는 ar 명령은 심볼 충돌을 검사하지 않기 때문입니다.

$ gcc -c a.c
$ gcc -c b.c
$ gcc -c main.c
$ ar cr libtest.a a.o b.o
$ gcc -o main main.o libtest.a

$ ./main 
$ test() in a.c

생성된 실행파일 main은 a.c에 있는 test()를 생행하는 것을 알 수 있습니다. 

이는 링크할 때 libtest.a에 있는 두 함수 중 a.c의 함수를 먼저 찾았기 때문입니다.

그렇다면 정적라이브러리 libtest.a를 생성할 때 순서를 변경하면 어떻게 될까요?

실행해 봅니다.

rm *.o
rm libtest.a

$ gcc -c a.c
$ gcc -c b.c
$ gcc -c main.c
$ ar cr libtest.a b.o a.o 
$ gcc -o main main.o libtest.a

실행해 볼까요?
./main
test() in b.c

간단한 방법으로 심볼 충돌을 피해 갈 수 있습니다 ^^