아래와 같이 caculator라는 프로그램이 같은 디렉토리에 있는 lib내의 libcalcops라는 라이브러리를 사용할 수 있도록 만들어보도록 하겠습니다.

 

아주 간략하게 무슨 프로그램이냐를 설명해드리면, calculator라는 이 프로그램은 사용자로부터 두 수를 입력받아 덧셈, 뺄셈, 나눗셈의 결과를 출력해주는 프로그램입니다.

우리는 더 쉽게 calculator라는 프로그램을 구현하기 위해서(사실은 그냥 짜는게 더 쉽지만 라이브러리를 연동하는 방법을 알기 위해서) lib/libcalcops의 라이브러리를 가져다가 쓸겁니다. 물론 우리가 만들어 쓸거에요.

이 라이브러리에는 실제 연산 동작(calc operation)이 구현되어있습니다.

 

 

우선 현재 디렉토리에 mkdir lib를 이용해서 lib를 저장할 수 있는 디렉토리를 만들어줍시다.

 


# mkdir lib
# cd lib

 

라이브러리 소스코드 작성

너무나 간단한 연산 동작을 하는 함수를 정의한 헤더파일과 구현한 c파일을 작성하고 컴파일 해줍니다.

 

calc_operations.h

#ifndef __CALC_OPERATION_H_
#define __CALC_OPERATION_H_
int add(int a,int b);
int sub(int a,int b);
int mult(int a,int b);
double div(int a,int b);
#endif

 

calc_operations.c

#include "calc_operations.h"

int add(int a,int b){
    return a+b;
}

int sub(int a,int b){
    return a-b;
}

int mult(int a,int b){
    return a*b;
}

double div(int a,int b){
    return (double)a/(double)b;
}

 

여기까지는 뭐 누구나 아는 프로그램이지요. 아래와 같이 컴파일하게 되면 object파일이 하나 생성되겠죠.


# gcc -c calc_operations.c
# ls
calc_operations.c  calc_operations.h  calc_operations.o 

 

이제 이것을 ar로 rc옵션을 주어 정적라이브러리 아카이브를 만듭니다. 


# ar rc libcalcops.a calc_operations.o
# ls
calc_operations.c  calc_operations.h  calc_operations.o  libcalcops.a

 

프로그램 구현

이제 lib밖으로(cd ..) 이동해주세요. 여기서 소스 코드를 구현하도록 하겠습니다.

 

calculator.c

#include <stdio.h>
#include "lib/calc_operations.h"

int main(){
        int a,b;
        scanf("%d %d",&a,&b);

        printf("%d + %d = %d\n", a,b,add(a,b));
        printf("%d - %d = %d\n", a,b,sub(a,b));
        printf("%d * %d = %d\n", a,b,mult(a,b));
        printf("%d / %d = %f\n", a,b,div(a,b));

}

 

이제 아래와 같이 컴파일하도록 해봅시다. 아래 옵션 중에서 -L은 라이브러리가 위치한 디렉토리를 명시해주고 -lcalcops는 우리가 작성한 lib파일 이름입니다. 우리가 lib파일 이름을 libcalcops.a라고 정의하였을때 옵션은 -lcalcops라고 명시해주면 됩니다. lib가 -l로 바뀌고 확장자 .a를 빼주는 식이죠.


# gcc calculator.c -L ./lib -lcalcops
# ./a.out
7 3
7 + 3 = 10
7 - 3 = 4
7 * 3 = 21
7 / 3 = 2.333333

기존의 .o파일과 .a를 지우고 나서도 calculator 프로그램이 동작할까요? 지우고 실행을 다시 해보도록 합시다.


# rm -rf *.a *.o
# ls
calc_operations.c  calc_operations.h
# cd ..
# # ./calculator
10 3
10 + 3 = 13
10 - 3 = 7
10 * 3 = 30
10 / 3 = 3.333333

보시다시피 잘 동작하는 것을 알 수 있습니다. 추측해볼 수 있는 것은 런타임과는 관계가 없고 컴파일시(calculator)에 프로그램에 적재되는 것을 알 수 있고 실제로도 그렇습니다.

 

 

 

공유라이브러리

공유라이브러리는 컴파일 방식만 변경하면 됩니다. lib 디렉토리로 이동해주세요. 

아래의 명령으로 라이브러리를 컴파일해줍니다. 그런후에 /usr/lib 디렉토리에 복사해줍니다.


 # gcc -shared -o libcalcops.so calc_operations.c
 # cp libcalcops.so /usr/lib

 

이제 calculator 프로그램을 컴파일 할것인데, 위의 컴파일 옵션보다 더 간단합니다.


# gcc calculator.c -lcalcops
# ./a.out
8 3
8 + 3 = 11
8 - 3 = 5
8 * 3 = 24
8 / 3 = 2.666667

 

그렇다면 아까와 같이 /usr/lib/libcalcops.so파일을 삭제하고 위 프로그램을 다시 실행해보도록 해봅시다.


# ./a.out
./a.out: error while loading shared libraries: libcalcops.so: cannot open shared object file: No such file or directory

 

정적라이브러리와는 다르게 라이브러리 파일이 삭제되면 실행 프로그램도 실행되지 않네요. 우리가 추측해볼 수 있는것은 프로그램이 시작시에 적재되는 것을 의심해볼 수 있고 실제로도 그렇습니다.

 

왜 하필 /usr/lib에 파일을 복사했을까요? 공유라이브러리할때 /etc/ld.so.conf 설정파일로부터 라이브러리 파일이 있는 지 봅니다. 

제 시스템을 기준으로 설명드리면 아래와 같이 /etc/ld.so.conf 파일이 작성되어 있습니다.


include /etc/ld.so.conf.d/*.conf

 

다시 /etc/ld.so.conf.d/ 디렉토리를 보면 libc.conf와 x86_64-linux-gnu.conf 파일 두개가 존재합니다. 하기의 경로에 lib파일이 있으면 실행되며 추가적으로 경로를 추가 후 저장하고 나와서 ldconfig 명령을 주어 반영하면 됩니다.

libc.conf x86_64-linux-gnu.conf
# libc default configuration
/usr/local/lib
/usr/lib
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

 

 

 

 

반응형
블로그 이미지

REAKWON

와나진짜

,