일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- socket
- spring eureka
- jenkins pipeline
- SD카드
- 우분투
- MSA
- linux
- 스케줄러
- 포맷
- spring cloud eureka
- pthread_create()
- 네트워크
- i/o scheduling
- 소켓 프로그래밍
- position independent code
- 소켓
- eureka
- 스케줄링
- 젠킨스
- pthread_join()
- i/o schduler
- Spring cloud
- 라즈베리파이 에러
- 리눅스
- scheduler
- 라즈베리파이
- scheduling
- 젠킨스 파이프라인
- Jenkins
- OS
- Today
- Total
dayne의 블로그
리눅스 라이브러리 종류 및 설명 본문
목차
1. 라이브러리의 정의
2. 라이브러리의 종류
3. 라이브러리 예제
1. 라이브러리의 정의
라이브러리란 특정한 코드(함수 혹은 클래스)를 포함하고 있는 컴파일된 파일입니다.
라이브러리를 만드는 목적은 자주 사용되는 특정한 기능을 main 함수에서 분리시켜 놓음으로써, 프로그램의 유지 및 디버깅을 쉽게 하고, 코드 재사용성을 높이며, 컴파일 시간을 단축할 수 있기 때문입니다.
만일 라이브러리를 만들지 않고 모든 함수를 main에 구현한다면, 함수를 수정하고자 할 때마다 main 코드를 수정해야 하고 다시 컴파일해야 할 것입니다. (당연히 수정도 어렵고, 컴파일에도 많은 시간 소요)
라이브러리화를 사용하면, 해당 라이브러리만 다시 컴파일 시켜서 main 함수와 링크 시켜주면 되기 때문에 시간도 절약되고 수정도 간편해집니다.
/lib, /usr/lib, /usr/local/lib 등의 경로에 존재합니다.
2. 라이브러리의 종류
라이브러리는 사용 용도에 따라 여러가지 종류가 있습니다.
그 중에서, 대표적으로 사용되는 라이브러리는 '정적 라이브러리', '공유 라이브러리', '동적 라이브러리' 입니다.
위의 라이브러리들은 '링킹 시점'과 '사용 방식'에 따라 분류됩니다.
2.1 정적 라이브러리
정적 라이브러리는, 프로그램 빌드 시에 라이브러리가 제공하는 코드를 실행 파일에 넣는 방식의 라이브러리를 의미합니다.
컴파일 시에 링크됩니다.
object file(.o 확장자를 가지는)들의 단순한 모음이며, 리눅스에서는 .a 확장자를 가집니다.
특징
- 코드 포함 : 컴파일 시 프로그램의 실행 파일에 라이브러리 코드가 직접 포함됩니다.
- 독립성 : 실행 파일이 외부 라이브러리에 의존하지 않으므로, 배포 시 별도 라이브러리 파일이 필요 없습니다.
- 크기 증가 : 라이브러리 코드가 실행 파일에 포함되므로, 실행 파일의 크기가 커집니다.
- 유연성 저하 : 컴파일 시점에 링킹되기 때문에 유연성이 떨어집니다.
근래에는 정적 라이브러리 사용이 지양되는 추세인데, 그 이유는 아래와 같습니다.
예전에 'libz'라는 라이브러리에 보안 문제가 발생해 떠들석했던 일이 있었습니다.
libz는 각종 서버 프로그램에 매우 널리 사용되는 라이브러리였는데, libz를 사용하는 많은 프로그램들이 '정적 라이브러리' 형식으로 라이브러리를 사용했습니다.
정적 라이브러리 형식을 사용했기 때문에, 버그 픽스를 위해서는 문제가 되는 libz를 사용하는 프로그램들을 다시 컴파일 시켜야 했는고, 이렇게 버그 픽스 자체가 어려웠던 것이 큰 문제점이었습니다. (언제 그 많은 프로그램들을 다시 컴파일 하고 있냐는 문제..)
만약 libz 라이브러리를 '공유 라이브러리' 형태로 사용 중이었다면, libz 공유 라이브러리는 하나만 존재했을 것이고 이것만 수정시켜주면 되기 때문에 버그 픽스가 훨씬 쉬웠을 것입니다.
이렇게 '유연성 저하' 측면에서 정적 라이브러리 사용이 지양되는 추세입니다.
/usr/lib/arm-linux-gnueabihf 경로로 이동한 후, ls -al 명령어를 입력하면, 'libutil.a', 'libtripc.a' 등의 정적 라이브러리 파일들을 확인할 수 있습니다.
2.2 공유 라이브러리
공유 라이브러리는, 특정 라이브러리가 제공하는 기능을 다른 애플리케이션에서 사용하고 싶을 때, 라이브러리 코드를 메모리에 하나만 두고 각 애플리케이션에서 이를 공유하는 방식의 라이브러리를 의미합니다.
프로그램이 시작될 때 정적으로 로드되거나, 실행 중에 동적으로 로드될 수 있습니다.
정적으로 로드된 공유 라이브러리는 프로그램이 시작될 때 운영 체제에 의해 자동으로 로드되고, 프로그램이 종료될 때 자동으로 해제됩니다.
반대로, 동적으로 로드된 라이브러리는 개발자가 특정 시점에 명시적으로 로드하고, 사용이 끝나면 명시적으로 해제해야 합니다. → 동적 라이브러리
프로그램 시작 시에, 라이브러리 코드와 애플리케이션 코드 모두 메모리에 로드될 때 링크됩니다.
리눅스에서는 .so 확장자를 가집니다.
특징
- 공유 가능 : 여러 프로그램이 동일한 라이브러리를 메모리에 공유하여 사용하는 것이 가능하고, 이를 통해 메모리를 효율적으로 사용할 수 있습니다.
- 업데이트 용이성 : 라이브러리를 업데이트할 때, 라이브러리 파일만 교체하면 되므로 유지보수가 용이합니다.
- 종속성 : 실행 시 필요한 라이브러리가 시스템에 존재해야 하며, 해당 라이브러리가 없으면 프로그램 실행이 안될 수도 있습니다.
- 라이브러리의 내용이 실행 파일 내에 포함되지 않기 때문에, 실행 파일 배포 시에 반드시 라이브러리들을 함께 배포해야 합니니다.
리눅스 터미널에, cd /lib 입력 후 ls 명령어를 입력했을 때, 'libc.so', ' libm.so', 'libm.so'등의 파일이 공유 라이브러리입니다.
'ldconfig -p' 명령어를 입력하면, 시스템에 존재하는 모든 공유 라이브러리들의 이름, 공류 라이브러리의 경로와 해당 라이브러리를 사용하는 애플리케이션의 정보를 확인할 수 있습니다.
2.3 동적 라이브러리
동적 라이브러리는 공유 라이브러리를 사용하는 방식 중 하나로, 실행 파일에 포함되지 않고 프로그램이 실행 중에 필요에 따라 명시적으로 메모리에 로드하고 해제되는 라이브러리를 의미합니다.
공유 라이브러리를 그대로 사용하는데, 단지 프로그램 시작 시에 정적으로 로드되는 것이 아니라, 실행 중에 명시적으로 로드하고 해제하는 방식을 사용합니다.
실행 시점에 링킹됩니다.
리눅스에서 주로 .so 확장자를 가집니다.
특징
- 런타임 로딩 : 동적 라이브러리는 주로 프로그래머가 필요 시에 명시적으로 라이브러리를 로드하고 해제하는 방식입니다.
- 유연성 : 프로그램이 특정 기능을 필요로 할 때만 라이브러리를 로드할 수 있기 때문에, 초기 메모리 사용량을 줄일 수 있습니다.
- 공유 가능 : 여러 프로그램이 동일한 동적 라이브러리를 메모리에 공유하여 사용할 수 있습니다.
- 업데이트 용이성 : 라이브러리를 업데이트하거나 버그를 수정할 때, 라이브러리 파일만 교체하면 되므로 실행 파일을 다시 컴파일하거나 재배포할 필요가 없습니다.
- 종속성 관리 : 동적 라이브러리는 다른 라이브러리에 종속될 수도 있기 때문에, 종속성을 관리하는 것이 중요합니다.
- 라이브러리의 내용이 실행 파일 내에 포함되지 않기 때문에, 실행 파일 배포 시에 반드시 라이브러리들을 함께 배포해야 합니니다.
3. 라이브러리 예제
라이브러리화 할 코드는 아래와 같이 간단하게 덧셈과 뺄셈을 수행하는 코드입니다.
라이브러리의 이름은 libmy_calculator으로 정했습니다.
- my_calculator.h
int mySum(int a, int b);
int myDiff(int a, int b);
- my_calculator.c
#include "my_calculator.h"
int mySum(int a, int b) {
return a + b;
}
int myDiff(int a, int b) {
return a - b;
}
3.1 정적 라이브러리 예제
정적 라이브러리는 단순히 오브젝트의 모음이기 때문에, 오브젝트를 생성한 후 'ar'이라는 명령어를 사용해 라이브러리 아카이브를 만들면 됩니다.
sdh@raspberrypi:~$ gcc -c my_calculator.c
sdh@raspberrypi:~$ ar rc libmy_calculator.a my_calculator.o
- 우선 gcc를 사용해서 my_calculator.c을 컴파일하는데, 이때 옵션 '-c'를 주어서 오브젝트 파일(my_calculator.o)로 생성합니다.
- 그 다음 ar 명령어를 사용해서, my_calculator.o 오브젝트 파일을 포함하는 'libmy_calculator.a' 라는 이름의 정적 라이브러리 아카이브를 생성합니다.
- 이때, 옵션 r은 libmy_calculator.a 라이브러리 아카이브에 새로운 오브젝트 파일을 추가하는 역할입니다.
- 이때 옵션 c는 아카이브가 존재하지 않을 경우 생성하는 역할입니다.
이제 생성한 라이브러리가 실제로 사용 가능한지 확인해 보도록 하겠습니다.
- print_calculator.c
#include "my_calculator.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char left[10]; // 최대 10자리 숫자까지 받을 수 있는 배열 선언
char oper[1]
char right[10];
int result;
// 표준 입력(키보드)로 부터 '0~9 사이의 연속된 숫자', 연산자, 숫자를 입력받아서 left, oper, right에 넣어주기
fscanf(stdin, "%[0-9]%[^0-9]%[0-9]", left, oper, right);
if(oper[0] == '+'){
result = mySum(atoi(left), atoi(right));
}
if(oper[0] == '-'){
result = myDiff(atoi(left), atoi(right));
}
printf("%s %s %s = %d\n", left, oper, right, result);
return 0;
}
위의 프로그램을 컴파일하기 위해서는 '라이브러리의 위치' 와 '어떤 라이브러리를 사용할 것인지'를 명시해 줘야 합니다.
sdh@raspberrypi:~$ gcc -o print_calculator print_calculator.c -L./ -lmy_calculator
- '-L' 옵션을 사용해 '라이브러리의 위치'를 알려줄 수 있습니다.
- '-l' 옵션을 사용해 '어떤 라이브러리를 사용할 것인지'를 알려줄 수 있습니다.
- 이때 -l 옵션 뒤에 사용될 라이브러리 이름은, 라이브러리 이름에서 'lib'와 확장자 '.a'를 제외한 나머지 이름을 제시하면 됩니다. (libmy_calculator.a => my_calculator)
- 만약 사용할 라이브러리가 표준 라이브러리 디렉토리 경로에 명시되어 있을 경우, -L 옵션을 사용하지 않아도 됩니다.
- 표준 라이브러리 디렉토리 경로는 /etc/ld.so.conf 에 명시되어 있습니다.
정적라이브러리 상태로 컴파일한 프로그램의 경우 컴파일시에 라이브러리가 포함되므로 라이브러리를 함께 배포할 필요는 없습니다.
./print_calculator 명령어를 입력해 구현한 프로그램이 정상적으로 동작하는지 확인할 수 있습니다.
3.2 공유 라이브러리 예제
print_calculator.c 파일의 컴파일을 위해 사용되는 라이브러리의 형태가 정적 라이브러리에서 공유 라이브러리로 바뀌었다고 해서, print_calculator.c의 코드가 변경되는 것은 아닙니다.
컴파일 방법 또한 동일한데, '라이브러리 제작 방법'에만 차이가 있습니다.
my_calculator.c를 '.so' 확장자를 가지는 공유 라이브러리 형태로 만들어보겠습니다.
sdh@raspberrypi:~$ gcc -fPIC -c my_calculator.c
sdh@raspberrypi:~$ gcc -shared -Wl,-soname,libmy_calculator.so.1 -o libmy_calculator.so.1.0.1 my_calculator.o
sdh@raspberrypi:~$ sudo cp libmy_calculator.so.1.0.1 /usr/local/lib
sdh@raspberrypi:~$ ln -s /usr/local/lib/libmy_calculator.so.1.0.1 /usr/local/lib/libmy_calculator.so.1
- gcc -fPIC -c my_calculator.c
- -fPIC 옵션을 통해 PIC(Position Independent Code)로 컴파일하여 my_calculator.o 오브젝트 생성
- PIC란
- -fPIC 옵션을 통해 PIC(Position Independent Code)로 컴파일하여 my_calculator.o 오브젝트 생성
- gcc -shared -Wl,-soname,libmy_calculator.so.1 -o libmy_calculator.so.1.0.1 my_calculator.o
- 다시 gcc를 사용해서 공유 라이브러리 생성
- -shared 옵션
- 공유 라이브러리를 생성하겠다는 의미
- -Wl 옵션
- 해당 옵션 뒤에 오는 모든 옵션을 링커에게 전달하겠다는 의미
- -soname
- 라이브러리의 '소네임(soname)'을 지정
- 소네임은 동적 링크 시 라이브러리의 버전을 구별하기 위해 사용되며, 라이브러리의 주요 버전을 나타냄
- 위의 문장에 libmy_calculator.so.1로 설정되어 있으며, 다른 프로그램들은 이 이름으로 라이브러리를 참조
- -o libmy_calculator.so.1.0.1 my_calculator.o
- my_calculator.o 오브젝트 파일의 내용을 기반으로, 이름이 'libmy_calculator.so.1.0.1' 인 공유 라이브러리 파일 생성됨
- sudo cp libmy_calculator.so.1.0.1 /usr/local/lib
- 위의 명령어로 생성된 공유 라이브러리 파일 'libmy_calculator.so.1.0.1'을 /usr/local/lib 경로에 복사
- ln -s /usr/local/lib/libmy_calculator.so.1.0.1 /usr/local/lib/libmy_calculator.so.1
- ln 명령어에 -s 옵션(심볼릭 링크)을 이용해서, 컴파일러에서 인식할 수 있는 이름으로 심볼릭 링크를 생성.
컴파일하는 방식은 정적 라이브러리를 사용한 코드의 컴파일 방식과 동일합니다.
sdh@raspberrypi:~$ gcc -o print_calculator_shared print_calculator.c -L./ -lmy_calculator
공유 라이브러리는 실행 시에 라이브러리를 적재하기 때문에, 프로그램을 배포할 때는 공유 라이브러리도 함께 배포되어야 합니다.
그렇지 않을 경우, 아래와 같이 공유 라이브러리를 찾을 수 없다는 메시지를 출력하면서 프로그램 실행이 중단될 것입니다.
sdh@raspberrypi:~$ ./print_calculator_shared
./print_calculator: error while loading shared libraries: libmy_calculator.so.1: cannot open shared object file: No such file or directory
위와 같은 오류가 발생했다면, LD_LIBRARY_PATH에 라이브러리 패스가 지정되어 있지 않은 경우입니다.
이를 해결하기 위해, LD_LIBRARY_PATH 환경 변수에 libmy_calculator.so.1이 존재하는 디렉토리를 아래와 같이 명시해 줬습니다.
sdh@raspberrypi:~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
위와 같이 LD_LIBRARY_PATH 환경 변수에 libmy_calculator.so.1이 존재하는 디렉토리를 명시해 주면, ./print_calculator 명령어를 입력했을 때 프로그램이 성공적으로 실행됩니다.
- LD_LIBRARY_PATH
- 이 환경 변수는 런타임에 동적 라이브러리의 검색 경로를 지정합니다.
- 프로그램이 실행될 때, 해당 경로에 있는 라이브러리 파일을 찾을 수 있도록 해줍니다.
환경 변수에 명시 후에, sudo ldconfig 명령어를 입력하여 공유 라이브러리 캐시를 업데이트 하고, ldconfig -p 명령어를 입력해 현재 캐시에 저장된 디렉토리와 라이브러리 목록을 출력해 보면, libmy_calculator.so.1이 존재하는 것을 확인할 수 있습니다.
- ldconfig
- 시스템의 공유 라이브러리 캐시를 업데이트하는 명령어입니다.
- /etc/ld.so.conf 파일에 지정된 디렉토리와 LD_LIBRARY_PATH 환경 변수에 지정된 경로에 있는 라이브러리들을 검색하여 캐시를 만듭니다.
- -p 옵션과 함께 사용하면, 현재 시스템에서 사용 가능한 라이브러리 목록을 확인할 수 있습니다.
3.3 동적 라이브러리 예제
동적 라이브러리를 사용하고자 할 때, 일반 공유 라이브러리를 그대로 사용하며, 단지 실행 시간에 동적 라이브러리를 호출하기 위한 방법 상의 차이만 존재합니다.
정적/공유 라이브러리가 라이브러리의 생성 방법과 컴파일 방법에 약간의 차이만 있고 코드는 동일하게 사용되었던 것과는 달리 동적 라이브러리는 코드 자체에 차이가 있습니다. 동적 라이브러리는 프로그램 실행 중에, 특정한 시점에서 호출하는 순간에 라이브러리를 적재해야 하므로, 라이브러리를 로드, 사용, 해제하기 위한 코드를 생성해야 하기 때문입니다.
linux 에서는 이러한 라이브러리를 호출하기 위한 아래와 같은 함수들을 제공합니다.
#include <dlfcn.h>
void *dlopen (const char *filename, int flag);
const char *dlerror(void);
void *dlsym(void *handle, char *symbol);
int dlclose(void *handle);
- dlopen() 함수는 동적 라이브러리를 로드하기 위해서 사용되는 함수입니다.
- 첫 번째 매개변수인 filename 은 /usr/my/lib/libmy_calculator.so 와 같이 적재하기 원하는 라이브러리의 이름을 명시해 줍니다.
해당 라이브러리의 이름이 절대 경로로 지정되어 있지 않을 경우, LD_LIBRARY_PATH 환경 변수에 등록된 디렉토리에서 찾고, 여기에서도 찾지 못할 경우 /etc/ld.so.cache 에 등록된 디렉토리 리스트에서 찾게 됩니다. dlopen() 이 성공적으로 호출되면 해당 라이브러리에 대한 handle 값을 넘겨 줍니다. - flag 는 RTLD_LAZY와 RTLD_NOW 중 하나를 정의할 수 있습니다.
RTLD_LAZY는 라이브러리의 코드가 실행 시간에 정의되지 않은 심볼을 해결하며, RTLD_NOW 는 dlopen 의 실행이 끝나기 전에(return 전에) 라이브러리에 정의되지 않은 심볼을 해결합니다.
- 첫 번째 매개변수인 filename 은 /usr/my/lib/libmy_calculator.so 와 같이 적재하기 원하는 라이브러리의 이름을 명시해 줍니다.
- dlerror() 함수는 동적 라이브러리 관련 함수들이 제대로 동작하지 않았을 경우 에러 메시지를 반환합니다.
- dlsym() 함수는 dlopen() 을 통해 열린 라이브러리를 사용할 수 있도록 심볼(함수, 전역 변수)값을 찾아줍니다.
- handle 은 dlopen() 에 의해서 반환된 값입니다.
- dlsym 의 리턴값은 dlopen 으로 열린 라이브러리에서의 호출된 심볼을 가르키게 됩니다.
- dlclose() 함수는 동적 라이브러리의 handle을 해제하여 해당 라이브러리를 메모리에서 해제하는 역할을 합니다.
아래는 동적 라이브러리를 사용하는 print_calculator_dl.c을 생성하고, 해당 파일의 수정 없이 단지 설정 파일만 변경시켜 줌으로써 '곱하기'와 '나누기' 새로운 기능을 추가시키는 예제입니다.
1. 이전 예제에서 사용했던 print_calcualtor.c를 수정해서, 동적 라이브러리를 사용하는 'print_calculator_dl.c' 파일 생성 && 'plugin.cfg' 설정 파일 생성
<plugin.cfg>
+,mySum,libmy_calculator.so.1
-,myDiff,libmy_calculator.so.1
<print_calculator_dl.c>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
struct input_data
{
char oper[2];
char func[10];
char lib[30];
};
int main(int argc, char **argv)
{
char oper[2];
char left[11];
char right[11];
char buf[50];
char null[1];
int data_num;
struct input_data plug_num[10];
void *handle;
int (*result)(int, int); // 매개변수로 int, int를 받는 함수를 가리키는, 이름이 result인 변수 선언
int i;
char *error;
FILE *fp;
// 설정 파일을 읽어들이고 내용을 구조체에 저장
fp = fopen("plugin.cfg", "r");
data_num = 0;
while(fgets(buf, 50, fp) != NULL)
{
buf[strlen(buf) -1] = '\0';
sscanf(buf, "%[^,]%[,]%[^,]%[,]%[^,]", plug_num[data_num].oper, null, plug_num[data_num].func, null, plug_num[data_num].lib);
data_num++;
}
fclose(fp);
printf("> ");
memset(left, 0x00, 11);
memset(right, 0x00, 11);
fscanf(stdin, "%[0-9]%[^0-9]%[0-9]", left, oper, right);
// 연산자를 비교해서 적당한 라이브러리를 불러오기
for (i = 0; i < data_num ; i++)
{
int state;
if ((state = strcmp(plug_num[i].oper, oper)) == 0)
{
printf("my operator is : %s\n", plug_num[i].oper);
printf("my call function is : %s\n", plug_num[i].func);
break;
}
}
handle = dlopen(plug_num[i].lib, RTLD_NOW);
if (!handle)
{
printf("open error\n");
fputs(dlerror(), stderr);
exit(1);
}
// 해당 함수를 불러와서(dlsym), 실행
result = dlsym(handle, plug_num[i].func);
if ((error = dlerror()) != NULL)
{
fputs(error, stderr);
exit(1);
}
printf("%s %s %s = %d\n",left, oper, right, result(atoi(left), atoi(right)));
dlclose(handle);
}
2. 해당 파일 컴파일 (라이브러리 파일 위치는 /usr/local/lib 하위에 위치되어 있고, 환경 변수에 경로 등록되어 있다고 가정)
sdh@raspberrypi:~$ gcc -o print_calculator_dl print_calculator_dl.c -ldl
3. 새로운 곱하기와 나누기를 하는 새로운 'my_multi_div.h'와 'my_multi_div.c' 파일 생성
<my_multi_div.h>
int myMulti(int a, int b);
int myDiv(int a, int b);
<my_multi_div.c>
int myMulti(int a, int b)
{
return a * b;
}
int myDiv(int a, int b)
{
return a / b;
}
4. 과정 3에서 생성한 파일들을 사용해서 공유 라이브러리 생성 && /usr/local/lib 디렉토리로 카피
sdh@raspberrypi:~$ gcc -c -fPIC my_multi_div.c
sdh@raspberrypi:~$ gcc -shared -W1,-soname,libmy_multi_div.so.1 -o libmymulti.so.1.0.1 my_multi_div.o
sdh@raspberrypi:~$ sudo cp libmy_multi_div.so.1.0.1 /usr/local/lib
5. 기존 설정 파일 변경
+,mySum,libmy_calculator.so.1
-,myDiff,libmy_calculator.so.1
*,myMulti,libmy_multi_div.so.1.0.1
/,myDiv,libmy_multi_div.so.1.0.1
6. 실행시켜보면, printf_calculator_dl.c 파일을 변경하지 않고 plugin.cfg 설정 파일만 변경함으로써, 새로 생성한 동적 라이브러리를 가져와서 사용해 새로운 기능(*, /)이 실행되는 것을 확인할 수 있습니다.
참고
리눅스 라이브러리 생성(동적,정적)
https://www.joinc.co.kr/w/Site/C/Documents/Make_Library#AEN58 library 의 사용윤 상배yundream@coconut.co.kr 차례1절. 소개2절. Library 이야기2.1절. 라이브러리란 무엇인가2.2절. 라이브러리의 종류2.2.1절. 왜 정적라이브
enst.tistory.com
https://m.blog.naver.com/kr_dukie27/10175747579
정적 라이브러리와 동적 라이브러리(Static Library, Dynamic Library)
라이브러리에 의존하는 프로그램은 시스템에 필요한 라이브러리가 설치되지 않으면 동작하지 않는다. ...
blog.naver.com
https://www.joinc.co.kr/w/Site/C/Documents/Make_Library#AEN58
라이브러리 만들기
라이브러리 만들기nm을 이용하면 라이브러리(# nm libproc.aalloc.onmcompare.onmdevname.onmksym.onm
www.joinc.co.kr
'시스템 프로그래밍 > 리눅스' 카테고리의 다른 글
리눅스 디바이스 드라이버의 종류 및 확인 (0) | 2024.10.15 |
---|---|
리눅스 모듈 종류 및 모듈 적용 방법 (0) | 2024.10.14 |
리눅스 커널 컴파일 방법 (0) | 2024.10.11 |
리눅스 I/O 스케줄러 종류 및 동작 과정 (0) | 2024.10.10 |
리눅스 프로세스 스케줄링, 프로세스 스케줄러의 종류 및 동작 방식 (0) | 2024.10.10 |