C++ - [펌] Linux에서 동적 라이브러리 만들기
출처: [리눅스 공유라이브러리(동적 라이브러리) 만들어 쓰기 | 작성자 라온이아부지 선성태](http://blog.naver.com/r2adne/120127832516) |
순서
- 라이브러리로 쓸 함수가 포함된 소스 두 개 작성
- 공용으로 각각 컴파일
- 두개의 오브젝트를 하나의 라이브러리로 통합
- 링크파일 생성
- 라이브러리 등록
- 라이브러리의 함수를 사용 하는 프로그램 소스 작성
- 라이브러리를 사용하도록 컴파일
- 실행
라이브러리로 쓸 함수가 포함된 두개의 소스 작성
// file1.c
#include <stdio.h>
int add(int a, int b)
{
int result=0;
printf("add : %d + %d = ",a,b);
return a+b;
}
int sub(int a, int b)
{
printf("sub : %d - %d = ",a,b);
return a-b;
}
//file2.c
#include <stdio.h>
void test3()
{
printf(" test 3 \n");
}
두 파일 컴파일
#gcc -fPIC -c file1.c file2.c
-fPIC 옵션 은 위치 독립적인코드를 생성 하는 옵션이다. - fpic (소문자) 는 플랫폼에 제약이 생기지만 빠르고 가볍다. - fPIC (대문자) 는 플랫폼에 제약이 없지만 무겁고 느리다. - 대부분 이걸 사용 한다.
- c 옵션: 오브젝트 파일을 생성 한다.
결과물 : file1.o file2.o
두개의 오브젝트를 하나의 라이브러리로 통합
#gcc -shared -Wl,-soname,libmy.so.0 -o libmy.so.0.0.0 file1.o file2.o
- shared 는 공유 라이브러리를 사용해서 링크 하라는 옵션이다.
- Wl 는 뒤에 오는 옵션들을 링커(collect2) 에게 gcc 를 거치지 않고 바로 전달 하라는 옵션이다.
- soname 은 실제 만들 라이브러리인 libmy.so.0.0.0 에 libmy.so.0 이라는 soname 을 생성하여 나중에 동적링크(/lib/ld-linux.so.2)가 공유 라이브러리를 찾을때 libmy.so.0.0.0 을 찾는게 아니라 soname 인 libmy.so.0 를 찾아 링크 하도록 한다. 버전 관리를 융통성 있게 하기 위함이며, 실제 gcc 가 링크 하는 파일명은 버전 정보가 없는 libmy.so 를 상요 하며, 이또한 libmy.so0.0.0 의 링크 파일로 만들어 사용 하는 것이다.
결과물 : libmy.so.0.0.0
링크 파일 생성
$ln -s libmy.so.0.0.0 libmy.so --> gcc 링크를 위한 파일 생성 $ln -s libmy.so.0.0.0 libmy.so.0 --> 동적 링크를 위한 파일 생성
결과물 libmy.so libmy.so.0 ( 둘다 링크 파일임)
라이브러리 등록
라이브러리를 등록 하는 방법은 여러가지가 있으나 가장 간단한 방법으로 한다.
원칙적으로 사용자가 만들어쓰는 라이브러리는 /usr/local/lib 에 넣어 쓰는 것을 권장 하지만, 현재 위치를 그냥 명시 하는 방법을 쓴다.
> #vi /etc/ld.so.conf include ld.so.conf.d/*.conf --> 리눅스 커널 2.6 에서 방식이 바껴서. 파일 위치를 명시하는 .conf 파일을 만들어 주면 자동으로 잡힘.. /mnt/samba/shared_lib_test --> 라이브러리 경로를 추가 하고 저장 한다..( 그러나, 이렇게 강제로 실제 경로를 넣어도 되더라.) /etc/ld.so.cache 파일 갱신 #ldconfig -> 실제 위치는 /sbin/ldconfig 이므로, 그냥 써서 안되면 /sbin/ldconfig 를 치면 된다.
라이브러리의 함수를 사용 하는 프로그램 소스 작성
//mylib.h 파일
int add(int,int);
int add(int,int);
void test3(void);
// test.c 파일
#include <stdio.h>
#include "mylib.h"
int main(void)
{
int result = 0;
result = add(5,6);
printf("%d\n",result);
result = 0;
result = sub(10,4);
printf("%d\n",result);
test3();
return 0;
}
라이브러리를 사용하도록 컴파일
#gcc -o test test.c -L./ -lmy
여기서 주의할 것은 -lmy 옵션이다… 이것 때문에 하루 죙일 삽질 했다.. -l 옵션 뒤에 바로 붙는 my 는 앞서 생성한 라이브러리 이름중 lib 를 제외한 나머지이다. 반드시 라이브러리는 libname 형태로 만들고, 이 옵션에서 -lname 형태로 써야만 컴파일이 된다.
만약 이 형태를 따르지 않고, 예를 들어 -ltest 라고 했다면.. 아래와 같은 에러를 볼것이다.
/usr/bin/ld: cannot find -ltest collect2: ld returned 1 exit status
결과물 : 실행 파일 test
실행 결과
#./test @localhost shared_lib_test]# ./test add : 5 + 6 = 11 sub : 10 - 4 = 6 test 3
이 글은 2019-04-20에 작성되었습니다.