1{ stdenv
2, lib
3, buildPythonPackage
4, pythonOlder
5, fetchFromGitHub
6, cmake
7, boost
8, eigen
9, python
10, catch
11, numpy
12, pytestCheckHook
13, libxcrypt
14, makeSetupHook
15, darwin
16}: let
17 setupHook = makeSetupHook {
18 name = "pybind11-setup-hook";
19 substitutions = {
20 out = placeholder "out";
21 pythonInterpreter = python.pythonForBuild.interpreter;
22 pythonIncludeDir = "${python}/include/python${python.pythonVersion}";
23 pythonSitePackages = "${python}/${python.sitePackages}";
24 };
25 } ./setup-hook.sh;
26
27 # clang 16 defaults to C++17, which results in the use of aligned allocations by pybind11.
28 # libc++ supports aligned allocations via `posix_memalign`, which is available since 10.6,
29 # but clang has a check hard-coded requiring 10.13 because that’s when Apple first shipped a
30 # support for C++17 aligned allocations on macOS.
31 # Tell clang we’re targeting 10.13 on x86_64-darwin while continuing to use the default SDK.
32 stdenv' = if stdenv.isDarwin && stdenv.isx86_64
33 then python.stdenv.override (oldStdenv: {
34 buildPlatform = oldStdenv.buildPlatform // { darwinMinVersion = "10.13"; };
35 targetPlatform = oldStdenv.targetPlatform // { darwinMinVersion = "10.13"; };
36 hostPlatform = oldStdenv.hostPlatform // { darwinMinVersion = "10.13"; };
37 })
38 else python.stdenv;
39in buildPythonPackage rec {
40 pname = "pybind11";
41 version = "2.11.1";
42
43 src = fetchFromGitHub {
44 owner = "pybind";
45 repo = pname;
46 rev = "v${version}";
47 hash = "sha256-sO/Fa+QrAKyq2EYyYMcjPrYI+bdJIrDoj6L3JHoDo3E=";
48 };
49
50 postPatch = ''
51 sed -i "/^timeout/d" pyproject.toml
52 '';
53
54 nativeBuildInputs = [ cmake ];
55 buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ];
56 propagatedBuildInputs = [ setupHook ];
57
58 stdenv = stdenv';
59
60 dontUseCmakeBuildDir = true;
61
62 # Don't build tests if not needed, read the doInstallCheck value at runtime
63 preConfigure = ''
64 if [ -n "$doInstallCheck" ]; then
65 cmakeFlagsArray+=("-DBUILD_TESTING=ON")
66 fi
67 '';
68
69 cmakeFlags = [
70 "-DBoost_INCLUDE_DIR=${lib.getDev boost}/include"
71 "-DEIGEN3_INCLUDE_DIR=${lib.getDev eigen}/include/eigen3"
72 ] ++ lib.optionals (python.isPy3k && !stdenv.cc.isClang) [
73 "-DPYBIND11_CXX_STANDARD=-std=c++17"
74 ];
75
76 postBuild = ''
77 # build tests
78 make -j $NIX_BUILD_CORES
79 '';
80
81 postInstall = ''
82 make install
83 # Symlink the CMake-installed headers to the location expected by setuptools
84 mkdir -p $out/include/${python.libPrefix}
85 ln -sf $out/include/pybind11 $out/include/${python.libPrefix}/pybind11
86 '';
87
88 nativeCheckInputs = [
89 catch
90 numpy
91 pytestCheckHook
92 ];
93
94 disabledTestPaths = [
95 # require dependencies not available in nixpkgs
96 "tests/test_embed/test_trampoline.py"
97 "tests/test_embed/test_interpreter.py"
98 # numpy changed __repr__ output of numpy dtypes
99 "tests/test_numpy_dtypes.py"
100 # no need to test internal packaging
101 "tests/extra_python_package/test_files.py"
102 # tests that try to parse setuptools stdout
103 "tests/extra_setuptools/test_setuphelper.py"
104 ];
105
106 disabledTests = lib.optionals stdenv.isDarwin [
107 # expects KeyError, gets RuntimeError
108 # https://github.com/pybind/pybind11/issues/4243
109 "test_cross_module_exception_translator"
110 ];
111
112 hardeningDisable = lib.optional stdenv.hostPlatform.isMusl "fortify";
113
114 meta = with lib; {
115 homepage = "https://github.com/pybind/pybind11";
116 changelog = "https://github.com/pybind/pybind11/blob/${src.rev}/docs/changelog.rst";
117 description = "Seamless operability between C++11 and Python";
118 longDescription = ''
119 Pybind11 is a lightweight header-only library that exposes
120 C++ types in Python and vice versa, mainly to create Python
121 bindings of existing C++ code.
122 '';
123 license = licenses.bsd3;
124 maintainers = with maintainers; [ yuriaisaka dotlambda ];
125 };
126}