在CMake中查找目录

7

问题:

我想在我的构建中将boost numeric bindings添加为一个包含目录。它通常是这样编译的:

c++ -I/where/you/want/to/install/it/include/boost-numeric-bindings

我所引用的所有头文件都是相对于该目录的,因此在CMake中,我希望找到这个目录(无论其安装在父系统上的何处)并将其添加到include_directories

我的要求:

我需要像下面这样的内容:

find_directory(BNB_INCLUDE_DIR boost-numeric-bindings)

include_directories(${BNB_INCLUDE_DIR})

但是“find_directory”命令不存在。我错过了什么吗?

我尝试过的方法:

我尝试过:

find_path(BNB_INCLUDE_DIR boost/numeric/bindings/traits/ublas_vector.hpp)

include_directories(${BNB_INCLUDE_DIR})

(这是我从库中需要的第一个文件),但这给了我文件的完整路径,而不是指令中指定的文件前缀所在目录的路径。

1个回答

6

请参考这个答案,了解如何编写cmake Find文件。作为示例,以下是我为lm-sensors库编写的一个Find文件:

# - Try to find the LM_SENSORS library.
#
# The following are set after configuration is done: 
#  LM_SENSORS_FOUND
#  LM_SENSORS_INCLUDE_DIRS
#  LM_SENSORS_LIBRARY_DIRS
#  LM_SENSORS_LIBRARIES

find_path(LM_SENSORS_INCLUDE_DIR NAMES sensors/sensors.h)
find_library(LM_SENSORS_LIBRARY NAMES libsensors sensors)

message("LM_SENSORS include dir = ${LM_SENSORS_INCLUDE_DIR}")
message("LM_SENSORS lib = ${LM_SENSORS_LIBRARY}")

set(LM_SENSORS_LIBRARIES ${LM_SENSORS_LIBRARY})
set(LM_SENSORS_INCLUDE_DIRS ${LM_SENSORS_INCLUDE_DIR})

include(FindPackageHandleStandardArgs)
# Handle the QUIETLY and REQUIRED arguments and set the LM_SENSORS_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LM_SENSORS DEFAULT_MSG
                                  LM_SENSORS_LIBRARY LM_SENSORS_INCLUDE_DIR)

mark_as_advanced(LM_SENSORS_INCLUDE_DIR LM_SENSORS_LIBRARY)

将上述内容更改以匹配您的库(boost-numeric-bindings),将文件命名为Findboost-numeric-bindings.cmake,并将其放入cmake模块目录中(或在您的源代码树中创建一个模块目录)。

然后,在您的 CMakeLists.txt 文件中执行以下操作:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} your_cmake_module_dir)
find_package (boost-numeric-bindings REQUIRED)
include_directories(${BOOST_NUMERIC_BINDINGS_INCLUDE_DIR})

假设您没有将库安装在标准位置,请按照以下方式运行cmake:

cmake -D CMAKE_PREFIX_PATH:STRING="/where/you/have/installed/it/" <源代码路径>

注意

在调用find_pathfind_package之前,请确保已定义项目。否则,CMAKE_SYSTEM_INCLUDE_PATH将不会设置。例如:

find_path (BOOST_STATE_HPP boost/statechart/state.hpp)
message ("CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH}")
message ("CMAKE_SYSTEM_INCLUDE_PATH=${CMAKE_SYSTEM_INCLUDE_PATH}")
message ("CMAKE_SYSTEM_FRAMEWORK_PATH=${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message ("CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
message ("BOOST_STATE_HPP=${BOOST_STATE_HPP}")

project (my_project)

将导致以下cmake输出:
CMAKE_FIND_ROOT_PATH=
CMAKE_SYSTEM_INCLUDE_PATH=
CMAKE_SYSTEM_FRAMEWORK_PATH=
CMAKE_PREFIX_PATH=
BOOST_STATE_HPP=BOOST_STATE_HPP-NOTFOUND

相比之下:

project (my_project)

find_path (BOOST_STATE_HPP boost/statechart/state.hpp)
message ("CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH}")
message ("CMAKE_SYSTEM_INCLUDE_PATH=${CMAKE_SYSTEM_INCLUDE_PATH}")
message ("CMAKE_SYSTEM_FRAMEWORK_PATH=${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message ("CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
message ("BOOST_STATE_HPP=${BOOST_STATE_HPP}")

成功找到state.hpp并将BOOST_STATE_HPP设置为您所需的/usr/include,如下:

CMAKE_FIND_ROOT_PATH=
CMAKE_SYSTEM_INCLUDE_PATH=/usr/include/w32api;/usr/X11R6/include;/usr/include/X11;/usr/pkg/include;/opt/csw/include;/opt/include;/usr/openwin/include
CMAKE_SYSTEM_FRAMEWORK_PATH=
CMAKE_PREFIX_PATH=
BOOST_STATE_HPP=/usr/include

我可以想象在非标准安装中使用类似的东西,但通常(至少在Unix上)绑定是安装到/usr/local/include/boost-numeric-bindings。 如果CMake自动发现它是否在这里(或Windows的等效位置),那就太好了。 - Neal Kruis
如果CMake安装在标准位置,当你使用“find”命令时,它已经会自动查找。这样,当你运行CMake时就不需要指定“CMAKE_PREFIX_PATH”了。 - Patrick
抱歉,那很令人困惑... 该软件包的标准安装位置是/usr/local/include/boost-numeric-bindings,这不是标准的包含路径(例如/usr/local/include),因此构建系统不知道如何在不显式包含 boost-numeric-bindings 目录的情况下找到头文件。我希望有一种方法让CMake在标准位置中查找 boost-numeric-bindings 目录并返回该目录的完整路径。 - Neal Kruis
你的编辑中添加的内容与我之前尝试做的有什么不同吗?路径将被设置为/usr/local/include/boost-numeric-bindings/boost/numeric/bindings/traits/,而我想要的只是/usr/local/include/boost-numeric-bindings/。如果我错了,请纠正我。 - Neal Kruis
对我来说(cmake 2.8.10.2)它不起作用。如果使用任何搜索路径(请参阅man cmake中的find_path描述)找到文件作为前缀,则会将前缀设置为变量值。 - Patrick
哦,/usr/include 没有列在 CMAKE_SYSTEM_INCLUDE_PATH 中,所以它一定是从另一个 CMake 变量中获取的。不过似乎找不到那个变量是哪一个。 - Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接