or-tools: 9.12 -> 9.14 (#458786)
This commit is contained in:
@@ -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 ];
|
||||
};
|
||||
})
|
||||
+25
-6
@@ -1,6 +1,20 @@
|
||||
From 077295f6ede59d9e2413b2d19f38cf63b64f4fec Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
|
||||
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
|
||||
$<IF:$<BOOL:${BUILD_MATH_OPT}>,copy,true>
|
||||
$<TARGET_FILE:math_opt_pybind11> ${PYTHON_PROJECT}/math_opt/core/python
|
||||
$<TARGET_FILE:math_opt_io_pybind11> ${PYTHON_PROJECT}/math_opt/io/python
|
||||
- COMMAND ${CMAKE_COMMAND} -E
|
||||
- $<IF:$<BOOL:${BUILD_MATH_OPT}>,copy,true>
|
||||
- $<TARGET_FILE:status_py_extension_stub> ${PYTHON_PROJECT}/../pybind11_abseil
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
$<IF:$<TARGET_EXISTS:pdlp_pybind11>,copy,true>
|
||||
$<$<TARGET_EXISTS:pdlp_pybind11>:$<TARGET_FILE:pdlp_pybind11>> ${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':[
|
||||
'$<TARGET_FILE_NAME:math_opt_pybind11>',
|
||||
--
|
||||
2.51.0
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
From 46e7d2cccd029a2c4215ce9b0c3bf72b2f2dd398 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
|
||||
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
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
{
|
||||
abseil-cpp_202407,
|
||||
stdenv,
|
||||
lib,
|
||||
callPackage,
|
||||
|
||||
abseil-cpp_202505,
|
||||
bzip2,
|
||||
cbc,
|
||||
cmake,
|
||||
@@ -11,12 +15,10 @@
|
||||
gbenchmark,
|
||||
glpk,
|
||||
highs,
|
||||
lib,
|
||||
pkg-config,
|
||||
protobuf_29,
|
||||
protobuf_31,
|
||||
python3,
|
||||
re2,
|
||||
stdenv,
|
||||
swig,
|
||||
unzip,
|
||||
zlib,
|
||||
@@ -30,14 +32,50 @@ 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; };
|
||||
python-protobuf = python3.pkgs.protobuf5.override { inherit protobuf; };
|
||||
pybind11-protobuf = python3.pkgs.pybind11-protobuf.override { protobuf_29 = 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 {
|
||||
inherit (python3.pkgs)
|
||||
buildPythonPackage
|
||||
cmake
|
||||
ninja
|
||||
numpy
|
||||
pytestCheckHook
|
||||
pythonOlder
|
||||
setuptools
|
||||
;
|
||||
python = python3;
|
||||
};
|
||||
pybind11-abseil' = python3.pkgs.pybind11-abseil.override {
|
||||
pybind11 = pybind11';
|
||||
abseil-cpp = abseil-cpp';
|
||||
};
|
||||
pybind11-protobuf' = callPackage ./pybind11-protobuf.nix {
|
||||
inherit (python3.pkgs) buildPythonPackage;
|
||||
pybind11 = pybind11';
|
||||
};
|
||||
# re2 must also use the same abseil version, else these two versions will conflict during linking
|
||||
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: {
|
||||
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
|
||||
_highs = highs.overrideAttrs (old: rec {
|
||||
highs' = highs.overrideAttrs (old: rec {
|
||||
version = "1.10.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "ERGO-Code";
|
||||
@@ -57,13 +95,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 = [
|
||||
@@ -74,16 +112,18 @@ 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";
|
||||
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
|
||||
@@ -108,6 +148,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}")
|
||||
@@ -136,37 +178,37 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
mypy
|
||||
]);
|
||||
buildInputs = [
|
||||
abseil-cpp
|
||||
abseil-cpp'
|
||||
bzip2
|
||||
cbc
|
||||
eigen
|
||||
glpk
|
||||
gbenchmark
|
||||
gtest
|
||||
_highs
|
||||
highs'
|
||||
python3.pkgs.absl-py
|
||||
python3.pkgs.pybind11
|
||||
python3.pkgs.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 = [
|
||||
@@ -178,8 +220,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
python3.pkgs.virtualenv
|
||||
];
|
||||
|
||||
# some tests fail on aarch64-linux and hang on darwin
|
||||
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
|
||||
|
||||
@@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
+12
-7
@@ -4,22 +4,22 @@
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
cmake,
|
||||
abseil-cpp_202407, # downgrade, same reason as toplevel protobuf_29
|
||||
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
|
||||
];
|
||||
@@ -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)
|
||||
@@ -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 <deque>
|
||||
+#include <initializer_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
+#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
@@ -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<const char *> 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 <typename T, typename U>
|
||||
@@ -66,17 +153,10 @@ private:
|
||||
}
|
||||
void reserve_maybe(const anyset &, void *) {}
|
||||
|
||||
-public:
|
||||
- bool load(handle src, bool convert) {
|
||||
- if (!isinstance<anyset>(src)) {
|
||||
- return false;
|
||||
- }
|
||||
- auto s = reinterpret_borrow<anyset>(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<Key &&>(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<anyset>(src)) {
|
||||
+ value.clear();
|
||||
+ return convert_anyset(reinterpret_borrow<anyset>(src), convert);
|
||||
+ }
|
||||
+ if (!convert) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ assert(isinstance<iterable>(src));
|
||||
+ value.clear();
|
||||
+ return convert_iterable(reinterpret_borrow<iterable>(src), convert);
|
||||
+ }
|
||||
+
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
if (!std::is_lvalue_reference<T>::value) {
|
||||
@@ -115,15 +218,10 @@ private:
|
||||
}
|
||||
void reserve_maybe(const dict &, void *) {}
|
||||
|
||||
-public:
|
||||
- bool load(handle src, bool convert) {
|
||||
- if (!isinstance<dict>(src)) {
|
||||
- return false;
|
||||
- }
|
||||
- auto d = reinterpret_borrow<dict>(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<dict>(src)) {
|
||||
+ return convert_elements(reinterpret_borrow<dict>(src), convert);
|
||||
+ }
|
||||
+ if (!convert) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ auto items = reinterpret_steal<object>(PyMapping_Items(src.ptr()));
|
||||
+ if (!items) {
|
||||
+ throw error_already_set();
|
||||
+ }
|
||||
+ assert(isinstance<iterable>(items));
|
||||
+ return convert_elements(dict(reinterpret_borrow<iterable>(items)), convert);
|
||||
+ }
|
||||
+
|
||||
template <typename T>
|
||||
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<Value>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
- if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {
|
||||
+ if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) {
|
||||
return false;
|
||||
}
|
||||
- auto s = reinterpret_borrow<sequence>(src);
|
||||
+ if (isinstance<sequence>(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<iterable>(src));
|
||||
+ return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+ template <typename T = Type, enable_if_t<has_reserve_method<T>::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<sequence>(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 <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
|
||||
- void reserve_maybe(const sequence &s, Type *) {
|
||||
- value.reserve(s.size());
|
||||
- }
|
||||
- void reserve_maybe(const sequence &, void *) {}
|
||||
-
|
||||
public:
|
||||
template <typename T>
|
||||
static handle cast(T &&src, return_value_policy policy, handle parent) {
|
||||
@@ -220,43 +352,87 @@ struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc
|
||||
template <typename Type, typename Alloc>
|
||||
struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
|
||||
|
||||
+template <typename ArrayType, typename V, size_t... I>
|
||||
+ArrayType vector_to_array_impl(V &&v, index_sequence<I...>) {
|
||||
+ return {{std::move(v[I])...}};
|
||||
+}
|
||||
+
|
||||
+// Based on https://en.cppreference.com/w/cpp/container/array/to_array
|
||||
+template <typename ArrayType, size_t N, typename V>
|
||||
+ArrayType vector_to_array(V &&v) {
|
||||
+ return vector_to_array_impl<ArrayType, V>(std::forward<V>(v), make_index_sequence<N>{});
|
||||
+}
|
||||
+
|
||||
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
|
||||
struct array_caster {
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
private:
|
||||
- template <bool R = Resizable>
|
||||
- bool require_size(enable_if_t<R, size_t> size) {
|
||||
- if (value.size() != size) {
|
||||
- value.resize(size);
|
||||
+ std::unique_ptr<ArrayType> value;
|
||||
+
|
||||
+ template <bool R = Resizable, enable_if_t<R, int> = 0>
|
||||
+ bool convert_elements(handle seq, bool convert) {
|
||||
+ auto l = reinterpret_borrow<sequence>(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<Value &&>(std::move(conv));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
- template <bool R = Resizable>
|
||||
- bool require_size(enable_if_t<!R, size_t> size) {
|
||||
- return size == Size;
|
||||
- }
|
||||
|
||||
-public:
|
||||
- bool load(handle src, bool convert) {
|
||||
- if (!isinstance<sequence>(src)) {
|
||||
+ template <bool R = Resizable, enable_if_t<!R, int> = 0>
|
||||
+ bool convert_elements(handle seq, bool convert) {
|
||||
+ auto l = reinterpret_borrow<sequence>(seq);
|
||||
+ if (l.size() != Size) {
|
||||
return false;
|
||||
}
|
||||
- auto l = reinterpret_borrow<sequence>(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<Value> temp;
|
||||
+ temp.reserve(l.size());
|
||||
+ for (auto it : l) {
|
||||
value_conv conv;
|
||||
if (!conv.load(it, convert)) {
|
||||
return false;
|
||||
}
|
||||
- value[ctr++] = cast_op<Value &&>(std::move(conv));
|
||||
+ temp.emplace_back(cast_op<Value &&>(std::move(conv)));
|
||||
}
|
||||
+ value.reset(new ArrayType(vector_to_array<ArrayType, Size>(std::move(temp))));
|
||||
return true;
|
||||
}
|
||||
|
||||
+public:
|
||||
+ bool load(handle src, bool convert) {
|
||||
+ if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (isinstance<sequence>(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<iterable>(src));
|
||||
+ return convert_elements(tuple(reinterpret_borrow<iterable>(src)), convert);
|
||||
+ }
|
||||
+
|
||||
template <typename T>
|
||||
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<Resizable>(const_name(""), const_name("Annotated["))
|
||||
- + const_name("list[") + value_conv::name + const_name("]")
|
||||
- + const_name<Resizable>(const_name(""),
|
||||
- const_name(", FixedSize(")
|
||||
- + const_name<Size>() + const_name(")]")));
|
||||
+ // Code copied from PYBIND11_TYPE_CASTER macro.
|
||||
+ // Intentionally preserving the behavior exactly as it was before PR #5305
|
||||
+ template <typename T_, enable_if_t<std::is_same<ArrayType, remove_cv_t<T_>>::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 <typename T_>
|
||||
+ using cast_op_type = movable_cast_op_type<T_>;
|
||||
+
|
||||
+ static constexpr auto name
|
||||
+ = const_name<Resizable>(const_name(""), const_name("Annotated[")) + const_name("list[")
|
||||
+ + value_conv::name + const_name("]")
|
||||
+ + const_name<Resizable>(
|
||||
+ const_name(""), const_name(", FixedSize(") + const_name<Size>() + const_name(")]"));
|
||||
};
|
||||
|
||||
template <typename Type, size_t Size>
|
||||
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<int, 2>{{1, 2}}; });
|
||||
m.def("load_array", [](const std::array<int, 2> &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<NoDefaultCtor, 2> arr;
|
||||
+ };
|
||||
+
|
||||
+ // test_array_no_default_ctor
|
||||
+ py::class_<NoDefaultCtor>(m, "NoDefaultCtor").def_readonly("val", &NoDefaultCtor::val);
|
||||
+ py::class_<NoDefaultCtorArray>(m, "NoDefaultCtorArray")
|
||||
+ .def(py::init<int>())
|
||||
+ .def_readwrite("arr", &NoDefaultCtorArray::arr);
|
||||
+
|
||||
// test_valarray
|
||||
m.def("cast_valarray", []() { return std::valarray<int>{1, 4, 9}; });
|
||||
m.def("load_valarray", [](const std::valarray<int> &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()
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12774,8 +12774,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 { };
|
||||
|
||||
Reference in New Issue
Block a user