cmake find_library and CMAKE_FIND_ROOT_PATH

cmake find_library and CMAKE_FIND_ROOT_PATH

本文关键字:FIND ROOT CMAKE PATH and find library cmake      更新时间:2023-10-16

在cmake的find_library函数的文档中,我们有

CMake变量CMAKE_FIND_ROOT_PATH指定一个或多个要附加到所有其他搜索目录的目录。这有效地"重新根"整个搜索在给定的位置。路径哪些是CMAKE_STAGING_PREFIX的后代被排除在外这是重新生根,因为该变量始终是主机上的路径系统。默认CMAKE_FIND_ROOT_PATH为空。

CMAKE_SYSROOT变量也可以用来指定一个要用作前缀的目录。设置CMAKE_SYSROOT也有其他的效果。有关该变量的更多信息,请参阅文档。

这些变量在交叉编译指向时特别有用目标环境的根目录和CMake将搜索那里。默认情况下,首先列出的目录搜索CMAKE_FIND_ROOT_PATH,则CMAKE_SYSROOT目录为搜索,然后搜索非根目录。的默认行为可以通过设置进行调整CMAKE_FIND_ROOT_PATH_MODE_LIBRARY。这种行为可以手动进行在每次调用的基础上重写。通过使用CMAKE_FIND_ROOT_PATH_BOTH搜查顺序将如上所述。NO_CMAKE_FIND_ROOT_PATH为那么CMAKE_FIND_ROOT_PATH将不会被使用。如果ONLY_CMAKE_FIND_ROOT_PATH只用于重根目录和CMAKE_STAGING_PREFIX以下的目录将被搜索。

(见http://www.cmake.org/cmake/help/v3.0/command/find_library.html)

我不知道你是怎么读的,但对我来说,这似乎暗示着find_library将使用CMAKE_FIND_ROOT_PATH来寻找库。我写了以下cmakelists.txt:

cmake_minimum_required( VERSION 3.0 )
project( "cmakefindlibtest" )
message( "CMAKE_FIND_ROOT_PATH is ${CMAKE_FIND_ROOT_PATH}" )
list( APPEND CMAKE_FIND_ROOT_PATH "C:/DEV/lib/" )
message( "CMAKE_FIND_ROOT_PATH is now ${CMAKE_FIND_ROOT_PATH}" )
#find_library( punycode_library_test punycode PATHS "C:/DEV/lib" )
find_library( punycode_library_test punycode  )
message( "punycode_library_test is now ${punycode_library_test}" )
add_executable( cmakefindlibtest main.cpp )
target_link_libraries( cmakefindlibtest ${punycode_library_test} )

main.cpp就是hello world。在C:DEVlib,我已经把一个库命名为punycode.lib(这是在Windows上)。我已经将CMAKE_FIND_ROOT_PATH指向了目录。然后当我调用find_library时,我得到:

c:DEVcmakefindtest_build>cmake ..
-- Building for: Visual Studio 11 2012
CMAKE_FIND_ROOT_PATH is
CMAKE_FIND_ROOT_PATH is now C:/DEV/lib/
punycode_library_test is now punycode_library_test-NOTFOUND
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
punycode_library_test
    linked by target "cmakefindlibtest" in directory C:/DEV/cmakefindtest
-- Configuring incomplete, errors occurred!
See also "C:/DEV/cmakefindtest/_build/CMakeFiles/CMakeOutput.log".

注意,当我将目录添加到find_library调用的PATHS部分时

find_library( punycode_library_test punycode PATHS "C:/DEV/lib" )

一切工作:

c:DEVcmakefindtest_build>cmake ..
-- Building for: Visual Studio 11 2012
CMAKE_FIND_ROOT_PATH is
CMAKE_FIND_ROOT_PATH is now C:/DEV/lib/
punycode_library_test is now C:/DEV/lib/punycode.lib
-- Configuring done
-- Generating done
-- Build files have been written to: C:/DEV/cmakefindtest/_build

那么find_library不使用CMAKE_FIND_ROOT_PATH吗?

更新:

看起来CMAKE_LIBRARY_PATH基本上做了我想要它做的事情,根据http://public.kitware.com/pipermail/cmake-developers/2012-January/002850.html,看起来这就是我在这种情况下应该使用它的原因。

但是,我仍然在试图弄清楚为什么CMAKE_FIND_ROOT_PATH不能与find_library一起工作。http://www.cmake.org/Wiki/CMake_Cross_Compiling上的文档说CMAKE_FIND_ROOT_PATH

这是一个目录列表,每个目录都列在那里会不会在每一个搜索目录前加上每一个FIND_XXX()命令。

在这种情况下似乎不为真,除非有某种设置或我遗漏了另一个变量

首先,CMAKE_FIND_ROOT_PATH将被添加到find_library的文档中描述的一组目录中。它不会被添加到您为find_library指定的文件名中。

您只需要使用CMAKE_FIND_ROOT_PATH进行交叉编译。例如,虽然find_library(.. jpeg ...)会找到/usr/lib/libjpeg.so,但你可以用set(CMAKE_FIND_ROOT_PATH ~/my_toolchain)劫持这个搜索来找到~/my_toolchain/usr/lib/libjpeg.so

既然你没有提到你在交叉编译,你可能需要的是CMAKE_PREFIX_PATH

尝试set(CMAKE_PREFIX_PATH "c:/DEV")set(CMAKE_LIBRARY_PATH "c:/DEV/lib")c:/DEV/lib中进行find_library搜索。

在使用指定的外部工具链进行openwrt交叉编译时,我遇到了同样的问题。

就像所描述的问题一样,我已经将CMAKE_FIND_ROOT_PATH设置为工具链的目录,但是rpcd仍然抱怨缺少crypt库。

然后我注意到这个线程,并认为可能是因为./usr/lib./lib隐含的lib搜索路径。因此,我将CMAKE_FIND_ROOT_PATH更改为工具链的系统根,其中包括目标平台的./usr/lib./lib,然后问题就解决了。

回到原来的问题,我想也许如果你可以尝试将CMAKE_FIND_ROOT_PATH设置为C:/DEV,并将库链接到C:/DEV/lib下。

也就是说,如果您不进行交叉编译,这可能不是最明智的解决方案。