How to make cmake find pybind11
Asked Answered
F

6

17

I am trying to follow the simple example for embedding python within c++ using pybind11 as found on this page. However, when trying to use cmake to build the solution, I keep getting an error that says

By not providing "Findpybind11.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "pybind11", but CMake did not find one.

Could not find a package configuration file provided by "pybind11" with any of the following names:

pybind11Config.cmake
pybind11-config.cmake

I have a folder called pybindtest on my Desktop which includes CMakeLists.txt and main.cpp as described in the link above, as well as a build folder that I created. While in the build folder, I have tried the following lines to no avail (running on Powershell 7):

cmake ..
cmake .. -Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/pybind11Config.cmake
cmake .. -DCMAKE_MODULE_PATH=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11

I installed pybind11 using conda install pybind11, and pybind11Config.cmake is in C:\Users\ben.wolfley\Anaconda3\Library\share\cmake\pybind11

Flyblow answered 4/8, 2020 at 20:26 Comment(3)
If you try using the cmakegui, there should be a variable called pybind11_DIR or something. Can you try to set it to the *.cmake dir and try again?Indiscipline
Or I think you were supposed to set the CMAKE_PREFIX_PATH and not the CMAKE_MODULE_PATHIndiscipline
"... and pybind11Config.cmake is in C:\Users\ben.wolfley\Anaconda3\Library\share\cmake\pybind11" - So set pybind11_DIR variable to that directory as the error message suggests (not to the file in it, as you currently set).Man
P
20

In case someone having the same issue without Anaconda, like directly with pip pybind11 or manual clone installation, both caused problems in my case. Manual installation of pybind11 with git didn't install the cmake config pybind11Config.cmake, although there is a tools/pybind11Config.cmake.in file, that I couldn't turn into a proper pybind11Config.cmake.

Installation pybind11 global with pip solved it for me, and automatically uninstalled the manual git installation:

pip install "pybind11[global]"

which installed both pybind11 and pybind11-global with proper cmake config like Anaconda does.

Python answered 18/12, 2021 at 12:10 Comment(0)
V
3

Add following to CMakeLists.txt:

# set pybind11 dir
set(pybind11_DIR /Users/Caleb/Softwares/pybind11)
find_package(pybind11 REQUIRED)
Vendace answered 19/10, 2021 at 6:50 Comment(2)
Thanks, this really helped. For future help seekers: For me [using Ubuntu 22.04, Python 3.10], the pybind11 directory was located at: /usr/local/lib/python3.10/dist-packages/ You can find out your PyBind11 directory via CMD line: Type "python -v" to enter the Python console --> detailed information on all loaded packages will be given. Then, within the Python console, just use "import pybind11", and in the first output line you should see the storage location for pybind11. Hope that helps!Romine
For those who installed pybind11 with PyPI, you need to either set full directory all the way to '.cmake' files by set(pybind11_DIR python_env/site-packages/pybind11/share/cmake/pybind11) or find packages in config mode by find_package(pybind11 REQUIRED CONFIG).Contemptuous
F
2

Thanks to Tsyvarev for pointing me in the right direction. The following command worked:

cmake .. -G "Visual Studio 15 2017" -A x64 `
      -Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/

I was pointing to the .cmake file instead of the file's directory. I also had to specify the compiler in order for the code to work.

Flyblow answered 4/8, 2020 at 21:29 Comment(0)
M
2

In my case, Ubuntu 22.04 LTS, python 3.10

pip install pybind11

or

pip3 install pybind11

this command will install at your local lib, bin path under /home so, you can find .cmake files as the below path

/home/your_account/.local/lib/python3.10/site-packages/pybind11/share/cmake/pybind11

edit CMakeLists.txt

set(pybind11_DIR /home/your_account/.local/lib/python3.10/site-packages/pybind11/share/cmake/pybind11)

find_package(pybind11 REQUIRED)
Malignant answered 19/2 at 11:27 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Nonfulfillment
This worked for me, but I still don't see why the pybind11 package needed to be installed from PyPi when the pybind11-dev deb package was already installed and had the exact same files. Something in how CMake is looking for pybind11 isn't right.Turgot
T
0

I followed this tutorial to get started with pybind11: https://www.blopig.com/blog/2021/03/c-python-bindings-in-5-minutes/ That works VERY easily, and doesn't require having a CMake script all at.

But... I wanted to edit my code from within my IDE of choice (Qt Creator), and have that provide intellisense for me and whatnot. As such, I added CMake to the project for that benefit (Qt Creator can lean on it).

So, to get my IDE to simply not complain about missing includes (and to even compile the code if I want - though not actually build the whole pybind wrapper), all I needed to do was add a couple of include paths. In my environment, they were as follows:

include_directories(/usr/include/python3.6m)
include_directories(/home/johndoe/.local/lib/python3.6/site-packages/pybind11/include)

That, of course, is not portable. So to address that, I dropped in a macro which would allow me to implement a better solution using environmental variables:

macro(include_envvar_directory varname)
    if(DEFINED ENV{${varname}})
        set(dir_path $ENV{${varname}})
    else()
        message(FATAL_ERROR "ERROR: Env var ${varname} must be defined!")
    endif()
    if(NOT EXISTS ${dir_path})
        message(FATAL_ERROR
            "ERROR: Invalid path: ${dir_path} specified by env var: ${varname}")
    endif()
    message(STATUS "Adding to include path: ${dir_path}")
    include_directories(${dir_path})
endmacro()

include_envvar_directory(PY_INCLUDE_PATH)
include_envvar_directory(PYBIND_INCLUDE_PATH)

With that in place, I passed the PY_INCLUDE_PATH and PYBIND_INCLUDE_PATH env vars to the CMake via the IDE's feature to define such per project / workstation.

Triboelectricity answered 14/7, 2023 at 21:3 Comment(0)
V
0

the command

pip install pybind11

doesn't install the pybing11Config.cmake file in your system path,so CMAKE couldn't find it;but it does installed the file at the /path/to/the/python/env/python_version/lib/site-packages/pybind11/share/cmake/pybind11,in my case,is:

/home/run/miniconda3/envs/py311/lib/python3.11/site-packages/pybind11/share/cmake/pybind11

I recommend that you temporary add that path to CMAKE_PREFIX_PATH:

export CMAKE_PREFIX_PATH=/home/run/miniconda3/envs/py311/lib/python3.11/site-packages/pybind11/share/cmake/pybind11:$CMAKE_PREFIX_PATH

by adding this, CMAKE can find pybing11,and CMakeCache.txt will remember it, so that you haven't need to add the line every time.

Viscoid answered 14/8 at 12:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.