cmake find_library和CMAKE_FIND_ROOT_PATH

时间:2014-07-09 17:05:42

标签: c++ c cmake

在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只是你好世界。在C:\DEV\lib中,我放了一个名为punycode.lib的库(这是在Windows上)。我已将CMAKE_FIND_ROOT_PATH指向该目录。然后当我致电find_library时,我得到:

c:\DEV\cmakefindtest\_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:\DEV\cmakefindtest\_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()命令。

在这种情况下似乎不是真的,除非我错过了某种设置或其他变量。

2 个答案:

答案 0 :(得分:2)

首先,find_library将被添加到docs of 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劫持此搜索,以便找到set(CMAKE_PREFIX_PATH "c:/DEV")

由于你没有提到你正在交叉编译你可能需要的是CMAKE_PREFIX_PATH。尝试set(CMAKE_LIBRARY_PATH "c:/DEV/lib")find_libraryc:/DEV/lib中进行positions = [('0','927','928'),('2','693','694'),('2','742','743'),('2','776','777'),('2','804','805'), ('2','987','988'),('2','997','998'),('2','1019','1020'), ('2','1038','1039'),('2','1047','1048'),('2','1083','1084'),('2','659','660'), ('2','677','678'),('2','743','744'),('2','777','778'),('2','805','806'),('2','830','831')] sorted_dict = {} sorted_list = [] grouped_list = [] doc_ids = [] def sort_func(positions): for item in positions: if item[0] not in doc_ids: doc_ids.append(item[0]) for doc_id in doc_ids: sorted_set = [] for item in positions: if item[0] != doc_id: continue else: if item[1] not in sorted_set: sorted_set.append(item[1]) if item[2] not in sorted_set: sorted_set.append(item[2]) sorted_list = sorted(sorted_set) sorted_dict[doc_id] = sorted_list for k in sorted_dict: group = [] grouped_list = [] for i in sorted_dict[k]: try: if int(i)-1 == int(sorted_dict[k][sorted_dict[k].index(i)-1]): group.append(i) else: if group != []: grouped_list.append(group) group = [i] except IndexError: group.append(i) continue if grouped_list != []: sorted_dict[k] = grouped_list else: sorted_dict[k] = group return sorted_dict 搜索。

答案 1 :(得分:1)

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

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

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

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

话虽如此,如果你没有进行交叉编译,这可能不是最明智的解决方案。