我正在创建一个用cmake构建的C库,使用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中写入,以查找我知道已正确安装的库?
最佳答案
使用VERBOSE=1 make
查看链接器输出。搜索-lhtslib
阅读特定Find<LIB>.cmake
的文档。
你的具体问题:
“我如何找到CMake发现的”:使用cmake-gui
或ccmake
。它们都显示相同的信息,但一个是GUI,另一个是Curses接口。在高级模式(“t”onccmake
)中,您将找到搜索包的所有变量。此外,您还可以使用MESSAGE(STATUS "Found htslib at: ${htslib_LIBRARIES}")
。
“如何在库所在的CMakeLists.txt中显式写入?”求你了,别那么做!CMake的本意是将这种信息准确地提取出来。您有两个选项,首先是好的选项:在命令行(或在上面提到的gui中)配置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
link。这个函数使用pkg_config
来配置库。为了复制您的问题,我使用brew安装了htslib
。pkg配置文件可以在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
我建议将CMake的最低版本从2.8改为
CMakeLists.txt
(或至少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
可以通过在
3.10
中的CMakeLists.txt
行之后添加以下行来解决此问题:target_link_libraries(libbamdb ${LIBS})
进一步说明:您现在拥有一个带有
add_library(libbamdb ${SOURCES})
函数的库。这是因为main
用于构建可执行文件和库。会有意想不到的副作用。除非有需要,否则不要这样做。