저는 Unix/Linux C 라이브러리(예 : ) 를 사용하는 타사 C 코드 조각으로 작업하는 경우가 많습니다 #include <glib.h>
. 예 를 #include <net/if.h>
들어 특정 라이브러리 파일 이름이나 pkg-config 이름을 알아야 합니다 . "2.0", "1"의 헤더 파일이 달라서 추측할 수 없습니다.-lglib-2.0
-lbluetooth
pkg-config --libs dbus-1
API/라이브러리가 소유한 라이브러리 파일의 정확한 이름을 어떻게 찾을 수 있나요? 위의 예를 사용하면 #include <glib.h>
라이브러리 파일의 이름을 어떻게 찾을 수 있습니까 -lglib-2.0
? 실망스럽게도 Glib/dbus/all에 대한 온라인 참조에는 "라이브러리 파일 이름이 glib-2.0입니다"라고만 나와 있지 않습니다.
이를 파악하는 데 사용할 수 있는 터미널 명령이 있습니까? 이를 알아내는 데 사용할 수 있는 유틸리티가 있습니까? 온라인 API/라이브러리 참조는 이것을 찾는 데 정말 좋지 않습니다.
위치 를 찾고 싶다면 hci.h
쉽게 찾을 수 있습니다 locate hci.h
. 라이브러리 이름을 찾는 터미널 명령과 같은 것이 있습니까?
답변1
특정 기능을 사용하는 데 어떤 라이브러리가 필요한지 알 수 있는 일반적인 방법은 없습니다. 이 라이브러리에 대한 설명서를 확인해야 합니다. 잘 작성된 튜토리얼이나 API 참조는 이것이 무엇인지 알려줄 것입니다.
적어도 도서관이 무엇인지는 이해할 수 있습니다.팩필수: 헤더 파일이 포함된 라이브러리 패키지와 동일합니다. 헤더 파일이 포함된 패키지를 확인하는 방법은 배포판(예: dpkg -S /usr/include/glib-2.0/glib.h
Debian/Ubuntu/Mint/..., rpm -qf /usr/include/glib-2.0/glib.h
RHEL/CentOS/Fedora/... 등) 에 따라 다릅니다. 라이브러리 패키지를 알고 나면 해당 내용을 나열하여 .so
포함된 파일을 찾습니다.
dpkg -L libglib2.0-dev | grep '\.so$'
rpm -qlf /usr/include/glib-2.0/glib.h | grep '\.so$'
Glib에는 여러 .so
파일이 있으며 특정 기능에 어떤 파일이 필요한지 자동으로 알 수 있는 방법이 없습니다(여러 파일이 있을 수 있음).
라이브러리에서 이를 사용하는 경우 pkg-config
헤더 및 라이브러리 경로를 하드코딩하는 대신 이를 사용해야 합니다. 그러나 모든 도서관이 이를 사용하는 것은 아닙니다. 배포판의 라이브러리 패키지는 해당 pkg-config
패키지(예 dpkg -s libglib2.0-dev |grep '^Depends:.*pkg-config'
: )에 종속되어야 하기 때문에 일반적으로 알 수 있습니다.
문서가 정말 형편없으면 라이브러리에서 정의한 기호를 나열해 보세요.
nm -D /usr/lib/x86_64-linux-gnu/libgio-2.0.so |awk '$2=="T" {print $3}'
다른 라이브러리가 필요한지 알려주지 않으므로 이는 완벽한 방법이 아닙니다.
답변2
이러한 #include
명령어는 C 전처리기에 의해 확장됩니다. 검색 경로는 컴파일러(예: -I<dir>
플래그)에 의해 제어됩니다. 생성된 개체 파일에 기호를 제공합니다.
그런 다음 링커는 규칙을 사용하여 이러한 기호를 아카이브/객체 파일에 매핑합니다. 유사한 플래그가 주어지면 -l<namespec>
링커는 라이브러리 경로 lib<namespec>.a
또는 의 디렉터리에서 검색합니다 lib<namespec>.so
. 링커는 생성된 바이너리에 이러한 파일 이름을 포함하고 동적 링커는 런타임에 이러한 파일 이름을 사용하여 기호를 실제 구현으로 해석합니다.
검색 디렉토리를 사용하여 컴파일러 링커를 찾을 수 있습니다 ld --verbose | grep SEARCH_DIR
. 예를 들어 다음은 링커가 라이브러리 이름을 파일에 매핑하는 방법을 대략적으로 시뮬레이션합니다 .so
.
$ libname=glib-2.0; ld --verbose | grep SEARCH_DIR | tr -s ' ;' '\n' | sed 's/SEARCH_DIR("=\?\(.*\)")/\1/g' | xargs -I{} find {} -maxdepth 1 2>/dev/null | grep lib${libname}.so
/usr/lib/libglib-2.0.so.0.7000.0
/usr/lib/libglib-2.0.so
/usr/lib/libglib-2.0.so.0
(이것들은 모두 동일한 파일에 대한 심볼릭 링크입니다.)
패키지 관리자에서 이 파일을 제공하는 패키지를 찾을 수 있습니다 yum
. 예를 들면 다음과 같습니다.
$ yum whatprovides /usr/lib64/libglib-2.0.so.0
glib2-2.68.1-1.fc34.x86_64 : A library of handy utility functions
Repo : fedora
Matched from:
Filename : /usr/lib64/libglib-2.0.so.0
glib2-2.68.4-1.fc34.x86_64 : A library of handy utility functions
Repo : @System
Matched from:
Filename : /usr/lib64/libglib-2.0.so.0
glib2-2.68.4-1.fc34.x86_64 : A library of handy utility functions
Repo : updates
Matched from:
Filename : /usr/lib64/libglib-2.0.so.0
다음 명령을 사용하여 기호를 볼 수 있습니다 nm
.
$ nm -D --defined-only /usr/lib/libglib-2.0.so.0
0000000000070000 T g_access
000000000001d600 T g_allocator_free
000000000001d5f0 T g_allocator_new
0000000000022810 T g_array_append_vals
000000000001e3a0 T g_array_binary_search
...
링커 규칙은 에 문서화되어 있습니다 man ld
.
마지막으로 귀하의 질문에 답변해 드리겠습니다. 이러한 메커니즘은 실제 구현에서 헤더를 분리하도록 설계되었으므로 설계상 헤더를 개체/아카이브에 매핑하는 보편적인 방법은 없습니다. 결국에는 .so
기호를 구현하는 파일을 찾아야 합니다 #include
. 다른 답변에서 말했듯이 이것은 일시적입니다.
그러나 패키지 관리자는 일반적으로 헤더 파일을 제공하는 패키지이고 <package>-devel
해당 패키지는 <package>
공유 객체를 제공하므로 많은 도움이 됩니다. 예를 들어, yum
이를 사용하여 개발 패키지를 찾을 수 있습니다.
$ yum provides '*/glib.h'
glib-devel-1:1.2.10-62.fc34.i686 : Libraries and header files for glib development
Repo : fedora
Matched from:
Filename : /usr/include/glib-1.2/glib.h
glib-devel-1:1.2.10-62.fc34.x86_64 : Libraries and header files for glib development
Repo : fedora
Matched from:
Filename : /usr/include/glib-1.2/glib.h
glib2-devel-2.68.1-1.fc34.i686 : A library of handy utility functions
Repo : fedora
Matched from:
Filename : /usr/include/glib-2.0/glib.h
...
glib2-devel
패키지에 헤더 파일이 제공되는 것을 볼 수 있습니다 . 따라서 glib2
패키지는 해당 .so
파일을 제공하며 해당 파일 이름에서 사용할 플래그가 무엇인지 알 수 있습니다 -l
.
$ repoquery -l glib2 | grep '.so'
/usr/lib/libgio-2.0.so.0
/usr/lib/libgio-2.0.so.0.6800.4
/usr/lib/libglib-2.0.so.0
/usr/lib/libglib-2.0.so.0.6800.4
...
따라서 를 고려하면 glib.h
최소한 을 사용해야 한다는 것을 알 수 있습니다 -lglib-2.0
.