From 434e07601ec559e92cac36b8ea34a162d8780d9b Mon Sep 17 00:00:00 2001 From: Benjamin Sparks Date: Sat, 12 Apr 2025 23:24:38 +0100 Subject: [PATCH 1/4] nlopt: Correct build process Now uses cmakeFlags to determine what gets built. Adds proper support for potential Python and Octave bindings --- pkgs/development/libraries/nlopt/default.nix | 79 +++++++++++++------- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/pkgs/development/libraries/nlopt/default.nix b/pkgs/development/libraries/nlopt/default.nix index 1e1f5f01c382..db7071ba429e 100644 --- a/pkgs/development/libraries/nlopt/default.nix +++ b/pkgs/development/libraries/nlopt/default.nix @@ -3,49 +3,74 @@ stdenv, fetchFromGitHub, cmake, - octave ? null, - libiconv, + # Optionally build Python bindings + withPython ? false, + python3, + python3Packages, + swig, + # Optionally build Octave bindings + withOctave ? false, + octave, + # Build static on-demand + withStatic ? stdenv.hostPlatform.isStatic, }: - -stdenv.mkDerivation rec { +let + buildPythonBindingsEnv = python3.withPackages (p: [ p.numpy ]); +in +stdenv.mkDerivation (finalAttrs: { pname = "nlopt"; version = "2.7.1"; src = fetchFromGitHub { owner = "stevengj"; - repo = pname; - rev = "v${version}"; - sha256 = "sha256-TgieCX7yUdTAEblzXY/gCN0r6F9TVDh4RdNDjQdXZ1o="; + repo = "nlopt"; + tag = "v${finalAttrs.version}"; + hash = "sha256-TgieCX7yUdTAEblzXY/gCN0r6F9TVDh4RdNDjQdXZ1o="; }; - nativeBuildInputs = [ cmake ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ]; - buildInputs = [ octave ]; - - configureFlags = - [ - "--with-cxx" - "--enable-shared" - "--with-pic" - "--without-guile" - "--without-python" - "--without-matlab" + nativeBuildInputs = + [ cmake ] + ## Building the python bindings requires SWIG, and numpy in addition to the CXX routines. + ## The tests also make use of the same interpreter to test the bindings. + ++ lib.optionals withPython [ + swig + buildPythonBindingsEnv ] - ++ lib.optionals (octave != null) [ - "--with-octave" - "M_INSTALL_DIR=$(out)/${octave.sitePath}/m" - "OCT_INSTALL_DIR=$(out)/${octave.sitePath}/oct" - ]; + ## Building octave bindings requires `mkoctfile` to be installed. + ++ lib.optional withOctave octave; + + # Python bindings depend on numpy at import time. + propagatedBuildInputs = lib.optional withPython python3Packages.numpy; + + cmakeFlags = + [ + (lib.cmakeBool "BUILD_SHARED_LIBS" (!withStatic)) + (lib.cmakeBool "NLOPT_CXX" true) + (lib.cmakeBool "NLOPT_PYTHON" withPython) + (lib.cmakeBool "NLOPT_OCTAVE" withOctave) + (lib.cmakeBool "NLOPT_SWIG" withPython) + (lib.cmakeBool "NLOPT_FORTRAN" false) + (lib.cmakeBool "NLOPT_MATLAB" false) + (lib.cmakeBool "NLOPT_GUILE" false) + (lib.cmakeBool "NLOPT_TESTS" finalAttrs.doCheck) + ] + ++ lib.optional withPython ( + lib.cmakeFeature "Python_EXECUTABLE" "${buildPythonBindingsEnv.interpreter}" + ); + + doCheck = true; postFixup = '' - substituteInPlace $out/lib/cmake/nlopt/NLoptLibraryDepends.cmake --replace \ + substituteInPlace $out/lib/cmake/nlopt/NLoptLibraryDepends.cmake --replace-fail \ 'INTERFACE_INCLUDE_DIRECTORIES "''${_IMPORT_PREFIX}/' 'INTERFACE_INCLUDE_DIRECTORIES "' ''; meta = { homepage = "https://nlopt.readthedocs.io/en/latest/"; + changelog = "https://github.com/stevengj/nlopt/releases/tag/v${finalAttrs.version}"; description = "Free open-source library for nonlinear optimization"; license = lib.licenses.lgpl21Plus; - hydraPlatforms = lib.platforms.linux; + platforms = lib.platforms.all; + maintainers = [ lib.maintainers.bengsparks ]; }; - -} +}) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0a2161727e00..bdcbd816ac72 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -4298,7 +4298,7 @@ with pkgs; nifskope = libsForQt5.callPackage ../tools/graphics/nifskope { }; - nlopt = callPackage ../development/libraries/nlopt { octave = null; }; + nlopt = callPackage ../development/libraries/nlopt { }; notation = callPackage ../by-name/no/notation/package.nix { buildGoModule = buildGo123Module; From 9d2808a3187d503bce78d748ccab1ec3e6f1443a Mon Sep 17 00:00:00 2001 From: Benjamin Sparks Date: Sun, 23 Mar 2025 23:36:32 +0100 Subject: [PATCH 2/4] python3Packages.nlopt: init --- pkgs/development/python-modules/nlopt/default.nix | 5 +++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 pkgs/development/python-modules/nlopt/default.nix diff --git a/pkgs/development/python-modules/nlopt/default.nix b/pkgs/development/python-modules/nlopt/default.nix new file mode 100644 index 000000000000..55bfc2d2884c --- /dev/null +++ b/pkgs/development/python-modules/nlopt/default.nix @@ -0,0 +1,5 @@ +{ + toPythonModule, + pkgs, +}: +toPythonModule (pkgs.nlopt.override { withPython = true; }) diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 9abac7174fad..cce6ef086220 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -10547,6 +10547,8 @@ self: super: with self; { nkdfu = callPackage ../development/python-modules/nkdfu { }; + nlopt = callPackage ../development/python-modules/nlopt { }; + nlpcloud = callPackage ../development/python-modules/nlpcloud { }; nlpo3 = callPackage ../development/python-modules/nlpo3 { }; From 1d15d511ae795718efdeb4c8ee8d2080c0b55d9a Mon Sep 17 00:00:00 2001 From: Benjamin Sparks Date: Tue, 8 Apr 2025 12:38:59 +0100 Subject: [PATCH 3/4] nlopt: add passthru.updateScript --- pkgs/development/libraries/nlopt/default.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/development/libraries/nlopt/default.nix b/pkgs/development/libraries/nlopt/default.nix index db7071ba429e..ec5effa6dae3 100644 --- a/pkgs/development/libraries/nlopt/default.nix +++ b/pkgs/development/libraries/nlopt/default.nix @@ -3,6 +3,7 @@ stdenv, fetchFromGitHub, cmake, + nix-update-script, # Optionally build Python bindings withPython ? false, python3, @@ -65,6 +66,8 @@ stdenv.mkDerivation (finalAttrs: { 'INTERFACE_INCLUDE_DIRECTORIES "''${_IMPORT_PREFIX}/' 'INTERFACE_INCLUDE_DIRECTORIES "' ''; + passthru.updateScript = nix-update-script { }; + meta = { homepage = "https://nlopt.readthedocs.io/en/latest/"; changelog = "https://github.com/stevengj/nlopt/releases/tag/v${finalAttrs.version}"; From 43a09052f12503bb63702977acf27f36e99c1e2c Mon Sep 17 00:00:00 2001 From: Benjamin Sparks Date: Sat, 12 Apr 2025 22:02:05 +0100 Subject: [PATCH 4/4] nlopt: 2.7.1 -> 2.10.0 v2.10.0 introduced / fixed: - Java bindings - Disabling Luksan solvers to allow licensing under the MIT license - Docs can now be built --- pkgs/development/libraries/nlopt/default.nix | 83 ++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/pkgs/development/libraries/nlopt/default.nix b/pkgs/development/libraries/nlopt/default.nix index ec5effa6dae3..51386f659748 100644 --- a/pkgs/development/libraries/nlopt/default.nix +++ b/pkgs/development/libraries/nlopt/default.nix @@ -2,33 +2,90 @@ lib, stdenv, fetchFromGitHub, + fetchpatch, cmake, nix-update-script, # Optionally build Python bindings withPython ? false, python3, python3Packages, - swig, # Optionally build Octave bindings withOctave ? false, octave, + # Optionally build Java bindings + withJava ? false, + jdk, + # Required for building the Python and Java bindings + swig, + # Optionally exclude Luksan solvers to allow licensing under MIT + withoutLuksanSolvers ? false, # Build static on-demand withStatic ? stdenv.hostPlatform.isStatic, + + # v2.8.0 introduced a regression where testing on Linux platforms fails with a buffer overflow + # when compiled with -D_FORTIFY_SOURCE=3. + # This was deemed to be a compiler false positive by the library's author in https://github.com/stevengj/nlopt/issues/563. + # Building with `clangStdenv` prevents this from occurring. + clangStdenv, }: let buildPythonBindingsEnv = python3.withPackages (p: [ p.numpy ]); + buildDocsEnv = python3.withPackages (p: [ + p.mkdocs + p.python-markdown-math + ]); in -stdenv.mkDerivation (finalAttrs: { +clangStdenv.mkDerivation (finalAttrs: { pname = "nlopt"; - version = "2.7.1"; + version = "2.10.0"; src = fetchFromGitHub { owner = "stevengj"; repo = "nlopt"; tag = "v${finalAttrs.version}"; - hash = "sha256-TgieCX7yUdTAEblzXY/gCN0r6F9TVDh4RdNDjQdXZ1o="; + hash = "sha256-mZRmhXrApxfiJedk+L/poIP2DR/BkV04c5fiwPGAyjI="; }; + outputs = [ + "out" + "doc" + ]; + + patches = [ + # 26-03-2025: `mkdocs.yml` is missing a link for the subpage related to the Java bindings. + # 26-03-2025: This commit was merged after v2.10.0 was released, and has not been made + # 26-03-2025: part of a release. + (fetchpatch { + name = "missing-java-reference-mkdocs"; + url = "https://github.com/stevengj/nlopt/commit/7e34f1a6fe82ed27daa6111d83c4d5629555454b.patch"; + hash = "sha256-XivfZtgIGLyTtU+Zo2jSQAx2mVdGLJ8PD7VSSvGR/5Q="; + }) + + # 26-03-2025: The docs pages still list v2.7.1 as the newest version. + # 26-03-2025: This commit was merged after v2.10.0 was released, and has not been made + # 26-03-2025: part of a release. + (fetchpatch { + name = "update-index-md"; + url = "https://github.com/stevengj/nlopt/commit/2c4147832eff7ea15d0536c82351a9e169f85e43.patch"; + hash = "sha256-BXcbNUyu20f3N146v6v9cpjSj5CwuDtesp6lAqOK2KY="; + }) + + # 26-03-2025: There is an off-by-one error in the test/CMakeLists.txt + # 26-03-2025: that causes the tests to attempt to run disabled Luksan solver code, + # 26-03-2025: which in turn causes the test suite to fail. + # 26-03-2025: See https://github.com/stevengj/nlopt/pull/605 + (fetchpatch { + name = "fix-nondisabled-luksan-algorithm"; + url = "https://github.com/stevengj/nlopt/commit/7817ec19f21be6877a4b79777fc5315a52c6850b.patch"; + hash = "sha256-KgdAMSYKOQuraun4HNr9GOx48yjyeQk6W3IgWRA44oo="; + }) + ]; + + postPatch = '' + substituteInPlace nlopt.pc.in \ + --replace-fail 'libdir=''${exec_prefix}/@NLOPT_INSTALL_LIBDIR@' 'libdir=@NLOPT_INSTALL_LIBDIR@' + ''; + nativeBuildInputs = [ cmake ] ## Building the python bindings requires SWIG, and numpy in addition to the CXX routines. @@ -37,6 +94,11 @@ stdenv.mkDerivation (finalAttrs: { swig buildPythonBindingsEnv ] + ## Building the java bindings requires SWIG, C++, JNI and Java + ++ lib.optionals withJava [ + swig + jdk + ] ## Building octave bindings requires `mkoctfile` to be installed. ++ lib.optional withOctave octave; @@ -49,16 +111,25 @@ stdenv.mkDerivation (finalAttrs: { (lib.cmakeBool "NLOPT_CXX" true) (lib.cmakeBool "NLOPT_PYTHON" withPython) (lib.cmakeBool "NLOPT_OCTAVE" withOctave) - (lib.cmakeBool "NLOPT_SWIG" withPython) + (lib.cmakeBool "NLOPT_JAVA" withJava) + (lib.cmakeBool "NLOPT_SWIG" (withPython || withJava)) (lib.cmakeBool "NLOPT_FORTRAN" false) (lib.cmakeBool "NLOPT_MATLAB" false) (lib.cmakeBool "NLOPT_GUILE" false) + (lib.cmakeBool "NLOPT_LUKSAN" (!withoutLuksanSolvers)) (lib.cmakeBool "NLOPT_TESTS" finalAttrs.doCheck) ] ++ lib.optional withPython ( lib.cmakeFeature "Python_EXECUTABLE" "${buildPythonBindingsEnv.interpreter}" ); + postBuild = '' + ${buildDocsEnv.interpreter} -m mkdocs build \ + --config-file ../mkdocs.yml \ + --site-dir $doc \ + --no-directory-urls + ''; + doCheck = true; postFixup = '' @@ -72,7 +143,7 @@ stdenv.mkDerivation (finalAttrs: { homepage = "https://nlopt.readthedocs.io/en/latest/"; changelog = "https://github.com/stevengj/nlopt/releases/tag/v${finalAttrs.version}"; description = "Free open-source library for nonlinear optimization"; - license = lib.licenses.lgpl21Plus; + license = if withoutLuksanSolvers then lib.licenses.mit else lib.licenses.lgpl21Plus; platforms = lib.platforms.all; maintainers = [ lib.maintainers.bengsparks ]; };