2.4. GCC를 사용하여 라이브러리 생성
라이브러리를 생성하는 단계와 Linux 운영 체제에서 라이브러리에 사용하는 필수 개념에 대해 알아봅니다. 또한 라이브러리에 사용되는 특수 파일 이름 규칙을 알아야 합니다. 2.3.1절. “라이브러리 이름 지정 규칙”을 참조하십시오.
2.4.1. soname 메커니즘 링크 복사링크가 클립보드에 복사되었습니다!
동적으로 로드된 라이브러리(공유 오브젝트)는 soname 이라는 메커니즘을 사용하여 여러 호환 가능한 라이브러리 버전을 관리합니다. 이 개념을 이해하려면 다음을 수행하십시오.
- 동적 연결 및 라이브러리를 이해해야 합니다.
- ABI 호환성의 개념을 이해해야 합니다.
- 라이브러리 이름 지정 규칙을 이해해야 합니다.
심볼릭 링크를 이해해야 합니다.
- 문제 도입
- 동적으로 로드된 라이브러리(공유 오브젝트)는 독립적인 실행 파일로 존재합니다. 이렇게 하면 종속된 애플리케이션을 업데이트하지 않고 라이브러리를 업데이트할 수 있습니다. 그러나 이 개념에서는 다음과 같은 문제가 발생합니다.
- 라이브러리의 실제 버전 확인
- 동일한 라이브러리의 여러 버전이 필요
여러 버전의 각 ABI 호환성
- soname 메커니즘
- 이를 해결하기 위해 Linux는 soname이라는 메커니즘을 사용합니다.
foo 라이브러리 버전 X.Y 는 버전 번호에서 동일한 X 값을 가진 다른 버전과 호환됩니다. 호환성을 유지하는 사소한 변경으로 인해 Y 수가 증가합니다. 주요 변경으로 인해 호환성이 증가하여 X 가 증가합니다.
실제 foo 라이브러리 버전 X.Y 는 libfoo.so.x.y 파일로 존재합니다. 라이브러리 파일 내부에서 soname은 libfoo.so.x 값으로 기록되어 호환성을 알립니다.
빌드 중에 링커는 라이브러리 파일을 가리키는 libfoo.so 라는 심볼릭 링크를 검색합니다. 이 이름의 심볼릭 링크가 있어야 실제 라이브러리 파일을 가리킵니다. 그런 다음 링커는 라이브러리 파일에서 soname을 읽고 애플리케이션 실행 파일에 기록합니다. 마지막으로 링커는 이름 또는 파일 이름이 아닌 soname을 사용하여 라이브러리에 대한 종속성을 선언하는 애플리케이션을 생성합니다.
런타임 동적 링커가 실행하기 전에 애플리케이션을 연결하면 애플리케이션의 실행 파일에서 soname을 읽습니다. 이 soname은 libfoo.so.x 입니다. 이 이름의 심볼릭 링크가 있어야 실제 라이브러리 파일을 가리킵니다. 이렇게 하면 soname이 변경되지 않기 때문에 버전의 Y 구성 요소와 관계없이 라이브러리를 로드할 수 있습니다.
버전 번호의 Y 구성 요소는 단일 수에만 국한되지 않습니다. 또한 일부 라이브러리는 해당 버전을 이름으로 인코딩합니다.
- 파일에서 soname 읽기
라이브러리 파일의 이름을 표시하려면
some Cryostat:$ objdump -p somelibrary | grep SONAME
일부 Cryostat 를 검사하려는 라이브러리의 실제 파일 이름으로 교체합니다.
- 파일 이름에서 라이브러리 이름 및 버전 찾기
예를 들어
libevent-2.0.so.5.1.9파일로 존재하는 라이브러리를 고려해 보십시오. 실제 구성 요소를 찾으려면 다음을 수행합니다.-
먼저 표준 라이브러리 파일 이름 접두사
lib를 무시하고 시작합니다. -
나머지 부분을 앞의 두 부분으로 나누고
.so.문자열 뒤에 나머지 부분을 나눕니다. -
첫 번째 부분은 라이브러리의 이름인
event-2.0입니다. -
두 번째 부분은
5.1.9입니다. X 버전 구성 요소를 찾으려면 첫 번째 점:5이전의 모든 것을 가져 가십시오. -
나머지 요소는 Y 버전 구성 요소
1.9입니다.
-
먼저 표준 라이브러리 파일 이름 접두사
따라서 라이브러리의 이름은 event-2.0 이고 X 버전 구성 요소는 5이고 Y 는 1.9입니다.
이 라이브러리 파일의 이름은 모든 Y 구성 요소인 libevent-2.0.so.5 까지입니다.
최신 버전이지만 호환되는 라이브러리 버전이 릴리스되면 동일한 soname을 사용하고 Y 버전 구성 요소가 증가합니다. 새 파일 이름은 libevent-2.0.so.5.1.10 입니다.
2.4.2. GCC를 사용하여 동적 라이브러리 생성 링크 복사링크가 클립보드에 복사되었습니다!
동적으로 연결된 라이브러리(공유 오브젝트)를 사용하면 다음을 수행할 수 있습니다.
- 코드 재사용을 통한 리소스 보존
- 라이브러리 코드를 쉽게 업데이트하여 보안 향상
다음 단계에 따라 소스에서 동적 라이브러리를 빌드하고 설치합니다.
사전 요구 사항
- soname 메커니즘을 이해해야 합니다.
- GCC는 시스템에 설치되어 있어야 합니다.
- 라이브러리의 소스 코드가 있어야 합니다.
프로세스
- 라이브러리 소스가 있는 디렉터리로 변경합니다.
독립적인 코드 옵션
-fPIC을 사용하여 각 소스 파일을 오브젝트 파일로 컴파일합니다.$ gcc ... -c -fPIC some_file.c ...오브젝트 파일의 이름은 원래 소스 코드 파일과 동일하지만 확장자는
.o입니다.오브젝트 파일에서 공유 라이브러리를 연결합니다.
$ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.x some_file.o ...사용되는 주요 버전 번호는 X 및 마이너 버전 번호 Y입니다.
libfoo.so.x.y파일을 시스템의 동적 링커가 찾을 수 있는 적절한 위치에 복사합니다. Red Hat Enterprise Linux에서 라이브러리용 디렉터리는/usr/lib64입니다.# cp libfoo.so.x.y /usr/lib64이 디렉터리의 파일을 조작하려면 root 권한이 필요합니다.
soname에 대한 심볼릭 링크를 생성합니다.
# ln -s libfoo.so.x.y libfoo.so.x링커 이름에 대한 심볼릭 링크를 생성합니다.
# ln -s libfoo.so.x libfoo.so
추가 리소스
2.4.3. GCC 및 ar를 사용하여 정적 라이브러리 생성 링크 복사링크가 클립보드에 복사되었습니다!
오브젝트 파일을 특별한 유형의 아카이브 파일로 변환하면 정적 연결을 위한 라이브러리를 생성할 수 있습니다.
Red Hat은 보안상의 이유로 정적 링크를 사용하지 않습니다. 특히 Red Hat이 제공하는 라이브러리와 관련하여 필요할 때만 정적 링크를 사용하십시오. 자세한 내용은 정적 및 동적 연결을 참조하십시오.
사전 요구 사항
- GCC 및 binutils가 시스템에 설치되어 있어야 합니다.
- 정적 및 동적 연결을 이해해야 합니다.
- 라이브러리로 공유할 함수가 있는 소스 파일을 사용할 수 있습니다.
프로세스
GCC를 사용하여 중간 오브젝트 파일을 생성합니다.
$ gcc -c source_file.c ...필요한 경우 소스 파일을 더 추가합니다. 결과 오브젝트 파일은 파일 이름을 공유하지만
.o파일 이름 확장자를 사용합니다.binutils패키지의ar툴을 사용하여 오브젝트 파일을 정적 라이브러리(archive)로 전환합니다.$ ar rcs libfoo.a source_file.o ...libfoo.a파일이 생성됩니다.nm명령을 사용하여 결과 아카이브를 검사합니다.$ nm libfoo.a- 정적 라이브러리 파일을 적절한 디렉터리에 복사합니다.
라이브러리에 대해 연결할 때 GCC는 라이브러리가 정적 연결을 위한 아카이브인
.a파일 이름 확장에서 자동으로 인식합니다.$ gcc ... -lfoo ...