Skip to content

Commit 420a120

Browse files
committed
add installation support for pkg-config dependency detection
pkg-config is a buildsystem-agnostic alternative to `pybind11Config.cmake` that can be used from build systems other than cmake. Fixes #230
1 parent 59f03ee commit 420a120

9 files changed

+67
-2
lines changed

CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ else()
198198
endif()
199199

200200
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
201+
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake")
201202

202203
# Relative directory setting
203204
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
@@ -262,6 +263,16 @@ if(PYBIND11_INSTALL)
262263
NAMESPACE "pybind11::"
263264
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
264265

266+
# pkg-config support
267+
if(NOT prefix_for_pc_file)
268+
set(prefix_for_pc_file "${CMAKE_INSTALL_PREFIX}")
269+
endif()
270+
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
271+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in"
272+
"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc" @ONLY)
273+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
274+
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
275+
265276
# Uninstall target
266277
if(PYBIND11_MASTER_PROJECT)
267278
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"

pybind11/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66

77

88
from ._version import __version__, version_info
9-
from .commands import get_cmake_dir, get_include
9+
from .commands import get_cmake_dir, get_pkgconfig_dir, get_include
1010

1111
__all__ = (
1212
"version_info",
1313
"__version__",
1414
"get_include",
1515
"get_cmake_dir",
16+
"get_pkgconfig_dir",
1617
)

pybind11/__main__.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sys
55
import sysconfig
66

7-
from .commands import get_cmake_dir, get_include
7+
from .commands import get_cmake_dir, get_pkgconfig_dir, get_include
88

99

1010
def print_includes() -> None:
@@ -36,13 +36,20 @@ def main() -> None:
3636
action="store_true",
3737
help="Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.",
3838
)
39+
parser.add_argument(
40+
"--pkgconfigdir",
41+
action="store_true",
42+
help="Print the pkgconfig directory, ideal for setting $PKG_CONFIG_PATH.",
43+
)
3944
args = parser.parse_args()
4045
if not sys.argv[1:]:
4146
parser.print_help()
4247
if args.includes:
4348
print_includes()
4449
if args.cmakedir:
4550
print(get_cmake_dir())
51+
if args.pkgconfigdir:
52+
print(get_pkgconfig_dir())
4653

4754

4855
if __name__ == "__main__":

pybind11/commands.py

+11
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,14 @@ def get_cmake_dir() -> str:
2323

2424
msg = "pybind11 not installed, installation required to access the CMake files"
2525
raise ImportError(msg)
26+
27+
def get_pkgconfig_dir() -> str:
28+
"""
29+
Return the path to the pybind11 pkgconfig directory.
30+
"""
31+
pkgconfig_installed_path = os.path.join(DIR, "share", "pkgconfig")
32+
if os.path.exists(pkgconfig_installed_path):
33+
return pkgconfig_installed_path
34+
35+
msg = "pybind11 not installed, installation required to access the pkgconfig files"
36+
raise ImportError(msg)

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def remove_output(*sources: str) -> Iterator[None]:
127127
"-DCMAKE_INSTALL_PREFIX=pybind11",
128128
"-DBUILD_TESTING=OFF",
129129
"-DPYBIND11_NOPYTHON=ON",
130+
"-Dprefix_for_pc_file=${pcfiledir}/../../",
130131
]
131132
if "CMAKE_ARGS" in os.environ:
132133
fcommand = [

tools/JoinPaths.cmake

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This module provides function for joining paths
2+
# known from most languages
3+
#
4+
# SPDX-License-Identifier: (MIT OR CC0-1.0)
5+
# Copyright 2020 Jan Tojnar
6+
# https://github.com/jtojnar/cmake-snips
7+
#
8+
# Modelled after Python’s os.path.join
9+
# https://docs.python.org/3.7/library/os.path.html#os.path.join
10+
# Windows not supported
11+
function(join_paths joined_path first_path_segment)
12+
set(temp_path "${first_path_segment}")
13+
foreach(current_segment IN LISTS ARGN)
14+
if(NOT ("${current_segment}" STREQUAL ""))
15+
if(IS_ABSOLUTE "${current_segment}")
16+
set(temp_path "${current_segment}")
17+
else()
18+
set(temp_path "${temp_path}/${current_segment}")
19+
endif()
20+
endif()
21+
endforeach()
22+
set(${joined_path} "${temp_path}" PARENT_SCOPE)
23+
endfunction()

tools/pybind11.pc.in

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
prefix=@prefix_for_pc_file@
2+
includedir=@includedir_for_pc_file@
3+
4+
Name: @PROJECT_NAME@
5+
Description: Seamless operability between C++11 and Python
6+
Version: @PROJECT_VERSION@
7+
Cflags: -I${includedir}

tools/setup_global.py.in

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ main_headers = glob.glob("pybind11/include/pybind11/*.h")
2929
detail_headers = glob.glob("pybind11/include/pybind11/detail/*.h")
3030
stl_headers = glob.glob("pybind11/include/pybind11/stl/*.h")
3131
cmake_files = glob.glob("pybind11/share/cmake/pybind11/*.cmake")
32+
pkgconfig_files = glob.glob("pybind11/share/pkgconfig/*.pc")
3233
headers = main_headers + detail_headers + stl_headers
3334

3435
cmdclass = {"install_headers": InstallHeadersNested}
@@ -51,6 +52,7 @@ setup(
5152
headers=headers,
5253
data_files=[
5354
(base + "share/cmake/pybind11", cmake_files),
55+
(base + "share/pkgconfig", pkgconfig_files),
5456
(base + "include/pybind11", main_headers),
5557
(base + "include/pybind11/detail", detail_headers),
5658
(base + "include/pybind11/stl", stl_headers),

tools/setup_main.py.in

+2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ setup(
1717
"pybind11.include.pybind11.detail",
1818
"pybind11.include.pybind11.stl",
1919
"pybind11.share.cmake.pybind11",
20+
"pybind11.share.pkgconfig",
2021
],
2122
package_data={
2223
"pybind11": ["py.typed"],
2324
"pybind11.include.pybind11": ["*.h"],
2425
"pybind11.include.pybind11.detail": ["*.h"],
2526
"pybind11.include.pybind11.stl": ["*.h"],
2627
"pybind11.share.cmake.pybind11": ["*.cmake"],
28+
"pybind11.share.pkgconfig": ["*.pc"],
2729
},
2830
extras_require={
2931
"global": ["pybind11_global==$version"]

0 commit comments

Comments
 (0)