#c #cmake
#c #cmake
Вопрос:
Я использую CMake для компиляции приложения, которое использует библиотеку HSImage на github. После установки с помощью pip библиотека HSI генерирует файл общей библиотеки, в моем случае он создается по адресу /usr/src/HSI/HSI.cpython-36m-aarch64-linux-gnu.so
Я пытаюсь связать эту библиотеку с моим приложением с помощью CMake, но find_library
у метода CMake возникают некоторые проблемы с поиском библиотеки. Вот соответствующая часть моего CMakeLists.txt файл:
CMakeLists.txt
set(HSI_DIR /usr/src/HSI)
find_library(HSI_LIB HSI.cpython-36m-aarch64-linux-gnu PATHS ${HSI_DIR})
message(STATUS "HSI: ${HSI_LIB}") # outputs /usr/src/HSI/HSI.cpython-36m-aarch64-linux-gnu.so
add_executable(${TARGET_NAME} <sources...>)
target_link_directories(${TARGET_NAME} PUBLIC ${HSI_DIR})
target_link_libraries(${TARGET_NAME}
${HSI_LIB}
<other libs...>
-Wl,--unresolved-symbols=ignore-in-shared-libs
)
При сборке выдается следующее сообщение об ошибке:
cd /home/nvidia/projects/HsiInference/build;/usr/local/bin/cmake --build "/home/nvidia/projects/HsiInference/build" --target hsi_inference_onnx -- ;
Scanning dependencies of target hsi_inference_onnx
[ 14%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/targets/HsiInferenceOnnx/main_onnx.cpp.o
[ 28%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/targets/HsiInferenceOnnx/HsiInferenceOnnx.cpp.o
[ 42%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/src/ftpnano.cpp.o
[ 57%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/src/getOptions.cpp.o
[ 71%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/src/logger.cpp.o
[ 85%] Building CXX object CMakeFiles/hsi_inference_onnx.dir/src/utils.cpp.o
[100%] Linking CXX executable hsi_inference_onnx_debug
CMakeFiles/hsi_inference_onnx.dir/build.make:245: recipe for target 'hsi_inference_onnx_debug' failed
CMakeFiles/Makefile2:123: recipe for target 'CMakeFiles/hsi_inference_onnx.dir/all' failed
**/usr/bin/ld: cannot find -lHSI.cpython-36m-aarch64-linux-gnu**
**collect2: error: ld returned 1 exit status**
make[3]: *** [hsi_inference_onnx_debug] Error 1
make[2]: *** [CMakeFiles/hsi_inference_onnx.dir/all] Error 2
CMakeFiles/Makefile2:130: recipe for target 'CMakeFiles/hsi_inference_onnx.dir/rule' failed
make[1]: *** [CMakeFiles/hsi_inference_onnx.dir/rule] Error 2
Makefile:196: recipe for target 'hsi_inference_onnx' failed
make: *** [hsi_inference_onnx] Error 2
Build failed.
Важная часть:
/usr/bin/ld: cannot find -lHSI.cpython-36m-aarch64-linux-gnu
collect2: error: ld returned 1 exit status
Из того, что я собрал, target_link_libraries
просто добавляет -l<library_name>
к команде link и -l<library_name>
предполагает, что существует файл, вызываемый lib<library_name>.so
для ссылки, что здесь не так. Как я могу заставить CMake правильно связать библиотеку, несмотря на странное имя файла?
ПРИМЕЧАНИЕ: я могу запустить проект, выполнив следующие действия:
- Удалите
build
каталог проекта, чтобы очистить кэши CMake - Переименуйте файл или создайте символическую ссылку на
libhsi.so
- Изменить CMakeLists.txt чтобы
find_library(HSI_LIB hsi PATHS ${HSI_DIR})
Это изменяет команду link на -lhsi
instead, которая может найти переименованный / программный файл библиотеки. ОДНАКО это не идеально для меня, и первоначальный вопрос остается без ответа 🙂
Комментарии:
1. Вы можете указать полный путь в
target_link_library
и CMake не добавит к-l
нему опцию.2. @Someprogrammerdude Я попытался жестко закодировать полный путь к библиотеке в аргументы
target_link_library
, и он выдает ту же ошибку, даже после удаленияbuild
каталога :/3. Почему вы используете
target_link_directories
? Эта команда необходима только тогда, когда у вас есть только имя библиотеки. Ноfind_library
дает вам абсолютный путь.4. @Tsyvarev Вы правы, в данном случае в этом нет необходимости. Я думаю, что это осталось от того, когда у меня была другая команда, которая связывала библиотеку только по имени файла. В любом случае абсолютный путь не работает.
5. Я подозреваю, что вы каким-то образом связываете как по полному пути, так и по имени (или у вас сломанная версия CMake, это тоже случается).
Ответ №1:
Для библиотек со странным именем файла вы должны добавить :
перед именем файла. Будьте осторожны, как указано в https://linux.die.net/man/1/ld : Если namespec имеет вид :filename , ld будет искать путь к библиотеке для файла с именем filename , в противном случае он будет искать путь к библиотеке для файла с именем libnamespec.a (namespec — это то, что идет после -l).
Для вашего примера вы должны заменить ${HSI_LIB}
в target_link_libraries на :${HSI_LIB}.so
.