Компоновщику CMake не удается найти библиотеку, которая не начинается с «lib»

#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 .