Issue
For my current CMake-project, i'm in need for the numpy/ndarrayobject.h
-library. At first the project didn't compile and complained about numpy/ndarrayobject.h
not being found in the include-path.
So what i did was sudo find / -type f -name 'ndarrayobject.h'
and it spit out:
/usr/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h
which i included in CMakeLists.txt
:
include_directories(/usr/lib/python3.8/site-packages/numpy/core/include/)
So, there is no actual error here. The project compiles and works as i expected it to. However, i think there must be a smarter way to find the directory. I have seen CMake-projects use
find_package(PythonLibs 3 REQUIRED)
find_package(OpenCV REQUIRED)
or something along these lines. So my initial thought is to learn about such macros to include the numpy
-directory a bit smarter.
What are those macros called? Where are they defined? Where can i learn about them? Does such a macro exist for the above mentioned directory?
Is this maybe the wrong approach and there is a cleaner way to find and include the above mentioned directory?
Solution
However, i think there must be a smarter way
Yes, you are right, and you are on the right track.
What are those macros called? Where are they defined? Where can i learn about them?
Those are called "find modules", and are usually located in (assuming Unix/Linux): /usr/local/share/cmake-<version>
. You can learn about them in the official documentation: https://cmake.org/cmake/help/v3.14/manual/cmake-developer.7.html#find-modules
However: The ability to find NumPy seems to have been added in CMake 3.14: https://cmake.org/cmake/help/v3.14/module/FindPython3.html.
So, assuming you are using CMake 3.14 or later, this should do the trick:
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})
Here we use FindPython3.cmake
, which exports a whole heap of variables related to Python, including the one you need: Python3_NumPy_INCLUDE_DIRS
.
Edit: As @Pedro correctly pointed out, you can also link to NumPy and get access to its include that way. This is actually preferable, since you may have to link to NumPy libraries anyway when building your application, and this saves you from having to issue two separate commands.
target_link_libraries(<your target> Python3::NumPy)
Now you can include said header: #include <numpy/ndarrayobject.h>
If you are unable to use CMake 3.14 or newer, you can consult the latest find modules to see how it's done and simply write your own module, or build the latest CMake from source (which is trivial).
Answered By - thomas_f