From fb236b375f662801c22d98f1fa7c0e879de12de2 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Tue, 21 Oct 2025 13:17:53 +0300 Subject: [PATCH 1/5] Revert "abseil-cpp_202505: drop" This reverts commit 7559006efc5254e8e096084fd8dd349306430acd. It is needed for the current or-tools release, 9.14: https://github.com/google/or-tools/blob/93dafb79a0261b5211f4eb17437aeebd7f45e543/MODULE.bazel#L16 --- pkgs/by-name/ab/abseil-cpp_202505/package.nix | 45 +++++++++++++++++++ pkgs/top-level/aliases.nix | 1 - 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 pkgs/by-name/ab/abseil-cpp_202505/package.nix diff --git a/pkgs/by-name/ab/abseil-cpp_202505/package.nix b/pkgs/by-name/ab/abseil-cpp_202505/package.nix new file mode 100644 index 000000000000..c1884d4a953d --- /dev/null +++ b/pkgs/by-name/ab/abseil-cpp_202505/package.nix @@ -0,0 +1,45 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + gtest, + static ? stdenv.hostPlatform.isStatic, + cxxStandard ? null, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "abseil-cpp"; + version = "20250512.1"; + + src = fetchFromGitHub { + owner = "abseil"; + repo = "abseil-cpp"; + tag = finalAttrs.version; + hash = "sha256-eB7OqTO9Vwts9nYQ/Mdq0Ds4T1KgmmpYdzU09VPWOhk="; + }; + + cmakeFlags = [ + (lib.cmakeBool "ABSL_BUILD_TEST_HELPERS" true) + (lib.cmakeBool "ABSL_USE_EXTERNAL_GOOGLETEST" true) + (lib.cmakeBool "BUILD_SHARED_LIBS" (!static)) + ] + ++ lib.optionals (cxxStandard != null) [ + (lib.cmakeFeature "CMAKE_CXX_STANDARD" cxxStandard) + ]; + + strictDeps = true; + + nativeBuildInputs = [ cmake ]; + + buildInputs = [ gtest ]; + + meta = { + description = "Open-source collection of C++ code designed to augment the C++ standard library"; + homepage = "https://abseil.io/"; + changelog = "https://github.com/abseil/abseil-cpp/releases/tag/${finalAttrs.version}"; + license = lib.licenses.asl20; + platforms = lib.platforms.all; + maintainers = [ lib.maintainers.GaetanLepage ]; + }; +}) diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 61b6b6f12bdd..6d5348c9f90d 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -268,7 +268,6 @@ mapAliases { a4term = throw "'a4term' has been renamed to/replaced by 'a4'"; # Converted to throw 2025-10-27 abseil-cpp_202301 = throw "abseil-cpp_202301 has been removed as it was unused in tree"; # Added 2025-08-09 abseil-cpp_202501 = throw "abseil-cpp_202501 has been removed as it was unused in tree"; # Added 2025-09-15 - abseil-cpp_202505 = throw "abseil-cpp_202505 has been removed as it was unused in tree"; # Added 2025-09-15 adminer-pematon = throw "'adminer-pematon' has been renamed to/replaced by 'adminneo'"; # Converted to throw 2025-10-27 adminerneo = throw "'adminerneo' has been renamed to/replaced by 'adminneo'"; # Converted to throw 2025-10-27 adobe-reader = throw "'adobe-reader' has been removed, as it was broken, outdated and insecure"; # added 2025-05-31 From 003d9f75c47842ea5c669cb219235d3fd5718eb2 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Tue, 21 Oct 2025 14:54:56 +0300 Subject: [PATCH 2/5] or-tools: move pybind11-protobuf package into or-tools or-tools is the only consumer of this library, and 1910563bb3c0a76aae035d578a8c094c5646baa7 is already one instance of the toplevel build being broken. Absorb pybind11-protobuf into or-tools, and manage the pinning there. It will also make it much easier to do the upcoming or-tools bump, which will also change these version bounds. pybind11-protobuf is not actually packaged in the version that or-tools asks for, but trying to use that version showed it wants abseil from 2023, which has been removed from nixpkgs. --- .../add-install-target-for-cmake-builds.patch | 0 pkgs/by-name/or/or-tools/package.nix | 10 +++++++--- .../or/or-tools/pybind11-protobuf.nix} | 2 +- pkgs/top-level/python-aliases.nix | 1 + pkgs/top-level/python-packages.nix | 2 -- 5 files changed, 9 insertions(+), 6 deletions(-) rename pkgs/{development/python-modules/pybind11-protobuf => by-name/or/or-tools}/add-install-target-for-cmake-builds.patch (100%) rename pkgs/{development/python-modules/pybind11-protobuf/default.nix => by-name/or/or-tools/pybind11-protobuf.nix} (95%) diff --git a/pkgs/development/python-modules/pybind11-protobuf/add-install-target-for-cmake-builds.patch b/pkgs/by-name/or/or-tools/add-install-target-for-cmake-builds.patch similarity index 100% rename from pkgs/development/python-modules/pybind11-protobuf/add-install-target-for-cmake-builds.patch rename to pkgs/by-name/or/or-tools/add-install-target-for-cmake-builds.patch diff --git a/pkgs/by-name/or/or-tools/package.nix b/pkgs/by-name/or/or-tools/package.nix index c8e9ba327ff1..da905c1f4a5d 100644 --- a/pkgs/by-name/or/or-tools/package.nix +++ b/pkgs/by-name/or/or-tools/package.nix @@ -1,4 +1,8 @@ { + stdenv, + lib, + callPackage, + abseil-cpp_202407, bzip2, cbc, @@ -11,12 +15,10 @@ gbenchmark, glpk, highs, - lib, pkg-config, protobuf_29, python3, re2, - stdenv, swig, unzip, zlib, @@ -33,7 +35,9 @@ let abseil-cpp = abseil-cpp_202407; protobuf = protobuf_29.override { inherit abseil-cpp; }; python-protobuf = python3.pkgs.protobuf5.override { inherit protobuf; }; - pybind11-protobuf = python3.pkgs.pybind11-protobuf.override { protobuf_29 = protobuf; }; + pybind11-protobuf = callPackage ./pybind11-protobuf.nix { + inherit (python3.pkgs) buildPythonPackage pybind11; + }; # local revert of 58daf511687f191829238fc7f571e08dc9dedf56, # working around https://github.com/google/or-tools/issues/4911 diff --git a/pkgs/development/python-modules/pybind11-protobuf/default.nix b/pkgs/by-name/or/or-tools/pybind11-protobuf.nix similarity index 95% rename from pkgs/development/python-modules/pybind11-protobuf/default.nix rename to pkgs/by-name/or/or-tools/pybind11-protobuf.nix index eb7c0aa0b072..b6074d995f32 100644 --- a/pkgs/development/python-modules/pybind11-protobuf/default.nix +++ b/pkgs/by-name/or/or-tools/pybind11-protobuf.nix @@ -4,7 +4,7 @@ buildPythonPackage, fetchFromGitHub, cmake, - abseil-cpp_202407, # downgrade, same reason as toplevel protobuf_29 + abseil-cpp_202407, protobuf_29, pybind11, zlib, diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix index 7cf00fbaa665..860ccf50c2db 100644 --- a/pkgs/top-level/python-aliases.nix +++ b/pkgs/top-level/python-aliases.nix @@ -310,6 +310,7 @@ mapAliases { py-eth-sig-utils = throw "py-eth-sig-utils has been removed because it has been marked as broken since at least November 2024."; # Added 2025-10-04 py-scrypt = scrypt; # added 2025-08-07 py_stringmatching = throw "'py_stringmatching' has been renamed to/replaced by 'py-stringmatching'"; # Converted to throw 2025-10-29 + pybind11-protobuf = throw "'pybind11-protobuf' was only used by or-tools, and with some overrides, so vendored in there until it's used in other places."; # Converted to throw 2025-11-06 pycategories = throw "'pycategories' has been removed as it was broken and unmaintained"; # added 2025-11-08 PyChromecast = throw "'PyChromecast' has been renamed to/replaced by 'pychromecast'"; # Converted to throw 2025-10-29 pydns = throw "'pydns' has been renamed to/replaced by 'py3dns'"; # Converted to throw 2025-10-29 diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 99e66e842b76..be47cdf5a250 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -12766,8 +12766,6 @@ self: super: with self; { pybind11-abseil = callPackage ../development/python-modules/pybind11-abseil { }; - pybind11-protobuf = callPackage ../development/python-modules/pybind11-protobuf { }; - pybind11-stubgen = callPackage ../development/python-modules/pybind11-stubgen { }; pybindgen = callPackage ../development/python-modules/pybindgen { }; From 08ce3cc377601b54324822c05dd793fa0d8d6cd4 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Tue, 21 Oct 2025 16:20:35 +0300 Subject: [PATCH 3/5] or-tools: 9.12 -> 9.14 Some of the patches we ship(ed) had to be regenerated. or-tools now uses abseil-cpp_202505, and we need to ensure everything uses that, to avoid another version of abseil leaking into the build. pybind11 needs to be downgraded to 2.13.6 (I vendored the old nixpkgs expression for that). pybind11 also needs to be patched to fix math_opt's elemental python binding. or-tools ships this in their repo as a patch to their pybind11_bazel dep, including a patch file there. I decided to pop one layer of patching, and vendor the patch in here. Upstream also patches their scipopts-scip dependency, renaming some CMake targets, so we need to patch our dependency as well (and restore find_package() discovery that broke). --- ...py-pybind11_abseil-status-extension-.patch | 31 +- ...CMake-rules-for-bundled-pybind-stuff.patch | 26 + pkgs/by-name/or/or-tools/package.nix | 66 ++- pkgs/by-name/or/or-tools/pybind11-2.13.6.nix | 131 +++++ .../by-name/or/or-tools/pybind11-protobuf.nix | 19 +- .../or/or-tools/pybind11-setup-hook.sh | 12 + pkgs/by-name/or/or-tools/pybind11.patch | 452 ++++++++++++++++++ pkgs/by-name/or/or-tools/scip.patch | 145 ++++++ 8 files changed, 852 insertions(+), 30 deletions(-) create mode 100644 pkgs/by-name/or/or-tools/0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch create mode 100644 pkgs/by-name/or/or-tools/pybind11-2.13.6.nix create mode 100644 pkgs/by-name/or/or-tools/pybind11-setup-hook.sh create mode 100644 pkgs/by-name/or/or-tools/pybind11.patch create mode 100644 pkgs/by-name/or/or-tools/scip.patch diff --git a/pkgs/by-name/or/or-tools/0001-Do-not-try-to-copy-pybind11_abseil-status-extension-.patch b/pkgs/by-name/or/or-tools/0001-Do-not-try-to-copy-pybind11_abseil-status-extension-.patch index b3529481eb8e..519c775ad4af 100644 --- a/pkgs/by-name/or/or-tools/0001-Do-not-try-to-copy-pybind11_abseil-status-extension-.patch +++ b/pkgs/by-name/or/or-tools/0001-Do-not-try-to-copy-pybind11_abseil-status-extension-.patch @@ -1,6 +1,20 @@ +From 077295f6ede59d9e2413b2d19f38cf63b64f4fec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Tue, 21 Oct 2025 17:05:59 +0300 +Subject: [PATCH] Do not try to copy pybind11_abseil status extension module + +The module is already installed in the correct location. And even if not, +it should be done as part of the pybind11_abseil build ... +--- + cmake/python.cmake | 5 ----- + ortools/python/setup.py.in | 4 ---- + 2 files changed, 9 deletions(-) + +diff --git a/cmake/python.cmake b/cmake/python.cmake +index 2112ceeb66..db15434303 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake -@@ -322,7 +322,6 @@ +@@ -326,7 +326,6 @@ file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/init/python/__init__.py CONTENT "") file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/linear_solver/__init__.py CONTENT "") file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/linear_solver/python/__init__.py CONTENT "") if(BUILD_MATH_OPT) @@ -8,17 +22,17 @@ file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/math_opt/__init__.py CONTENT "") file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/math_opt/core/__init__.py CONTENT "") file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/math_opt/core/python/__init__.py CONTENT "") -@@ -635,9 +634,6 @@ +@@ -680,9 +679,6 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E $,copy,true> - $ ${PYTHON_PROJECT}/math_opt/core/python + $ ${PYTHON_PROJECT}/math_opt/io/python - COMMAND ${CMAKE_COMMAND} -E - $,copy,true> - $ ${PYTHON_PROJECT}/../pybind11_abseil COMMAND ${CMAKE_COMMAND} -E $,copy,true> $<$:$> ${PYTHON_PROJECT}/pdlp/python -@@ -696,7 +692,6 @@ +@@ -744,7 +740,6 @@ add_custom_command( COMMAND ${stubgen_EXECUTABLE} -p ortools.constraint_solver.pywrapcp --output . COMMAND ${stubgen_EXECUTABLE} -p ortools.linear_solver.pywraplp --output . COMMAND ${stubgen_EXECUTABLE} -p ortools.linear_solver.python.model_builder_helper --output . @@ -26,9 +40,11 @@ COMMAND ${stubgen_EXECUTABLE} -p ortools.math_opt.core.python.solver --output . COMMAND ${stubgen_EXECUTABLE} -p ortools.pdlp.python.pdlp --output . COMMAND ${stubgen_EXECUTABLE} -p ortools.sat.python.cp_model_helper --output . +diff --git a/ortools/python/setup.py.in b/ortools/python/setup.py.in +index 0aeaa900ef..ae4fa07815 100644 --- a/ortools/python/setup.py.in +++ b/ortools/python/setup.py.in -@@ -83,10 +83,6 @@ +@@ -83,10 +83,6 @@ setup( '*.pyi', 'py.typed' ], @@ -37,5 +53,8 @@ - '*.pyi' - ], '@PYTHON_PROJECT@.math_opt':['*.pyi'], + '@PYTHON_PROJECT@.math_opt.python':['*.pyi'], '@PYTHON_PROJECT@.math_opt.core.python':[ - '$', +-- +2.51.0 + diff --git a/pkgs/by-name/or/or-tools/0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch b/pkgs/by-name/or/or-tools/0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch new file mode 100644 index 000000000000..568740bd32fd --- /dev/null +++ b/pkgs/by-name/or/or-tools/0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch @@ -0,0 +1,26 @@ +From 46e7d2cccd029a2c4215ce9b0c3bf72b2f2dd398 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Thu, 2 Jan 2025 16:32:05 +0100 +Subject: [PATCH] Fix up broken CMake rules for bundled pybind stuff + +Unfortunately, upstream only uses and tests the bundled code, and the +unbundled cases are bitrotting. +--- + cmake/system_deps.cmake | 1 + + 1 files changed, 1 insertion(+) + +diff --git a/cmake/system_deps.cmake b/cmake/system_deps.cmake +index d9ae923..0c176a8 100644 +--- a/cmake/system_deps.cmake ++++ b/cmake/system_deps.cmake +@@ -94,6 +94,7 @@ endif() + + # Check language Dependencies + if(BUILD_PYTHON) ++ find_package(Python REQUIRED Interpreter Development.Module) + if(NOT BUILD_pybind11 AND NOT TARGET pybind11::pybind11_headers) + find_package(pybind11 REQUIRED) + endif() +-- +2.47.1 + diff --git a/pkgs/by-name/or/or-tools/package.nix b/pkgs/by-name/or/or-tools/package.nix index da905c1f4a5d..c7a98e080546 100644 --- a/pkgs/by-name/or/or-tools/package.nix +++ b/pkgs/by-name/or/or-tools/package.nix @@ -3,7 +3,7 @@ lib, callPackage, - abseil-cpp_202407, + abseil-cpp_202505, bzip2, cbc, cmake, @@ -16,7 +16,7 @@ glpk, highs, pkg-config, - protobuf_29, + protobuf_31, python3, re2, swig, @@ -32,12 +32,45 @@ let # protobuf. Do not un-pin these, even if you're upgrading them to # what might happen to be the latest version at the current moment; # future upgrades *will* break the build. - abseil-cpp = abseil-cpp_202407; - protobuf = protobuf_29.override { inherit abseil-cpp; }; + abseil-cpp = abseil-cpp_202505; + protobuf = protobuf_31.override { inherit abseil-cpp; }; python-protobuf = python3.pkgs.protobuf5.override { inherit protobuf; }; - pybind11-protobuf = callPackage ./pybind11-protobuf.nix { - inherit (python3.pkgs) buildPythonPackage pybind11; + + pybind11 = callPackage ./pybind11-2.13.6.nix { + inherit (python3.pkgs) + buildPythonPackage + cmake + ninja + numpy + pytestCheckHook + pythonOlder + setuptools + ; + python = python3; }; + pybind11-abseil = python3.pkgs.pybind11-abseil.override { + inherit abseil-cpp pybind11; + }; + pybind11-protobuf = callPackage ./pybind11-protobuf.nix { + inherit (python3.pkgs) buildPythonPackage; + inherit pybind11; + }; + # re2 must also use the same abseil version, else these two versions will conflict during linking + _re2 = re2.override { inherit abseil-cpp; }; + + # 77a28070b9c4c83995ac6bbfa9544722ff3342ce renamed the scip cmake target(s) differently + # to what upstream still calls it. Apply this patch to scipopt-scip. + _scipopt-scip = scipopt-scip.overrideAttrs (old: { + patches = old.patches or [ ] ++ [ + # from https://github.com/google/or-tools/commit/77a28070b9c4c83995ac6bbfa9544722ff3342ce#diff-c95174a817e73db366d414af1e329c1856f70e5158ed3994d43da88765ccc98f + ./scip.patch + ]; + # Their patch forgets to find_package() soplex, bring it back. + postPatch = (old.postPatch or "") + '' + substituteInPlace CMakeLists.txt \ + --replace-fail 'message(STATUS "Finding Soplex...")' 'find_package(SOPLEX CONFIG HINTS ''${SOPLEX_DIR})' + ''; + }); # local revert of 58daf511687f191829238fc7f571e08dc9dedf56, # working around https://github.com/google/or-tools/issues/4911 @@ -61,13 +94,13 @@ let in stdenv.mkDerivation (finalAttrs: { pname = "or-tools"; - version = "9.12"; + version = "9.14"; src = fetchFromGitHub { owner = "google"; repo = "or-tools"; tag = "v${finalAttrs.version}"; - hash = "sha256-5rFeAK51+BfjIyu/5f5ptaKMD7Hd20yHa2Vj3O3PkLU="; + hash = "sha256-FxKe3uY4L33mavwC2aanji3fY9dPqpkwVqi6PNjovSA="; }; patches = [ @@ -78,11 +111,7 @@ stdenv.mkDerivation (finalAttrs: { url = "https://build.opensuse.org/public/source/science/google-or-tools/0001-Revert-python-Fix-python-install-on-windows-breaks-L.patch?rev=19"; hash = "sha256-BNB3KlgjpWcZtb9e68Jkc/4xC4K0c+Iisw0eS6ltYXE="; }) - (fetchpatch { - name = "0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch"; - url = "https://build.opensuse.org/public/source/science/google-or-tools/0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch?rev=19"; - hash = "sha256-r38ZbRkEW1ZvJb0Uf56c0+HcnfouZZJeEYlIK7quSjQ="; - }) + ./0001-Fix-up-broken-CMake-rules-for-bundled-pybind-stuff.patch (fetchpatch { name = "math_opt-only-run-SCIP-tests-if-enabled.patch"; url = "https://github.com/google/or-tools/commit/b5a2f8ac40dd4bfa4359c35570733171454ec72b.patch"; @@ -112,6 +141,8 @@ stdenv.mkDerivation (finalAttrs: { (lib.cmakeFeature "CMAKE_INSTALL_INCLUDEDIR" "include") (lib.cmakeFeature "CMAKE_INSTALL_LIBDIR" "lib") (lib.cmakeBool "FETCH_PYTHON_DEPS" false) + # not packaged in nixpkgs + (lib.cmakeBool "USE_fuzztest" false) (lib.cmakeBool "USE_GLPK" true) (lib.cmakeBool "USE_SCIP" withScip) (lib.cmakeFeature "Python3_EXECUTABLE" "${python3.pythonOnBuildForHost.interpreter}") @@ -149,14 +180,14 @@ stdenv.mkDerivation (finalAttrs: { gtest _highs python3.pkgs.absl-py - python3.pkgs.pybind11 - python3.pkgs.pybind11-abseil + pybind11 + pybind11-abseil pybind11-protobuf python3.pkgs.pytest python3.pkgs.scipy python3.pkgs.setuptools python3.pkgs.wheel - re2 + _re2 zlib ]; propagatedBuildInputs = [ @@ -170,7 +201,7 @@ stdenv.mkDerivation (finalAttrs: { ] ++ lib.optionals withScip [ # Needed for downstream cmake consumers to not need to set SCIP_ROOT explicitly - scipopt-scip + _scipopt-scip ]; nativeCheckInputs = [ @@ -183,6 +214,7 @@ stdenv.mkDerivation (finalAttrs: { ]; # some tests fail on aarch64-linux and hang on darwin + # https://github.com/google/or-tools/issues/4746 doCheck = stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform.isLinux; preCheck = '' diff --git a/pkgs/by-name/or/or-tools/pybind11-2.13.6.nix b/pkgs/by-name/or/or-tools/pybind11-2.13.6.nix new file mode 100644 index 000000000000..048ed89f5632 --- /dev/null +++ b/pkgs/by-name/or/or-tools/pybind11-2.13.6.nix @@ -0,0 +1,131 @@ +# This is pybind11 2.13.6 from an earlier nixpkgs version, with the +# parts from https://github.com/google/or-tools/commit/7f29b27840436e19b6530d5c7f23eeadd819bd3e +# applied. +{ + stdenv, + lib, + buildPythonPackage, + pythonOlder, + fetchFromGitHub, + cmake, + ninja, + setuptools, + boost, + eigen, + python, + catch2, + numpy, + pytestCheckHook, + libxcrypt, + makeSetupHook, +}: +let + setupHook = makeSetupHook { + name = "pybind11-setup-hook"; + substitutions = { + out = placeholder "out"; + pythonInterpreter = python.pythonOnBuildForHost.interpreter; + pythonIncludeDir = "${python}/include/python${python.pythonVersion}"; + pythonSitePackages = "${python}/${python.sitePackages}"; + }; + } ./pybind11-setup-hook.sh; +in +buildPythonPackage rec { + pname = "pybind11"; + version = "2.13.6"; + pyproject = true; + + src = fetchFromGitHub { + owner = "pybind"; + repo = "pybind11"; + tag = "v${version}"; + hash = "sha256-SNLdtrOjaC3lGHN9MAqTf51U9EzNKQLyTMNPe0GcdrU="; + }; + + # https://github.com/google/or-tools/commit/7f29b27840436e19b6530d5c7f23eeadd819bd3e + patches = [ ./pybind11.patch ]; + + build-system = [ + cmake + ninja + setuptools + ]; + + buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ]; + propagatedNativeBuildInputs = [ setupHook ]; + + dontUseCmakeBuildDir = true; + + # Don't build tests if not needed, read the doInstallCheck value at runtime + preConfigure = '' + if [ -n "$doInstallCheck" ]; then + cmakeFlagsArray+=("-DBUILD_TESTING=ON") + fi + ''; + + cmakeFlags = [ + "-DBoost_INCLUDE_DIR=${lib.getDev boost}/include" + "-DCATCH_INCLUDE_DIR=${lib.getDev catch2}/include/catch2" + "-DEIGEN3_INCLUDE_DIR=${lib.getDev eigen}/include/eigen3" + ] + ++ lib.optionals (python.isPy3k && !stdenv.cc.isClang) [ "-DPYBIND11_CXX_STANDARD=-std=c++17" ]; + + postBuild = '' + # build tests + make -j $NIX_BUILD_CORES + ''; + + postInstall = '' + make install + # Symlink the CMake-installed headers to the location expected by setuptools + mkdir -p $out/include/${python.libPrefix} + ln -sf $out/include/pybind11 $out/include/${python.libPrefix}/pybind11 + ''; + + nativeCheckInputs = [ + catch2 + numpy + pytestCheckHook + ]; + + disabledTestPaths = [ + # require dependencies not available in nixpkgs + "tests/test_embed/test_trampoline.py" + "tests/test_embed/test_interpreter.py" + # numpy changed __repr__ output of numpy dtypes + "tests/test_numpy_dtypes.py" + # no need to test internal packaging + "tests/extra_python_package/test_files.py" + # tests that try to parse setuptools stdout + "tests/extra_setuptools/test_setuphelper.py" + ]; + + disabledTests = lib.optionals stdenv.hostPlatform.isDarwin [ + # expects KeyError, gets RuntimeError + # https://github.com/pybind/pybind11/issues/4243 + "test_cross_module_exception_translator" + ]; + + postCheck = '' + make cpptest + ''; + + hardeningDisable = lib.optional stdenv.hostPlatform.isMusl "fortify"; + + meta = { + homepage = "https://github.com/pybind/pybind11"; + changelog = "https://github.com/pybind/pybind11/blob/${src.rev}/docs/changelog.rst"; + description = "Seamless operability between C++11 and Python"; + mainProgram = "pybind11-config"; + longDescription = '' + Pybind11 is a lightweight header-only library that exposes + C++ types in Python and vice versa, mainly to create Python + bindings of existing C++ code. + ''; + license = lib.licenses.bsd3; + maintainers = with lib.maintainers; [ + yuriaisaka + dotlambda + ]; + }; +} diff --git a/pkgs/by-name/or/or-tools/pybind11-protobuf.nix b/pkgs/by-name/or/or-tools/pybind11-protobuf.nix index b6074d995f32..a93268e9358d 100644 --- a/pkgs/by-name/or/or-tools/pybind11-protobuf.nix +++ b/pkgs/by-name/or/or-tools/pybind11-protobuf.nix @@ -4,22 +4,22 @@ buildPythonPackage, fetchFromGitHub, cmake, - abseil-cpp_202407, - protobuf_29, + abseil-cpp_202505, + protobuf, pybind11, zlib, }: buildPythonPackage { pname = "pybind11-protobuf"; - version = "0-unstable-2025-02-10"; + version = "0-unstable-2025-10-29"; pyproject = false; src = fetchFromGitHub { owner = "pybind"; repo = "pybind11_protobuf"; - rev = "f02a2b7653bc50eb5119d125842a3870db95d251"; - hash = "sha256-jlZcxQKYYYvTOGhk+0Sgtek4oKy6R1wDGiBOf2t+KiU="; + rev = "4825dca68c8de73f5655fc50ce79c49c4d814652"; + hash = "sha256-SeIUyWLeThfBX3SljLdG7CbENdbuJG+X0+h/gn/ATWE="; }; patches = [ @@ -28,11 +28,16 @@ buildPythonPackage { ./add-install-target-for-cmake-builds.patch ]; + postPatch = '' + substituteInPlace cmake/dependencies/CMakeLists.txt \ + --replace-fail 'find_package(protobuf 5.29.2 REQUIRED)' 'find_package(protobuf REQUIRED)' + ''; + nativeBuildInputs = [ cmake ]; buildInputs = [ - abseil-cpp_202407 - protobuf_29 + abseil-cpp_202505 + protobuf pybind11 zlib ]; diff --git a/pkgs/by-name/or/or-tools/pybind11-setup-hook.sh b/pkgs/by-name/or/or-tools/pybind11-setup-hook.sh new file mode 100644 index 000000000000..a86eed36f1ec --- /dev/null +++ b/pkgs/by-name/or/or-tools/pybind11-setup-hook.sh @@ -0,0 +1,12 @@ +# Tell the pybind11 CMake module where to find host platform Python. This is +# required when cross-compiling. +pybind11CMakeFlags () { + cmakeFlagsArray+=( + '-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF' + '-DPYTHON_EXECUTABLE=@pythonInterpreter@' + '-DPYTHON_INCLUDE_DIR=@pythonIncludeDir@' + '-DPYTHON_SITE_PACKAGES=@pythonSitePackages@' + ) +} + +preConfigureHooks+=(pybind11CMakeFlags) diff --git a/pkgs/by-name/or/or-tools/pybind11.patch b/pkgs/by-name/or/or-tools/pybind11.patch new file mode 100644 index 000000000000..190e8471c467 --- /dev/null +++ b/pkgs/by-name/or/or-tools/pybind11.patch @@ -0,0 +1,452 @@ +diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h +index 71bc5902..6a148e74 100644 +--- a/include/pybind11/stl.h ++++ b/include/pybind11/stl.h +@@ -11,10 +11,14 @@ + + #include "pybind11.h" + #include "detail/common.h" ++#include "detail/descr.h" ++#include "detail/type_caster_base.h" + + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -35,6 +39,89 @@ + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + PYBIND11_NAMESPACE_BEGIN(detail) + ++// ++// Begin: Equivalent of ++// https://github.com/google/clif/blob/ae4eee1de07cdf115c0c9bf9fec9ff28efce6f6c/clif/python/runtime.cc#L388-L438 ++/* ++The three `PyObjectTypeIsConvertibleTo*()` functions below are ++the result of converging the behaviors of pybind11 and PyCLIF ++(http://github.com/google/clif). ++ ++Originally PyCLIF was extremely far on the permissive side of the spectrum, ++while pybind11 was very far on the strict side. Originally PyCLIF accepted any ++Python iterable as input for a C++ `vector`/`set`/`map` argument, as long as ++the elements were convertible. The obvious (in hindsight) problem was that ++any empty Python iterable could be passed to any of these C++ types, e.g. `{}` ++was accepted for C++ `vector`/`set` arguments, or `[]` for C++ `map` arguments. ++ ++The functions below strike a practical permissive-vs-strict compromise, ++informed by tens of thousands of use cases in the wild. A main objective is ++to prevent accidents and improve readability: ++ ++- Python literals must match the C++ types. ++ ++- For C++ `set`: The potentially reducing conversion from a Python sequence ++ (e.g. Python `list` or `tuple`) to a C++ `set` must be explicit, by going ++ through a Python `set`. ++ ++- However, a Python `set` can still be passed to a C++ `vector`. The rationale ++ is that this conversion is not reducing. Implicit conversions of this kind ++ are also fairly commonly used, therefore enforcing explicit conversions ++ would have an unfavorable cost : benefit ratio; more sloppily speaking, ++ such an enforcement would be more annoying than helpful. ++*/ ++ ++inline bool PyObjectIsInstanceWithOneOfTpNames(PyObject *obj, ++ std::initializer_list tp_names) { ++ if (PyType_Check(obj)) { ++ return false; ++ } ++ const char *obj_tp_name = Py_TYPE(obj)->tp_name; ++ for (const auto *tp_name : tp_names) { ++ if (std::strcmp(obj_tp_name, tp_name) == 0) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++inline bool PyObjectTypeIsConvertibleToStdVector(PyObject *obj) { ++ if (PySequence_Check(obj) != 0) { ++ return !PyUnicode_Check(obj) && !PyBytes_Check(obj); ++ } ++ return (PyGen_Check(obj) != 0) || (PyAnySet_Check(obj) != 0) ++ || PyObjectIsInstanceWithOneOfTpNames( ++ obj, {"dict_keys", "dict_values", "dict_items", "map", "zip"}); ++} ++ ++inline bool PyObjectTypeIsConvertibleToStdSet(PyObject *obj) { ++ return (PyAnySet_Check(obj) != 0) || PyObjectIsInstanceWithOneOfTpNames(obj, {"dict_keys"}); ++} ++ ++inline bool PyObjectTypeIsConvertibleToStdMap(PyObject *obj) { ++ if (PyDict_Check(obj)) { ++ return true; ++ } ++ // Implicit requirement in the conditions below: ++ // A type with `.__getitem__()` & `.items()` methods must implement these ++ // to be compatible with https://docs.python.org/3/c-api/mapping.html ++ if (PyMapping_Check(obj) == 0) { ++ return false; ++ } ++ PyObject *items = PyObject_GetAttrString(obj, "items"); ++ if (items == nullptr) { ++ PyErr_Clear(); ++ return false; ++ } ++ bool is_convertible = (PyCallable_Check(items) != 0); ++ Py_DECREF(items); ++ return is_convertible; ++} ++ ++// ++// End: Equivalent of clif/python/runtime.cc ++// ++ + /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for + /// forwarding a container element). Typically used indirect via forwarded_type(), below. + template +@@ -66,17 +153,10 @@ private: + } + void reserve_maybe(const anyset &, void *) {} + +-public: +- bool load(handle src, bool convert) { +- if (!isinstance(src)) { +- return false; +- } +- auto s = reinterpret_borrow(src); +- value.clear(); +- reserve_maybe(s, &value); +- for (auto entry : s) { ++ bool convert_iterable(const iterable &itbl, bool convert) { ++ for (const auto &it : itbl) { + key_conv conv; +- if (!conv.load(entry, convert)) { ++ if (!conv.load(it, convert)) { + return false; + } + value.insert(cast_op(std::move(conv))); +@@ -84,6 +164,29 @@ public: + return true; + } + ++ bool convert_anyset(anyset s, bool convert) { ++ value.clear(); ++ reserve_maybe(s, &value); ++ return convert_iterable(s, convert); ++ } ++ ++public: ++ bool load(handle src, bool convert) { ++ if (!PyObjectTypeIsConvertibleToStdSet(src.ptr())) { ++ return false; ++ } ++ if (isinstance(src)) { ++ value.clear(); ++ return convert_anyset(reinterpret_borrow(src), convert); ++ } ++ if (!convert) { ++ return false; ++ } ++ assert(isinstance(src)); ++ value.clear(); ++ return convert_iterable(reinterpret_borrow(src), convert); ++ } ++ + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + if (!std::is_lvalue_reference::value) { +@@ -115,15 +218,10 @@ private: + } + void reserve_maybe(const dict &, void *) {} + +-public: +- bool load(handle src, bool convert) { +- if (!isinstance(src)) { +- return false; +- } +- auto d = reinterpret_borrow(src); ++ bool convert_elements(const dict &d, bool convert) { + value.clear(); + reserve_maybe(d, &value); +- for (auto it : d) { ++ for (const auto &it : d) { + key_conv kconv; + value_conv vconv; + if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) { +@@ -134,6 +232,25 @@ public: + return true; + } + ++public: ++ bool load(handle src, bool convert) { ++ if (!PyObjectTypeIsConvertibleToStdMap(src.ptr())) { ++ return false; ++ } ++ if (isinstance(src)) { ++ return convert_elements(reinterpret_borrow(src), convert); ++ } ++ if (!convert) { ++ return false; ++ } ++ auto items = reinterpret_steal(PyMapping_Items(src.ptr())); ++ if (!items) { ++ throw error_already_set(); ++ } ++ assert(isinstance(items)); ++ return convert_elements(dict(reinterpret_borrow(items)), convert); ++ } ++ + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + dict d; +@@ -166,13 +283,35 @@ struct list_caster { + using value_conv = make_caster; + + bool load(handle src, bool convert) { +- if (!isinstance(src) || isinstance(src) || isinstance(src)) { ++ if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) { + return false; + } +- auto s = reinterpret_borrow(src); ++ if (isinstance(src)) { ++ return convert_elements(src, convert); ++ } ++ if (!convert) { ++ return false; ++ } ++ // Designed to be behavior-equivalent to passing tuple(src) from Python: ++ // The conversion to a tuple will first exhaust the generator object, to ensure that ++ // the generator is not left in an unpredictable (to the caller) partially-consumed ++ // state. ++ assert(isinstance(src)); ++ return convert_elements(tuple(reinterpret_borrow(src)), convert); ++ } ++ ++private: ++ template ::value, int> = 0> ++ void reserve_maybe(const sequence &s, Type *) { ++ value.reserve(s.size()); ++ } ++ void reserve_maybe(const sequence &, void *) {} ++ ++ bool convert_elements(handle seq, bool convert) { ++ auto s = reinterpret_borrow(seq); + value.clear(); + reserve_maybe(s, &value); +- for (const auto &it : s) { ++ for (const auto &it : seq) { + value_conv conv; + if (!conv.load(it, convert)) { + return false; +@@ -182,13 +321,6 @@ struct list_caster { + return true; + } + +-private: +- template ::value, int> = 0> +- void reserve_maybe(const sequence &s, Type *) { +- value.reserve(s.size()); +- } +- void reserve_maybe(const sequence &, void *) {} +- + public: + template + static handle cast(T &&src, return_value_policy policy, handle parent) { +@@ -220,43 +352,87 @@ struct type_caster> : list_caster + struct type_caster> : list_caster, Type> {}; + ++template ++ArrayType vector_to_array_impl(V &&v, index_sequence) { ++ return {{std::move(v[I])...}}; ++} ++ ++// Based on https://en.cppreference.com/w/cpp/container/array/to_array ++template ++ArrayType vector_to_array(V &&v) { ++ return vector_to_array_impl(std::forward(v), make_index_sequence{}); ++} ++ + template + struct array_caster { + using value_conv = make_caster; + + private: +- template +- bool require_size(enable_if_t size) { +- if (value.size() != size) { +- value.resize(size); ++ std::unique_ptr value; ++ ++ template = 0> ++ bool convert_elements(handle seq, bool convert) { ++ auto l = reinterpret_borrow(seq); ++ value.reset(new ArrayType{}); ++ // Using `resize` to preserve the behavior exactly as it was before PR #5305 ++ // For the `resize` to work, `Value` must be default constructible. ++ // For `std::valarray`, this is a requirement: ++ // https://en.cppreference.com/w/cpp/named_req/NumericType ++ value->resize(l.size()); ++ size_t ctr = 0; ++ for (const auto &it : l) { ++ value_conv conv; ++ if (!conv.load(it, convert)) { ++ return false; ++ } ++ (*value)[ctr++] = cast_op(std::move(conv)); + } + return true; + } +- template +- bool require_size(enable_if_t size) { +- return size == Size; +- } + +-public: +- bool load(handle src, bool convert) { +- if (!isinstance(src)) { ++ template = 0> ++ bool convert_elements(handle seq, bool convert) { ++ auto l = reinterpret_borrow(seq); ++ if (l.size() != Size) { + return false; + } +- auto l = reinterpret_borrow(src); +- if (!require_size(l.size())) { +- return false; +- } +- size_t ctr = 0; +- for (const auto &it : l) { ++ // The `temp` storage is needed to support `Value` types that are not ++ // default-constructible. ++ // Deliberate choice: no template specializations, for simplicity, and ++ // because the compile time overhead for the specializations is deemed ++ // more significant than the runtime overhead for the `temp` storage. ++ std::vector temp; ++ temp.reserve(l.size()); ++ for (auto it : l) { + value_conv conv; + if (!conv.load(it, convert)) { + return false; + } +- value[ctr++] = cast_op(std::move(conv)); ++ temp.emplace_back(cast_op(std::move(conv))); + } ++ value.reset(new ArrayType(vector_to_array(std::move(temp)))); + return true; + } + ++public: ++ bool load(handle src, bool convert) { ++ if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) { ++ return false; ++ } ++ if (isinstance(src)) { ++ return convert_elements(src, convert); ++ } ++ if (!convert) { ++ return false; ++ } ++ // Designed to be behavior-equivalent to passing tuple(src) from Python: ++ // The conversion to a tuple will first exhaust the generator object, to ensure that ++ // the generator is not left in an unpredictable (to the caller) partially-consumed ++ // state. ++ assert(isinstance(src)); ++ return convert_elements(tuple(reinterpret_borrow(src)), convert); ++ } ++ + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + list l(src.size()); +@@ -272,12 +448,36 @@ public: + return l.release(); + } + +- PYBIND11_TYPE_CASTER(ArrayType, +- const_name(const_name(""), const_name("Annotated[")) +- + const_name("list[") + value_conv::name + const_name("]") +- + const_name(const_name(""), +- const_name(", FixedSize(") +- + const_name() + const_name(")]"))); ++ // Code copied from PYBIND11_TYPE_CASTER macro. ++ // Intentionally preserving the behavior exactly as it was before PR #5305 ++ template >::value, int> = 0> ++ static handle cast(T_ *src, return_value_policy policy, handle parent) { ++ if (!src) { ++ return none().release(); ++ } ++ if (policy == return_value_policy::take_ownership) { ++ auto h = cast(std::move(*src), policy, parent); ++ delete src; // WARNING: Assumes `src` was allocated with `new`. ++ return h; ++ } ++ return cast(*src, policy, parent); ++ } ++ ++ // NOLINTNEXTLINE(google-explicit-constructor) ++ operator ArrayType *() { return &(*value); } ++ // NOLINTNEXTLINE(google-explicit-constructor) ++ operator ArrayType &() { return *value; } ++ // NOLINTNEXTLINE(google-explicit-constructor) ++ operator ArrayType &&() && { return std::move(*value); } ++ ++ template ++ using cast_op_type = movable_cast_op_type; ++ ++ static constexpr auto name ++ = const_name(const_name(""), const_name("Annotated[")) + const_name("list[") ++ + value_conv::name + const_name("]") ++ + const_name( ++ const_name(""), const_name(", FixedSize(") + const_name() + const_name(")]")); + }; + + template +diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp +index e7db8aaa..84bd4755 100644 +--- a/tests/test_stl.cpp ++++ b/tests/test_stl.cpp +@@ -193,6 +193,23 @@ TEST_SUBMODULE(stl, m) { + m.def("cast_array", []() { return std::array{{1, 2}}; }); + m.def("load_array", [](const std::array &a) { return a[0] == 1 && a[1] == 2; }); + ++ struct NoDefaultCtor { ++ explicit constexpr NoDefaultCtor(int val) : val{val} {} ++ int val; ++ }; ++ ++ struct NoDefaultCtorArray { ++ explicit constexpr NoDefaultCtorArray(int i) ++ : arr{{NoDefaultCtor(10 + i), NoDefaultCtor(20 + i)}} {} ++ std::array arr; ++ }; ++ ++ // test_array_no_default_ctor ++ py::class_(m, "NoDefaultCtor").def_readonly("val", &NoDefaultCtor::val); ++ py::class_(m, "NoDefaultCtorArray") ++ .def(py::init()) ++ .def_readwrite("arr", &NoDefaultCtorArray::arr); ++ + // test_valarray + m.def("cast_valarray", []() { return std::valarray{1, 4, 9}; }); + m.def("load_valarray", [](const std::valarray &v) { +diff --git a/tests/test_stl.py b/tests/test_stl.py +index 65fda54c..340cdc35 100644 +--- a/tests/test_stl.py ++++ b/tests/test_stl.py +@@ -48,6 +48,13 @@ def test_array(doc): + ) + + ++def test_array_no_default_ctor(): ++ lst = m.NoDefaultCtorArray(3) ++ assert [e.val for e in lst.arr] == [13, 23] ++ lst.arr = m.NoDefaultCtorArray(4).arr ++ assert [e.val for e in lst.arr] == [14, 24] ++ ++ + def test_valarray(doc): + """std::valarray <-> list""" + lst = m.cast_valarray() diff --git a/pkgs/by-name/or/or-tools/scip.patch b/pkgs/by-name/or/or-tools/scip.patch new file mode 100644 index 000000000000..7a92254118b6 --- /dev/null +++ b/pkgs/by-name/or/or-tools/scip.patch @@ -0,0 +1,145 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 8492dc75..4c12a9bf 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -38,9 +38,11 @@ set(CPACK_PACKAGE_VENDOR "Zuse Institute Berlin") + set(CPACK_PACKAGE_CONTACT "http://scipopt.org") + include(CPack) + +-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) ++if(CMAKE_PROJECT_NAME EQUAL "SCIP") ++ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) ++ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) ++ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) ++endif() + + if(SCIPOptSuite_BINARY_DIR) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SCIPOptSuite_BINARY_DIR}/bin) +@@ -412,22 +414,11 @@ endif() + #search the selected LP solver library + message(STATUS "Finding Solver \"${LPS}\"") + if(LPS STREQUAL "spx") +- message(STATUS "Finding Soplex") +- find_package(SOPLEX CONFIG HINTS ${SOPLEX_DIR}) +- if(NOT SOPLEX_FOUND) +- # Utilities to automatically download missing dependencies +- include(cmake/Dependencies.cmake) +- find_or_download_package( +- NAME SOPLEX +- VERSION 7.0.1 +- URL https://github.com/scipopt/soplex/archive/refs/tags/release-701.tar.gz +- URL_HASH SHA256=80cce994dcbe45fd52b60e31a3aeb5d2c60a7ddbaae495e0ce6bf58481675696 +- COMPONENTS soplex) +- find_package(SOPLEX REQUIRED CONFIG HINTS _deps/local) +- endif() +- if(NOT SOPLEX_FOUND) ++ message(STATUS "Finding Soplex...") ++ if(NOT TARGET libsoplex-pic OR NOT TARGET libsoplex) + message(FATAL_ERROR "Requested LP solver SoPlex not found.") + endif() ++ set(SOPLEX_FOUND TRUE) + if (DEFINED SOPLEX_WITH_PAPILO) + message(STATUS "SOPLEX links PAPILO") + if((NOT SCIP_WITH_PAPILO)) # TODO not sure how to handle AUTOBUILD +@@ -502,9 +493,9 @@ if(SOPLEX_FOUND) + message(STATUS "Finding SOPLEX - found") + # SoPlex headers can be directly included + include_directories(${SOPLEX_INCLUDE_DIRS}) +- set(LPS_LIBRARIES ${SOPLEX_LIBRARIES}) ++ set(LPS_LIBRARIES libsoplex) + if(SHARED) +- set(LPS_PIC_LIBRARIES ${SOPLEX_PIC_LIBRARIES}) ++ set(LPS_PIC_LIBRARIES libsoplex-pic) + else() + set(LPS_PIC_LIBRARIES ${LPS_LIBRARIES}) + endif() +@@ -514,7 +505,7 @@ if(SOPLEX_FOUND) + set(lpi lpi/lpi_spx2.cpp) + endif() + else() +- message(STATUS "Support SOPLEX: OFF") ++ message(FATAL_ERROR "SOPLEX not found !") + endif() + + if(CLP_FOUND) +diff --git a/scip-config.cmake.in b/scip-config.cmake.in +index 559552f9..682ac40a 100644 +--- a/scip-config.cmake.in ++++ b/scip-config.cmake.in +@@ -1,17 +1,16 @@ + if(NOT TARGET libscip) +- include("${CMAKE_CURRENT_LIST_DIR}/scip-targets.cmake") +-endif() ++ include(CMakeFindDependencyMacro) ++ if(@ZIMPL_NEEDED@) ++ find_dependency(ZIMPL REQUIRED NO_MODULE) ++ endif() ++ if(@SOPLEX_NEEDED@) ++ find_dependency(SOPLEX REQUIRED NO_MODULE) ++ endif() + +-if(@ZIMPL_NEEDED@) +- set(ZIMPL_DIR "@CONF_ZIMPL_DIR@") +- find_package(ZIMPL QUIET CONFIG) +-endif() +- +-if(@SOPLEX_NEEDED@) +- set(SOPLEX_DIR "@CONF_SOPLEX_DIR@") +- find_package(SOPLEX QUIET CONFIG) ++ include("${CMAKE_CURRENT_LIST_DIR}/scip-targets.cmake") + endif() + ++# Legacy + set(SCIP_LIBRARIES libscip) + set(SCIP_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") + set(SCIP_FOUND TRUE) +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index e6fda2d5..2d04b845 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -1149,17 +1149,8 @@ install(TARGETS scip libscip EXPORT scip-targets + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + # Add all targets to the build-tree export set +-export(TARGETS scip libscip +- FILE "${PROJECT_BINARY_DIR}/scip-targets.cmake") +- +-# make soplex and zimpl dir absolute for the config file +-if(SOPLEX_NEEDED) +- get_filename_component(CONF_SOPLEX_DIR ${SOPLEX_DIR} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) +-endif() +- +-if(ZIMPL_NEEDED) +- get_filename_component(CONF_ZIMPL_DIR ${ZIMPL_DIR} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) +-endif() ++#export(TARGETS scip libscip ++# FILE "${PROJECT_BINARY_DIR}/scip-targets.cmake") + + # configure the config file for the build tree + set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}") +@@ -1175,18 +1166,16 @@ ${PROJECT_BINARY_DIR}/scip-config-version.cmake + + #configure the config file for the install + set(CONF_INCLUDE_DIRS "\${CMAKE_CURRENT_LIST_DIR}/../../../include") +-if(SOPLEX_NEEDED) +- set(CONF_SOPLEX_DIR "\${CMAKE_CURRENT_LIST_DIR}/../soplex") +-endif() +-if(ZIMPL_NEEDED) +- set(CONF_ZIMPL_DIR "\${CMAKE_CURRENT_LIST_DIR}/../zimpl") +-endif() + configure_file(${PROJECT_SOURCE_DIR}/scip-config.cmake.in + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/scip-config.cmake" @ONLY) + + # install the targets of the scip export group and the config file so that other projects + # can link easily against scip +-install(EXPORT scip-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/scip) ++install(EXPORT scip-targets ++ NAMESPACE SCIP:: ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/scip ++ COMPONENT Devel ++) + install(FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/scip-config.cmake" + ${PROJECT_BINARY_DIR}/scip-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/scip) From f820afe58e7317aa8f06ab2303b30bbfe7df1839 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Wed, 5 Nov 2025 17:18:13 +0200 Subject: [PATCH 4/5] or-tools: enable tests on aarch64-linux https://github.com/google/or-tools/issues/4746 got fixed upstream, apply the fix locally until part of a release. --- pkgs/by-name/or/or-tools/package.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/or/or-tools/package.nix b/pkgs/by-name/or/or-tools/package.nix index c7a98e080546..d4a1b55aa7e8 100644 --- a/pkgs/by-name/or/or-tools/package.nix +++ b/pkgs/by-name/or/or-tools/package.nix @@ -117,6 +117,12 @@ stdenv.mkDerivation (finalAttrs: { url = "https://github.com/google/or-tools/commit/b5a2f8ac40dd4bfa4359c35570733171454ec72b.patch"; hash = "sha256-h96zJkqTtwfBd+m7Lm9r/ks/n8uvY4iSPgxMZe8vtXI="; }) + # Fix tests on aarch64-linux + # https://github.com/google/or-tools/issues/4746 + (fetchpatch { + url = "https://github.com/google/or-tools/commit/8442c7b1c219b0c8d58ee96d266d81b7c3a19ad2.patch"; + hash = "sha256-HrV9wU3PFMdb3feGt8i5UJNgHuitMRBF9cNrH5RRENQ="; + }) ]; # or-tools normally attempts to build Protobuf for the build platform when @@ -213,9 +219,8 @@ stdenv.mkDerivation (finalAttrs: { python3.pkgs.virtualenv ]; - # some tests fail on aarch64-linux and hang on darwin - # https://github.com/google/or-tools/issues/4746 - doCheck = stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform.isLinux; + # some tests hang on darwin + doCheck = stdenv.hostPlatform.isLinux; preCheck = '' export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}$PWD/lib From ca31461fe1e245254e2466dc7e010e3f6de4e164 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Mon, 10 Nov 2025 15:49:42 +0200 Subject: [PATCH 5/5] or-tools: use ' for overrides This seems to be more consistent with other places in nixpkgs. --- pkgs/by-name/or/or-tools/package.nix | 45 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/pkgs/by-name/or/or-tools/package.nix b/pkgs/by-name/or/or-tools/package.nix index d4a1b55aa7e8..5b068ab449fb 100644 --- a/pkgs/by-name/or/or-tools/package.nix +++ b/pkgs/by-name/or/or-tools/package.nix @@ -32,11 +32,11 @@ let # protobuf. Do not un-pin these, even if you're upgrading them to # what might happen to be the latest version at the current moment; # future upgrades *will* break the build. - abseil-cpp = abseil-cpp_202505; - protobuf = protobuf_31.override { inherit abseil-cpp; }; - python-protobuf = python3.pkgs.protobuf5.override { inherit protobuf; }; + abseil-cpp' = abseil-cpp_202505; + protobuf' = protobuf_31.override { abseil-cpp = abseil-cpp'; }; + python-protobuf' = python3.pkgs.protobuf5.override { protobuf = protobuf'; }; - pybind11 = callPackage ./pybind11-2.13.6.nix { + pybind11' = callPackage ./pybind11-2.13.6.nix { inherit (python3.pkgs) buildPythonPackage cmake @@ -48,19 +48,20 @@ let ; python = python3; }; - pybind11-abseil = python3.pkgs.pybind11-abseil.override { - inherit abseil-cpp pybind11; + pybind11-abseil' = python3.pkgs.pybind11-abseil.override { + pybind11 = pybind11'; + abseil-cpp = abseil-cpp'; }; - pybind11-protobuf = callPackage ./pybind11-protobuf.nix { + pybind11-protobuf' = callPackage ./pybind11-protobuf.nix { inherit (python3.pkgs) buildPythonPackage; - inherit pybind11; + pybind11 = pybind11'; }; # re2 must also use the same abseil version, else these two versions will conflict during linking - _re2 = re2.override { inherit abseil-cpp; }; + re2' = re2.override { abseil-cpp = abseil-cpp'; }; # 77a28070b9c4c83995ac6bbfa9544722ff3342ce renamed the scip cmake target(s) differently # to what upstream still calls it. Apply this patch to scipopt-scip. - _scipopt-scip = scipopt-scip.overrideAttrs (old: { + scipopt-scip' = scipopt-scip.overrideAttrs (old: { patches = old.patches or [ ] ++ [ # from https://github.com/google/or-tools/commit/77a28070b9c4c83995ac6bbfa9544722ff3342ce#diff-c95174a817e73db366d414af1e329c1856f70e5158ed3994d43da88765ccc98f ./scip.patch @@ -74,7 +75,7 @@ let # local revert of 58daf511687f191829238fc7f571e08dc9dedf56, # working around https://github.com/google/or-tools/issues/4911 - _highs = highs.overrideAttrs (old: rec { + highs' = highs.overrideAttrs (old: rec { version = "1.10.0"; src = fetchFromGitHub { owner = "ERGO-Code"; @@ -177,37 +178,37 @@ stdenv.mkDerivation (finalAttrs: { mypy ]); buildInputs = [ - abseil-cpp + abseil-cpp' bzip2 cbc eigen glpk gbenchmark gtest - _highs + highs' python3.pkgs.absl-py - pybind11 - pybind11-abseil - pybind11-protobuf + pybind11' + pybind11-abseil' + pybind11-protobuf' python3.pkgs.pytest python3.pkgs.scipy python3.pkgs.setuptools python3.pkgs.wheel - _re2 + re2' zlib ]; propagatedBuildInputs = [ - abseil-cpp - _highs - protobuf - python-protobuf + abseil-cpp' + highs' + protobuf' + python-protobuf' python3.pkgs.immutabledict python3.pkgs.numpy python3.pkgs.pandas ] ++ lib.optionals withScip [ # Needed for downstream cmake consumers to not need to set SCIP_ROOT explicitly - _scipopt-scip + scipopt-scip' ]; nativeCheckInputs = [