Linker 链接到特定库
我正在编译一个简单的测试程序,它使用了Linker 链接到特定库,linker,cmake,lapack,Linker,Cmake,Lapack,我正在编译一个简单的测试程序,它使用了lapack,但是我安装了3个版本的lapack库(一个来自/usr/lib中的苹果,一个来自/opt/local/lib中的macports,还有一个我自己安装在/usr/local/lib中) 我有以下CMakeLists.txt文件: cmake_minimum_required(VERSION 3.0) project(delme) include_directories(../../include /usr/local/include/boos
lapack
,但是我安装了3个版本的lapack库(一个来自/usr/lib
中的苹果,一个来自/opt/local/lib
中的macports,还有一个我自己安装在/usr/local/lib
中)
我有以下CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.0)
project(delme)
include_directories(../../include /usr/local/include/boost-numeric-bindings)
find_library(lapack_LIBRARY NAMES lapack liblapack HINTS /usr/local/lib )
find_library(atlas_LIBRARY NAMES atlas libatlas HINTS /usr/local/lib )
find_library(cblas_LIBRARY NAMES cblas libcblas HINTS /usr/local/lib )
add_executable(delme test.cpp main.cpp)
target_link_libraries(delme lapack atlas cblas)
install(TARGETS delme RUNTIME DESTINATION bin)
调用cmake.&使VERBOSE=1
,我得到的输出以:
Linking CXX executable delme
/opt/local/bin/cmake -E cmake_link_script CMakeFiles/delme.dir/link.txt --verbose=1
/usr/bin/c++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/delme.dir/test.cpp.o CMakeFiles/delme.dir/main.cpp.o -o delme -llapack -latlas -lcblas
Undefined symbols for architecture x86_64:
"_clapack_dgetrf", referenced from:
boost::numeric::bindings::atlas::detail::getrf(CBLAS_ORDER, int, int, double*, int, int*) in main.cpp.o
"_clapack_dgetri", referenced from:
boost::numeric::bindings::atlas::detail::getri(CBLAS_ORDER, int, double*, int, int const*) in main.cpp.o
"_clapack_dpotrf", referenced from:
boost::numeric::bindings::atlas::detail::potrf(CBLAS_ORDER, CBLAS_UPLO, int, double*, int) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
这些符号出现在/usr/local/lib
和macports版本中,但不是苹果的版本,苹果的版本似乎就是它链接的对象。
如果我手动将-L/usr/local/lib
添加到CMake生成的文件CMakeFiles/delme.dir/link.txt
,则它可以正常编译
我的问题是,如何指示cmake在其链接命令(或其他替代命令)中包含
-L/usr/local/lib
,以便使用/usr/local/lib
中的版本?其他库路径之一可能位于cmake缓存变量中。CMake首先找到库版本。找到库后,除非清除缓存,否则“查找库”不会再次查询同一库
如中所述,命令find_library
在搜索库时使用以下顺序:
无默认路径
或无默认路径
跳过李>
无默认路径
或无环境路径
跳过无默认路径跳过李>
使用无默认路径
或无系统环境路径
跳过
使用无默认路径
或无系统路径
跳过
使用无默认路径跳过
所以一开始看起来你会跳过步骤1和2,但根据Kitware的说法,你不应该把绝对路径放在提示下。关于暗示,美国
这些应该是由系统自省计算的路径,例如由已经找到的另一个项目的位置提供的提示。硬编码猜测应使用路径选项指定
当然,今天使用提示可能会奏效,但如果您希望将来验证您的CMake文件,我建议您遵循他们的建议。因此,您的命令与此类似,以防止CMake执行步骤1、2、3和4:
find_library(lapack_LIBRARY
NAMES lapack liblapack
PATHS /usr/local/lib
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH
)
另一种选择是设置在步骤1或2中搜索到的变量之一,但这更难做到正确,而且很容易被未来的更改破坏
另外,请注意,避免使用cmake.
创建源代码内构建。创建另一个文件夹,如build
,然后从那里运行cmake命令。这样可以更轻松地删除cmake生成的文件并重新开始。此外,它不会使源代码树混乱。其他库路径之一可能位于cmake缓存变量中。CMake首先找到库版本。找到库后,除非清除缓存,否则“查找库”不会再次查询同一库
如中所述,命令find_library
在搜索库时使用以下顺序:
在cmake特定缓存变量中指定的搜索路径李>
在cmake特定环境变量中指定的搜索路径李>
搜索提示选项指定的路径李>
搜索标准系统环境变量李>
搜索当前系统的平台文件中定义的cmake变量李>
搜索“路径”选项指定的路径或命令的简写版本
基于这些步骤,CMake在步骤1或2中找到了不同版本的库。
存在允许跳过部分或所有这些步骤的参数
使用无默认路径
或无默认路径
跳过李>
使用无默认路径
或无环境路径
跳过
使用无默认路径跳过李>
使用无默认路径
或无系统环境路径
跳过
使用无默认路径
或无系统路径
跳过
使用无默认路径跳过
所以一开始看起来你会跳过步骤1和2,但根据Kitware的说法,你不应该把绝对路径放在提示下。关于暗示,美国
这些应该是由系统自省计算的路径,例如由已经找到的另一个项目的位置提供的提示。硬编码猜测应使用路径选项指定
当然,今天使用提示可能会奏效,但如果您希望将来验证您的CMake文件,我建议您遵循他们的建议。因此,您的命令与此类似,以防止CMake执行步骤1、2、3和4:
find_library(lapack_LIBRARY
NAMES lapack liblapack
PATHS /usr/local/lib
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH
)
另一种选择是设置在步骤1或2中搜索到的变量之一,但这更难做到正确,而且很容易被未来的更改破坏
另外,请注意,避免使用cmake.
创建源代码内构建。创建另一个文件夹,如build
,然后从那里运行cmake命令。这样可以更轻松地删除cmake生成的文件并重新开始。也是