在 CMakeLists.txt 中包含目录的更好方法

Better way to include a directory in CMakeLists.txt

对于我当前的 CMake 项目,我需要 numpy/ndarrayobject.h-library。起初该项目没有编译并抱怨 numpy/ndarrayobject.h 在包含路径中找不到。

所以我所做的是 sudo find / -type f -name 'ndarrayobject.h' 然后它吐出:

/usr/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h

我包含在 CMakeLists.txt 中:

include_directories(/usr/lib/python3.8/site-packages/numpy/core/include/)

所以,这里没有实际错误。该项目按我预期的方式编译和工作。但是,我认为必须有一种更聪明的方法来查找目录。我见过 CMake 项目使用

find_package(PythonLibs 3 REQUIRED)
find_package(OpenCV REQUIRED)

或类似的东西。所以我最初的想法是了解这样的宏,以便更智能地包含 numpy-目录。

那些宏叫什么?它们在哪里定义?我在哪里可以了解它们?上述目录是否存在这样的宏?

这可能是错误的方法吗?有更简洁的方法来查找和包含上述目录吗?

However, i think there must be a smarter way

是的,你是对的,你走在正确的轨道上。

What are those macros called? Where are they defined? Where can i learn about them?

这些称为 "find modules",通常位于(假设 Unix/Linux):/usr/local/share/cmake-<version>。您可以在官方文档中了解它们:https://cmake.org/cmake/help/v3.14/manual/cmake-developer.7.html#find-modules

但是: CMake 3.14 中似乎已经添加了查找 NumPy 的功能: https://cmake.org/cmake/help/v3.14/module/FindPython3.html.

因此,假设您使用的是 CMake 3.14 或更高版本,这应该可以解决问题:

find_package(Python3 REQUIRED COMPONENTS NumPy)
# Use PUBLIC or INTERFACE scope if you need to
# propagate the include folder to dependents
target_include_directories(<your target> PRIVATE ${Python3_NumPy_INCLUDE_DIRS})

这里我们使用FindPython3.cmake,导出了一大堆与Python相关的变量,包括你需要的:Python3_NumPy_INCLUDE_DIRS.

编辑:正如@Pedro 正确指出的那样,您还可以link NumPy 并以这种方式访问​​其包含。 这实际上更可取,因为在构建应用程序时您可能不得不 link 使用 NumPy 库,这样您就不必发出两个单独的命令。

target_link_libraries(<your target> Python3::NumPy)

现在您可以包括 header: #include <numpy/ndarrayobject.h>

如果您无法使用 CMake 3.14 或更新版本,您可以查阅最新的 find modules 以了解它是如何完成的并简单地编写您自己的模块,或者从源代码构建最新的 CMake(这很简单) .