2.3. GCC에서 라이브러리 사용


코드에서 라이브러리 사용에 대해 알아봅니다.

2.3.1. 라이브러리 이름 지정 규칙

특수 파일 이름 규칙은 라이브러리에 사용됩니다. foo라는 라이브러리는 lib foo .so 또는 libfoo . a 파일로 존재할 것으로 예상됩니다. 이 규칙은 GCC의 입력 옵션을 연결하지만 출력 옵션에 의해 자동으로 이해되지 않습니다.

  • 라이브러리에 대해 연결할 때 -lfoo: -l 옵션을 사용하여 foo 라는 이름으로만 라이브러리를 지정할 수 있습니다.

    $ gcc ... -lfoo ...
  • 라이브러리를 생성할 때 전체 파일 이름 libfoo.so 또는 libfoo.a를 지정해야 합니다.

추가 리소스

2.3.2. 정적 및 동적 연결

개발자는 완전히 컴파일된 언어로 애플리케이션을 빌드할 때 정적 또는 동적 링크를 사용할 수 있습니다. 특히 Red Hat Enterprise Linux에서 C 및 C++ 언어 사용의 맥락에서 정적 연결과 동적 연결의 차이점을 이해하는 것이 중요합니다. 요약하면 Red Hat은 Red Hat Enterprise Linux용 애플리케이션에서 정적 링크를 사용하지 않는 것이 좋습니다.

정적 연결 및 동적 연결 비교
정적 링크를 사용하면 라이브러리가 결과 실행 파일의 일부가 됩니다. 동적 링크는 이러한 라이브러리를 별도의 파일로 유지합니다.

정적 연결에는 여러 가지 단점이 있으며 특히 전체 애플리케이션 및 glibclibstdc++ 라이브러리의 경우 피해야 합니다.

resource use: 정적 연결로 인해 더 큰 실행 파일이 더 많은 코드가 포함됩니다. 라이브러리에서 제공되는 이 추가 코드는 시스템의 여러 프로그램에서 공유할 수 없으므로 런타임 시 파일 시스템 사용량과 메모리 사용량을 늘릴 수 있습니다. 동일한 정적으로 연결된 프로그램을 실행하는 여러 프로세스가 여전히 코드를 공유합니다.

반면 정적 애플리케이션에는 더 적은 런타임 재배치가 필요하므로 시작 시간을 단축하고 개인 상주 설정 크기(RSS) 메모리가 줄어듭니다. 정적 연결을 위한 생성된 코드는 위치 독립 코드(PIC)에 의해 도입된 오버헤드로 인해 동적 연결을 위한 것보다 더 효율적일 수 있습니다.

보안: ABI 호환성을 제공하는 동적 링크 라이브러리는 이러한 라이브러리에 따라 실행 파일을 변경하지 않고도 업데이트할 수 있습니다. 이는 Red Hat이 보안 업데이트를 제공하는 Red Hat Enterprise Linux의 일부로 Red Hat에서 제공하는 라이브러리에서 특히 중요합니다. 이러한 라이브러리에 대한 정적 연결은 권장되지 않습니다.

호환성: 정적 연결은 운영 체제에서 제공하는 라이브러리 버전과 관계없이 실행 파일을 제공하는 것으로 보입니다. 그러나 대부분의 라이브러리는 다른 라이브러리에 의존합니다. 정적 연결을 사용하면 이 종속성은 유연성이 떨어지고 결과적으로 앞으로 및 이전 버전과의 호환성이 모두 손실됩니다. 정적 연결은 실행 파일이 빌드된 시스템에서만 작동하도록 보장됩니다.

주의

GNU C 라이브러리(glibc)의 정적 라이브러리를 연결하는 애플리케이션은 여전히 동적 라이브러리로 시스템에 glibc 가 있어야 합니다. 또한 애플리케이션 실행 시 사용 가능한 glibc 의 동적 라이브러리 변형은 애플리케이션을 연결하는 동안 존재하는 것과 약간 동일한 버전이어야 합니다. 결과적으로 정적 연결은 실행 파일이 빌드된 시스템에서만 작동하도록 보장됩니다.

지원 범위: Red Hat에서 제공하는 대부분의 정적 라이브러리는 CodeReady Linux Builder 채널에 있으며 Red Hat에서 지원하지 않습니다.

기능: 일부 라이브러리, 특히 GNU C 라이브러리(glibc)는 정적으로 연결된 경우 기능 감소를 제공합니다.

예를 들어 정적으로 연결된 경우 glibc 는 동일한 프로그램에서 dlopen() 함수에 대한 스레드 및 모든 형태의 호출을 지원하지 않습니다.

정적 연결 사례

정적 연결은 다음과 같은 경우에 합리적인 선택일 수 있습니다.

  • 동적 연결에 사용할 수 없는 라이브러리를 사용하는 경우
  • chroot 환경 또는 컨테이너에서 코드를 실행하는 데 완전히 정적 링크가 필요한 경우입니다. 그러나 glibc-static 패키지를 사용한 정적 연결은 Red Hat에서 지원되지 않습니다.

2.3.4. GCC가 있는 라이브러리 사용

라이브러리는 프로그램에서 재사용할 수 있는 코드의 패키지입니다. C 또는 C++ 라이브러리는 다음 두 부분으로 구성됩니다.

  • 라이브러리 코드
  • 헤더 파일

    라이브러리를 사용하는 코드 컴파일
    헤더 파일은 라이브러리의 인터페이스, 즉 라이브러리에서 사용할 수 있는 함수 및 변수를 설명합니다. 헤더 파일의 정보는 코드를 컴파일하는 데 필요합니다.

일반적으로 라이브러리의 헤더 파일은 애플리케이션 코드와 다른 디렉터리에 배치됩니다. GCC 헤더 파일이 어디에 있는지 알려주려면 -I 옵션을 사용합니다.

$ gcc ... -Iinclude_path ...

include_path 를 헤더 파일 디렉터리의 실제 경로로 바꿉니다.

예를 들어 상대 경로를 지정하려면 some/interesting/directory:

$ gcc ... -Isome/interesting/directory ...

I 옵션을 여러 번 사용하여 헤더 파일이 있는 여러 디렉터리를 추가할 수 있습니다. 헤더 파일을 찾을 때 이러한 디렉터리는 -I 옵션에 표시되는 순서대로 검색됩니다.

라이브러리를 사용하는 코드 연결

실행 파일을 연결할 때 애플리케이션의 오브젝트 코드와 라이브러리의 바이너리 코드를 모두 사용할 수 있어야 합니다. 정적 및 동적 라이브러리의 코드는 다음과 같은 다양한 형태로 제공됩니다.

  • 정적 라이브러리는 아카이브 파일로 사용할 수 있습니다. 오브젝트 파일 그룹이 포함되어 있습니다. 아카이브 파일의 확장자는 .a 입니다.
  • 동적 라이브러리는 공유 오브젝트로 사용할 수 있습니다. 이는 일종의 실행 파일입니다. 공유 오브젝트에는 파일 이름 확장자 .so 가 있습니다.

GCC에 라이브러리의 아카이브 또는 공유 오브젝트 파일이 어디에 있는지 알려주려면 -L 옵션을 사용합니다.

$ gcc ... -Llibrary_path -lfoo ...

library_path 를 라이브러리 디렉터리의 실제 경로로 바꿉니다.

L 옵션을 여러 번 사용하여 여러 디렉터리를 추가할 수 있습니다. 라이브러리를 찾으면 이러한 디렉터리가 -L 옵션 순서대로 검색됩니다.

옵션 순서는 중요합니다. GCC는 이 라이브러리가 있는 디렉토리를 모르는 한 라이브러리 foo 에 대해 연결할 수 없습니다. 따라서 라이브러리에 연결하는 -l 옵션을 사용하기 전에 -L 옵션을 사용하여 라이브러리 디렉터리를 지정합니다.

한 단계에서 라이브러리를 사용하는 코드 컴파일 및 연결
단일 gcc 명령으로 컴파일 및 링크를 연결하면 컴파일 시간 및 링크 시간 옵션을 결합합니다.

2.3.5. GCC가 있는 정적 라이브러리 사용

정적 라이브러리는 오브젝트 파일이 포함된 아카이브로 사용할 수 있습니다. 연결 후 결과 실행 파일의 일부가 됩니다.

참고

Red Hat은 보안상의 이유로 정적 연결을 사용하지 않는 것이 좋습니다. 정적 및 동적 연결을 참조하십시오. 특히 Red Hat이 제공하는 라이브러리와 관련하여 필요할 때만 정적 링크를 사용하십시오.

사전 요구 사항

  • GCC가 시스템에 설치되어 있어야 합니다.
  • 정적 및 동적 연결을 이해해야 합니다.
  • 유효한 프로그램을 구성하는 소스 또는 오브젝트 파일 세트가 있으므로 일부 정적 라이브러리 foo 와 다른 라이브러리가 필요하지 않습니다.
  • foo 라이브러리는 libfoo.a 파일로 사용할 수 있으며 동적 연결을 위해 libfoo.so 파일이 제공되지 않습니다.

    참고

    Red Hat Enterprise Linux의 일부인 대부분의 라이브러리는 동적 연결에서만 지원됩니다. 아래 단계는 동적 링크에 사용할 수 없는 라이브러리에서만 작동합니다.

정적 및 동적 연결참조

프로세스

  • 소스 및 오브젝트 파일에서 프로그램을 연결하려면 lib foo.a 파일로 찾을 정적으로 연결된 라이브러리 foo를 추가합니다.

    1. 코드가 포함된 디렉터리로 변경합니다.
    2. foo 라이브러리의 헤더를 사용하여 프로그램 소스 파일을 컴파일합니다.

      $ gcc ... -Iheader_path -c ...

      header_pathfoo 라이브러리의 헤더 파일이 포함된 디렉터리의 경로로 바꿉니다.

    3. 프로그램을 foo 라이브러리와 연결합니다.

      $ gcc ... -Llibrary_path -lfoo ...

      library_pathlibfoo.a 파일이 포함된 디렉터리의 경로로 바꿉니다.

    4. 나중에 프로그램을 실행하려면 다음을 수행하십시오.

      $ ./program
      주의

      정적 링크와 관련된 -static GCC 옵션은 모든 동적 연결을 금지합니다. 대신 -Wl,-Bstatic-Wl,-Bdynamic 옵션을 사용하여 링커 동작을 보다 정확하게 제어합니다. GCC에서 정적 및 동적 라이브러리 사용을 참조하십시오.

2.3.6. GCC를 사용하는 동적 라이브러리 사용

동적 라이브러리는 독립 실행형 실행 파일로 사용할 수 있으며, 연결 시간과 런타임에 필요합니다. 애플리케이션의 실행 파일과 무관하게 유지됩니다.

사전 요구 사항

  • GCC는 시스템에 설치되어 있어야 합니다.
  • 유효한 프로그램을 구성하는 소스 또는 오브젝트 파일 세트에는 일부 동적 라이브러리 foo 및 기타 라이브러리가 필요하지 않습니다.
  • foo 라이브러리는 libfoo.so 파일로 사용 가능해야 합니다.

    동적 라이브러리에 대한 프로그램 연결
    동적 라이브러리 foo 에 대해 프로그램을 연결하려면 다음을 수행합니다.
$ *gcc ... -L__library_path__ -l__foo__ ...*

프로그램이 동적 라이브러리에 연결되어 있는 경우 결과 프로그램은 항상 런타임 시 라이브러리를 로드해야 합니다. 라이브러리를 찾는 방법은 다음 두 가지가 있습니다.

  • 실행 파일 자체에 저장된 실행 경로 값 사용
  • 런타임에 LD_LIBRARY_PATH 변수 사용

    실행 파일에 저장된 실행 경로 값 사용
    실행 경로는 연결될 때 실행 파일의 일부로 저장된 특수 값입니다. 나중에 프로그램이 실행 파일에서 로드되면 런타임 링커는 실행 경로 값을 사용하여 라이브러리 파일을 찾습니다.

GCC 와 연결하는 동안 library_path실행 경로로 저장하기 위해 다음을 수행합니다.

$ gcc ... -Llibrary_path -lfoo -Wl,-run path=library_path ...

path library_pathlibfoo.so 파일이 포함된 디렉토리를 가리켜야 합니다.

중요

-Wl,-run path= 옵션에 쉼표 뒤에 공백을 추가하지 마십시오.

나중에 프로그램을 실행하려면 다음을 수행합니다.

$ ./program
LD_LIBRARY_PATH 환경 변수 사용

라이브러리를 찾기 위해 검색 경로를 설정하는 또 다른 방법은 LD_LIBRARY_PATH 환경 변수를 사용하는 것입니다. 이 변수의 값은 각 프로그램에 대해 변경해야 합니다. 이 값은 공유 라이브러리 오브젝트가 있는 경로를 나타내며 모든 프로그램 호출에 대해 설정해야 합니다.

  1. LD_LIBRARY_PATH 환경 변수를 설정합니다.

    $ export LD_LIBRARY_PATH=library_path:$LD_LIBRARY_PATH
  2. 프로그램을 실행합니다.

    $ ./program
실행 경로 및 LD_LIBRARY_PATH의 상호 작용
Red Hat Enterprise Linux 10에서 연결 중에 프로그램에 인코딩된 실행 경로는 연결된 라이브러리를 LD_LIBRARY_PATH 에서 찾을 수 없는 경우에만 사용됩니다. LD_LIBRARY_PATH 전에 실행 경로가 검색되는 Red Hat Enterprise Linux 10의 이전 동작을 복원하기 위해 -Wl,--disable-new-dtags 옵션을 사용할 수 있습니다.
라이브러리가 기본 디렉터리에 배치
런타임 링커 구성은 여러 디렉터리를 동적 라이브러리 파일의 기본 위치로 지정합니다. 이 기본 동작을 사용하려면 라이브러리를 적절한 디렉터리에 복사합니다.

이 문서에서는 동적 연결 동작을 자세히 다루지 않습니다. 자세한 내용은 다음 리소스를 참조하십시오.

  • 동적 링커에 대한 Linux 도움말 페이지:
$ man ld.so
  • /etc/ld.so.conf 구성 파일의 콘텐츠:
$ cat /etc/ld.so.conf
  • 추가 구성 없이 동적 링커에서 인식하는 라이브러리의 보고서이며, 여기에는 디렉터리가 포함됩니다.
$ ldconfig -v

2.3.7. GCC에서 정적 및 동적 라이브러리 사용

경우에 따라 일부 라이브러리를 정적 및 기타 라이브러리를 동적으로 연결해야 하는 경우가 있습니다. 이 혼합 연결 접근 방식을 사용하려면 GCC가 다양한 라이브러리 유형을 처리하는 방법을 이해해야 합니다.

GCC 는 동적 라이브러리와 정적 라이브러리를 모두 인식합니다. lfoo 옵션이 발생하면 gcc 는 먼저 foo 라이브러리의 동적으로 연결된 버전이 포함된 공유 오브젝트( .so 파일)를 찾은 다음 라이브러리의 정적 버전이 포함된 아카이브 파일(.a)을 찾습니다. 따라서 이 검색으로 인해 다음과 같은 상황이 발생할 수 있습니다.

  • 공유 오브젝트만 발견되고 gcc 만 동적으로 연결됩니다.
  • 아카이브만 발견되고 gcc 만 정적으로 연결됩니다.
  • 공유 오브젝트와 아카이브가 모두 있으며 기본적으로 gcc 는 공유 오브젝트에 대한 동적 연결을 선택합니다.
  • 공유 오브젝트 또는 아카이브를 찾을 수 없으며 연결에 실패합니다.

이러한 규칙으로 인해 연결을 위한 정적 또는 동적 라이브러리 버전을 선택하는 가장 좋은 방법은 gcc 에서 해당 버전만 찾는 것입니다. 이는 -L경로 옵션을 지정할 때 라이브러리 버전이 포함된 디렉터리를 사용하거나 남겨 두어 어느 정도 제어할 수 있습니다.

또한 동적 링크가 기본값이므로 두 버전이 모두 있는 라이브러리를 정적으로 연결해야 하는 유일한 상황은 링크에서 명시적으로 지정해야 합니다. 두 가지 가능한 해결 방법이 있습니다.

  • -l 옵션 대신 파일 경로별 정적 라이브러리 지정
  • 링커에 옵션을 전달하려면 -Wl 옵션 사용

    파일별 정적 라이브러리 지정
    일반적으로 gccfoo 라이브러리에 대해 -lfoo 옵션을 사용하여 연결하라는 지시를 받습니다. 그러나 대신 라이브러리를 포함하는 libfoo.a 파일의 전체 경로를 지정할 수 있습니다.
$ *gcc ... path/to/libfoo.a ...*

파일 확장자 .a 에서gcc 는 프로그램과 연결할 라이브러리임을 이해할 것입니다. 그러나 라이브러리 파일의 전체 경로를 지정하는 것은 덜 유연합니다.

Wl 옵션 사용
gcc 옵션 -Wl 은 옵션을 기본 링커에 전달하는 특수 옵션입니다. 이 옵션의 구문은 다른 gcc 옵션과 다릅니다. w l 옵션 뒤에는 쉼표로 구분된 링커 옵션 목록이 있고 다른 gcc 옵션에는 공백으로 구분된 옵션 목록이 필요합니다.

gcc 에서 사용하는 ld 링커는 이 옵션의 라이브러리를 정적으로 연결하는 -Bstatic 옵션과 -Bdynamic 을 제공하여 동적으로 연결합니다. Bstatic 및 라이브러리를 링커에 전달한 후에는 다음 라이브러리가 -B dynamic 옵션과 동적으로 연결되도록 기본 동적 연결 동작을 수동으로 복원해야 합니다.

프로그램을 연결하려면 먼저 정적(lib first.a) 및 두 번째 동적으로(lib second.so ) 링크 라이브러리를 연결합니다.

$ gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond ...
참고

GCC 는 기본 ld 이외의 링커를 사용하도록 구성할 수 있습니다.

Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 문서 정보

Legal Notice

Theme

© 2026 Red Hat
맨 위로 이동