ฉันกำลังพยายามสร้างไลบรารี C libmy
ที่ขึ้นอยู่กับไลบรารีภายนอก libext
ทั้ง libmy
และ libext
ใช้ CMake นอกจากนี้ libext
ยังสร้างอ็อบเจ็กต์ที่ใช้ร่วมกันสองรายการ คือ libext1.so
และ libext2.so
ซึ่งทั้งสองอ็อบเจ็กต์จำเป็นสำหรับ libmy
ก่อนอื่น ฉันติดตั้ง libext
ด้วยโมดูล CMake ที่กำหนดเอง ซึ่งต่ำกว่า ${CMAKE_BINARY_DIR}/ext
กระบวนการนี้สำเร็จและฉันได้ผลลัพธ์ดังนี้:
${CMAKE_BINARY_DIR}
└── ext
└── lib
├── libext1.so
└── libext2.so
เพื่อทดสอบ libmy
ฉันสร้างกรณีทดสอบบางส่วนภายใต้เป้าหมาย mytest
ซึ่งเชื่อมโยงไปยังวัตถุที่ใช้ร่วมกัน libmy.so
, libext1.so
และ libext2.so
กระบวนการสร้างเป้าหมายทั้งหมดสิ้นสุดลงเรียบร้อยแล้ว แต่เมื่อฉันพยายามเรียกใช้ mytest
ฉันพบปัญหา ไม่สามารถเปิดไฟล์อ็อบเจ็กต์ที่แชร์ได้: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว แต่สำหรับ libext1.so
เท่านั้น ในขณะที่พบ libext2.so
อย่างถูกต้อง อย่างไรก็ตาม สิ่งที่มากน่าสงสัยก็คือ ทั้ง libext1.so
และ libext2.so
อยู่ในเส้นทางเดียวกัน และ libext2.so
ก็เชื่อมโยงได้สำเร็จจริง ๆ ขณะรันไทม์ นี่คือสิ่งที่ LD_DEBUG=libs mytest
พิมพ์:
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
ดังนั้น ด้วยเหตุผลบางประการ ในการค้นหา libext1.so
ระบบจะใช้พาธการค้นหาของระบบ (ซึ่งไม่รวมพาธไปยังไลบรารีภายนอก) ในขณะที่ libext2.so
จะใช้ RUNPATH (ซึ่งมีพาธที่ถูกต้อง)
โดยพื้นฐานแล้วโมดูล CMake ที่ฉันสร้างไลบรารีภายนอกจะทำสิ่งนี้:
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)
และไฟล์ CMakeLists.txt ที่ mytest
ถูกสร้างขึ้นประกอบด้วย:
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)
ข้อจำกัดความรับผิดชอบ: ฉันทำให้สถานการณ์ง่ายขึ้น เนื่องจากไลบรารีมีขนาดค่อนข้างใหญ่และกระบวนการสร้างประกอบด้วยองค์ประกอบอื่นๆ หลายประการ แต่หวังว่านี่จะเพียงพอแล้ว