아래와 같이 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 |
'컴퓨터 > 운영체제(주로 리눅스)' 카테고리의 다른 글
[리눅스] cmake에 대한 개념 설명과 CMakeLists.txt 작성법 (0) | 2021.02.24 |
---|---|
[운영체제/리눅스] 교착상태(deadlock)의 원인과 쓰레드를 통한 교착상태 발생 예제와 회피방법(pthread_mutex_timed_lock) (0) | 2020.12.31 |
[리눅스] 데몬 기초 : 개념과 구현 방법 (0) | 2020.12.19 |
[리눅스] 다중입출력 - select개념과 설명과 예제 (1) | 2020.11.26 |
[리눅스] 재지정, 리다이렉션(redirection: >, <)과 파이프(|) 개념과 쉬운 설명 (3) | 2020.07.09 |