Skip to content

[BUG]: pybind11-config wrong include flags #3998

Open
@susnux

Description

@susnux

Required prerequisites

Problem description

After installing the project using cmake the pybind11-config program prints wrong include flags.

% pybind11-config --includes
-I/usr/include/python3.8 -I/usr/lib/python3.8/site-packages/include

The first part (python include directory) is ok, but the pybind11 include path is wrong, there is no /usr/lib/python3.8/site-packages/include.

The problem is this part:

return installed_path if os.path.exists(installed_path) else source_path

This only works for not-installed versions, as soon as you install the project using cmake the path is wrong.
Probably cmake should insert its installation path into that file after installation (using configure_file).

For me I fixed it using this patch:

diff -Nur pybind11-2.9.2/CMakeLists.txt new/CMakeLists.txt
--- pybind11-2.9.2/CMakeLists.txt	2022-03-31 05:12:13.000000000 +0200
+++ new/CMakeLists.txt	2022-06-08 11:59:32.704707307 +0200
@@ -206,6 +206,8 @@
   file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
 endif()
 
+configure_file(pybind11/_config.py.in ${CMAKE_CURRENT_SOURCE_DIR}/pybind11/_config.py @ONLY)
+
 if(PYBIND11_INSTALL)
   install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
   set(PYBIND11_CMAKECONFIG_INSTALL_DIR
diff -Nur pybind11-2.9.2/pybind11/commands.py new/pybind11/commands.py
--- pybind11-2.9.2/pybind11/commands.py	2022-03-31 05:12:13.000000000 +0200
+++ new/pybind11/commands.py	2022-06-08 12:01:48.677372043 +0200
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 import os
+from ._config import HEADER_DIR
 
 DIR = os.path.abspath(os.path.dirname(__file__))
 
@@ -8,7 +9,7 @@
     # type: (bool) -> str
     installed_path = os.path.join(DIR, "include")
     source_path = os.path.join(os.path.dirname(DIR), "include")
-    return installed_path if os.path.exists(installed_path) else source_path
+    return HEADER_DIR if os.path.exists(HEADER_DIR) else ( installed_path if os.path.exists(installed_path) else source_path )
 
 
 def get_cmake_dir():
diff -Nur pybind11-2.9.2/pybind11/_config.py.in new/pybind11/_config.py.in
--- pybind11-2.9.2/pybind11/_config.py.in	1970-01-01 01:00:00.000000000 +0100
+++ new/pybind11/_config.py.in	2022-06-08 11:46:25.876860701 +0200
@@ -0,0 +1 @@
+HEADER_DIR = "@CMAKE_INSTALL_FULL_INCLUDEDIR@/pybind11"
diff -Nur pybind11-2.9.2/tests/extra_python_package/test_files.py new/tests/extra_python_package/test_files.py
--- pybind11-2.9.2/tests/extra_python_package/test_files.py	2022-03-31 05:12:13.000000000 +0200
+++ new/tests/extra_python_package/test_files.py	2022-06-08 12:22:22.899405848 +0200
@@ -63,6 +63,7 @@
 py_files = {
     "__init__.py",
     "__main__.py",
+    "_config.py",
     "_version.py",
     "_version.pyi",
     "commands.py",

Reproducible example code

Simply install it using cmake and then use pybind11-config --include

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions