Saya mencoba membangun perpustakaan C libmy
yang bergantung pada perpustakaan eksternal libext
. Baik libmy
dan libext
menggunakan CMake. Selanjutnya, libext
sebenarnya menghasilkan dua objek bersama, libext1.so
dan libext2.so
, keduanya dibutuhkan oleh libmy
.
Pertama, saya menginstal libext
dengan modul CMake khusus, di bawah ${CMAKE_BINARY_DIR}/ext
. Prosesnya berhasil dan saya mendapatkan pohon berikut:
${CMAKE_BINARY_DIR}
└── ext
└── lib
├── libext1.so
└── libext2.so
Untuk menguji libmy
, saya membuat beberapa kasus uji di bawah target mytest
, yang tertaut ke objek bersama libmy.so
, libext1.so
dan libext2.so
.
Proses pembangunan semua target berakhir dengan sukses. Tetapi ketika saya mencoba menjalankan mytest
, saya mendapatkan tidak dapat membuka file objek bersama yang terkenal: Tidak ada file atau direktori tersebut, tetapi hanya untuk libext1.so
, sementara libext2.so
ditemukan dengan benar. Namun, yang sangat membuat penasaran adalah bahwa libext1.so
dan libext2.so
terletak di jalur yang sama, dan libext2.so
memang berhasil ditautkan pada waktu proses. Inilah yang LD_DEBUG=libs mytest
cetak:
10703: find library=libext2.so [0]; searching
10703: search path=/usr/local/lib:/home/user/mylib/build/ext/lib:x86_64: (RUNPATH from file src/test/mytest)
10703: trying file=/usr/local/lib/libext2.so
10703: trying file=/home/user/mylib/build/ext/lib/libext2.so
10703:
10703: find library=libext1.so [0]; searching
10703: search cache=/etc/ld.so.cache
10703: trying file=/usr/local/lib/libext1.so
10703: search path=/lib/x86_64-linux-gnu/tls/haswell/x86_64:[...truncated long search path (/home/user/mylib/build/ext/lib is not here)...]:/usr/lib (system search path)
10703: trying file=/lib/x86_64-linux-gnu/tls/haswell/x86_64/libext1.so
...
10703: trying file=/usr/lib/haswell/libext1.so
10703: trying file=/usr/lib/x86_64/libext1.so
10703: trying file=/usr/lib/libext1.so
10703:
src/test/myest: error while loading shared libraries: libext1.so: cannot open shared object file: No such file or directory
Jadi, entah kenapa, untuk mencari libext1.so
digunakan jalur pencarian sistem (yang tidak menyertakan jalur ke perpustakaan eksternal), sedangkan untuk libext2.so
digunakan RUNPATH (yang memang memiliki jalur yang benar).
Modul CMake tempat saya membangun perpustakaan eksternal pada dasarnya melakukan ini:
include(ExternalProject)
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/ext)
ExternalProject_Add(extproject
GIT_REPOSITORY https://github.com/ext/ext.git
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION})
include_directories(${EXTERNAL_INSTALL_LOCATION}/include)
link_directories(${EXTERNAL_INSTALL_LOCATION}/lib)
set(EXT_INCLUDE_DIR ${EXTERNAL_INSTALL_LOCATION}/include)
set(EXT1_LIBRARY ext1)
set(EXT2_LIBRARY ext2)
Dan file CMakeLists.txt tempat mytest
dibuat berisi:
add_executable(mytest mytest.cpp)
target_include_directories (mytest
PUBLIC
${EXT_INCLUDE_DIR})
target_link_libraries(mytest
my
${EXT1_LIBRARY}
${EXT2_LIBRARY})
add_test(NAME mytest COMMAND mytest)
Penafian: Saya memberikan penyederhanaan skenario, karena perpustakaannya agak besar dan proses pembangunannya berisi beberapa komponen lainnya. Tapi semoga ini cukup.