Как изменить CMakeList.txt: библиотека найдена, но есть ошибки компоновки - PullRequest
0 голосов
/ 29 апреля 2018

Я создаю библиотеку C, которая будет собираться с помощью cmake, используя Mac OS для разработки. В CMakeList.txt у меня есть следующее

#htslib
find_package(htslib REQUIRED)
include_directories(${HTSLIB_INCLUDE_DIR})


target_link_libraries(projectname ${HTSlib_LIBRARIES})

который выводит при cmake ..

Found hstlib 

Однако при make я получаю ошибки компоновщика:

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Итак ... он может найти библиотеку, и библиотека определенно установлена ​​с sudo make install, но есть ошибки связывания только с этой библиотекой.

(1) Я предполагаю, что find_package(htslib REQUIRED) находит что-то еще. Как мне узнать что?

(2) Как я явно пишу в CMakeList.txt, чтобы найти библиотеку, которая, как я знаю, была правильно установлена?

1 Ответ

0 голосов
/ 30 апреля 2018
  1. Используйте VERBOSE=1 make для просмотра вывода компоновщика. Искать -lhtslib
  2. Прочитайте документацию для конкретного Find<LIB>.cmake.

Ваши конкретные вопросы:

  1. «Как мне найти то, что нашел CMake»: используйте cmake-gui или ccmake. Они оба показывают одну и ту же информацию, но один из них представляет собой графический интерфейс, а другой - интерфейс Curses. В расширенном режиме («t» на ccmake) вы найдете все переменные для найденных пакетов. Кроме того, вы можете использовать MESSAGE(STATUS "Found htslib at: ${htslib_LIBRARIES}").
  2. "Как явно написать в CMakeLists.txt, где находится библиотека?" Пожалуйста, не делайте этого! CMake предназначен для абстрагирования именно такой информации. У вас есть два варианта, во-первых, хороший: настроить cmake в командной строке (или в графических интерфейсах, упомянутых выше), чтобы получить CMAKE_MODULES_PATH или более конкретную подсказку для библиотеки -D htslib_PATH=/usr/local/.../ (указывающую на каталог, где libhts.dylib проживает). Худшее решение было бы предоставить подсказку для find_package. find_package(htslib REQUIRED PATH /usr/local/lib) или find_package(htslib REQUIRED HINT /usr/local/lib /some/second/path/where/it/may/be).

Решение

Ваш связанный проект имеет пользовательскую FindHTSlib.cmake ссылку . Этот использует pkg_config для настройки библиотеки. Чтобы повторить вашу проблему, я использовал brew для установки htslib. Файл pkg-config можно найти (для меня, но brew info htslib говорит вам) в /usr/local/Cellar/htslib/1.8/lib/htslib.pc. Итак, давайте дадим CMake необходимую подсказку.

Я не смог проверить это, потому что для меня он нашел пакет htslib напрямую, без дальнейших подсказок.

git clone https://github.com/D-Lo/bamdb # I am using version f5f03d0
mkdir -p bamdb/build; cd bamdb/build
brew install ck htslib lmdb
cmake ..  # -G Ninja recommended, but needs brew install ninja
make # lot's of missing symbols

Я бы порекомендовал изменить в CMakeLists.txt минимально требуемую версию CMake с 2,8 до 3.10 (или хотя бы 3,6).

Это ошибка, которую я получаю:

[ 62%] Linking C shared library libbamdb.dylib
/usr/local/Cellar/cmake/3.11.1/bin/cmake -E cmake_link_script CMakeFiles/libbamdb.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/cc -Wall -g -std=gnu99 -fPIC -dynamiclib -Wl,-headerpad_max_install_names  -o libbamdb.dylib -install_name @rpath/libbamdb.dylib CMakeFiles/libbamdb.dir/src/bam_api.c.o CMakeFiles/libbamdb.dir/src/bam_lmdb.c.o CMakeFiles/libbamdb.dir/src/bamdb.c.o
Undefined symbols for architecture x86_64:
  "_bam_destroy1", referenced from:
      _get_bam_row in bam_api.c.o
      _deserialize_func in bam_lmdb.c.o

Это можно исправить, добавив следующую строку в CMakeLists.txt после строки add_library(libbamdb ${SOURCES}):

target_link_libraries(libbamdb ${LIBS})

Некоторые дополнительные замечания: теперь у вас есть библиотека с функцией main. Это потому, что ${SOURCES} используется для сборки исполняемого файла и библиотеки. Это может иметь неожиданные побочные эффекты. Если это не нужно, не делайте этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...