From 7d0939829d6455eb211fed90c9345ae3593d7812 Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Thu, 31 Oct 2024 15:28:44 +0100 Subject: [PATCH] CMake: Add NLOPT_LUKSAN option --- .github/workflows/build.yml | 4 ++-- CMakeLists.txt | 14 +++++++++++--- COPYING | 15 +++++++-------- README.md | 22 +++------------------- doc/docs/NLopt_Installation.md | 8 ++++++++ src/api/optimize.c | 17 +++++++++++++++++ test/CMakeLists.txt | 7 +++++++ 7 files changed, 55 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 733f4393..819229e7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,10 +12,10 @@ jobs: PATH=$PATH:~/.local/bin mkdocs build mkdir build && pushd build cmake -DCMAKE_INSTALL_PREFIX=~/.local -DNLOPT_FORTRAN=ON -DCMAKE_C_FLAGS='-std=c89 -pedantic -D_POSIX_C_SOURCE=200809L -Wall -Wextra -Wshadow' -DCMAKE_CXX_FLAGS='-Wall -Wextra -pedantic -Wshadow' -DSWIG_COMPILE_FLAGS="-Wno-unused-parameter -Wno-missing-field-initializers" .. - make install -j2 && ctest -j2 --output-on-failure + make install -j4 && ctest -j4 --output-on-failure rm -rf * ~/.local cmake -DCMAKE_INSTALL_PREFIX=~/.local -DNLOPT_PYTHON=OFF -DNLOPT_OCTAVE=OFF -DNLOPT_GUILE=OFF -DNLOPT_FORTRAN=ON -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/toolchain-x86_64-w64-mingw32.cmake .. - make install -j2 + make install -j4 macos: runs-on: macos-latest diff --git a/CMakeLists.txt b/CMakeLists.txt index 8deb3f94..5cf9a0b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ option (NLOPT_OCTAVE "build octave bindings" ON) option (NLOPT_MATLAB "build matlab bindings" OFF) option (NLOPT_GUILE "build guile bindings" ON) option (NLOPT_SWIG "use SWIG to build bindings" ON) +option (NLOPT_LUKSAN "enable LGPL Luksan solvers" ON) if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) option (NLOPT_TESTS "build unit tests" ON) @@ -195,7 +196,6 @@ set (NLOPT_SOURCES src/algs/direct/DIRect.c src/algs/direct/direct_wrap.c src/algs/direct/DIRserial.c src/algs/direct/DIRsubrout.c src/algs/direct/direct-internal.h src/algs/direct/direct.h src/algs/cdirect/cdirect.c src/algs/cdirect/hybrid.c src/algs/cdirect/cdirect.h src/algs/praxis/praxis.c src/algs/praxis/praxis.h - src/algs/luksan/plis.c src/algs/luksan/plip.c src/algs/luksan/pnet.c src/algs/luksan/mssubs.c src/algs/luksan/pssubs.c src/algs/luksan/luksan.h src/algs/crs/crs.c src/algs/crs/crs.h src/algs/mlsl/mlsl.c src/algs/mlsl/mlsl.h src/algs/mma/mma.c src/algs/mma/mma.h src/algs/mma/ccsa_quadratic.c @@ -211,6 +211,12 @@ set (NLOPT_SOURCES src/util/mt19937ar.c src/util/sobolseq.c src/util/soboldata.h src/util/timer.c src/util/stop.c src/util/nlopt-util.h src/util/redblack.c src/util/redblack.h src/util/qsort_r.c src/util/rescale.c ) +if(NLOPT_LUKSAN) + list(APPEND NLOPT_SOURCES + src/algs/luksan/plis.c src/algs/luksan/plip.c src/algs/luksan/pnet.c src/algs/luksan/mssubs.c src/algs/luksan/pssubs.c src/algs/luksan/luksan.h) +endif() + + set_property(SOURCE src/algs/bobyqa/bobyqa.c src/algs/cdirect/hybrid.c src/algs/mma/ccsa_quadratic.c src/algs/cobyla/cobyla.c src/util/redblack.c src/algs/neldermead/nldrmd.c src/algs/newuoa/newuoa.c src/util/qsort_r.c PROPERTY SKIP_UNITY_BUILD_INCLUSION ON) @@ -252,8 +258,11 @@ install (FILES ${NLOPT_HEADERS} DESTINATION ${NLOPT_INSTALL_INCLUDEDIR}) set (nlopt_lib nlopt) add_library (${nlopt_lib} ${NLOPT_SOURCES}) add_dependencies(${nlopt_lib} generate-cpp) +if (NLOPT_LUKSAN) + target_include_directories(${nlopt_lib} PRIVATE src/algs/luksan) + target_compile_definitions (${nlopt_lib} PRIVATE NLOPT_LUKSAN) +endif () target_link_libraries (${nlopt_lib} ${M_LIBRARY}) - set_target_properties (${nlopt_lib} PROPERTIES SOVERSION ${SO_MAJOR}) set_target_properties (${nlopt_lib} PROPERTIES VERSION "${SO_MAJOR}.${SO_MINOR}.${SO_PATCH}") @@ -269,7 +278,6 @@ target_include_directories (${nlopt_lib} PRIVATE src/algs/direct src/algs/cdirect src/algs/praxis - src/algs/luksan src/algs/crs src/algs/mlsl src/algs/mma diff --git a/COPYING b/COPYING index f3d4c84c..884683df 100644 --- a/COPYING +++ b/COPYING @@ -5,20 +5,19 @@ information of these packages. The compiled NLopt library, i.e. the combined work of all of the included optimization routines, is licensed under the conjunction of -all of these licensing terms. Currently, the most restrictive terms +all of these licensing terms. By default, the most restrictive terms are for the code in the "luksan" directory, which is licensed under the GNU Lesser General Public License (GNU LGPL), version 2.1 or -later (see luksan/COPYRIGHT). - -That means that the compiled NLopt library is governed by the terms of -the LGPL. +later (see luksan/COPYRIGHT). That means that, by default, the compiled +NLopt library is governed by the terms of the LGPL. --------------------------------------------------------------------------- -Other portions of NLopt, including any modifications to the abovementioned -packages, are licensed under the standard "MIT License:" +However, NLopt also offers the option to be built without the code in +the "luksan" directory. In this case, NLopt, including any modifications +to the abovementioned packages, are licensed under the standard "MIT License:" -Copyright (c) 2007-2011 Massachusetts Institute of Technology +Copyright (c) 2007-2024 Massachusetts Institute of Technology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index 13024f06..907d0c85 100644 --- a/README.md +++ b/README.md @@ -7,27 +7,11 @@ a simple, unified interface and packaging of several free/open-source nonlinear optimization libraries. The latest release can be downloaded from the [NLopt releases](https://github.com/stevengj/nlopt/releases) page on Github, and the -[NLopt manual]( -https://nlopt.readthedocs.io/en/latest/) is hosted on readthedocs. +[NLopt manual](https://nlopt.readthedocs.io/en/latest/) is hosted on readthedocs. -NLopt is compiled and installed with the [CMake](https://cmake.org/) build system -(see `CMakeLists.txt` file for available options): +To build it refer to the [installation instructions](https://nlopt.readthedocs.io/en/latest/#download-and-installation). - git clone https://github.com/stevengj/nlopt.git - cd nlopt - mkdir build - cd build - cmake .. - make - sudo make install - -(To build the latest development sources from git, you will need [SWIG](http://www.swig.org/) -to generate the Python and Guile bindings.) - -Once it is installed, `#include ` in your C/C++ programs and -link it with `-lnlopt -lm`. You may need to use a C++ compiler to link -in order to include the C++ libraries (which are used internally by NLopt, -even though it exports a C API). See the [C reference manual](https://nlopt.readthedocs.io/en/latest/NLopt_Reference/). +To use in your C/C++ programs see the [C reference manual](https://nlopt.readthedocs.io/en/latest/NLopt_Reference/). There are also interfaces for [C++](https://nlopt.readthedocs.io/en/latest/NLopt_C-plus-plus_Reference/), [Fortran](https://nlopt.readthedocs.io/en/latest/NLopt_Fortran_Reference/), [Python](https://nlopt.readthedocs.io/en/latest/NLopt_Python_Reference/), [Matlab or GNU Octave](https://nlopt.readthedocs.io/en/latest/NLopt_Matlab_Reference/), [OCaml](https://bitbucket.org/mkur/nlopt-ocaml), [GNU Guile](https://nlopt.readthedocs.io/en/latest/NLopt_Guile_Reference/), [GNU R](https://www.ucl.ac.uk/~uctpjyy/nloptr.html), [Lua](https://github.com/rochus-keller/LuaNLopt), [Rust](https://github.com/jesskfullwood/rust-nlopt), and [Julia](https://github.com/JuliaOpt/NLopt.jl). Interfaces for other languages may diff --git a/doc/docs/NLopt_Installation.md b/doc/docs/NLopt_Installation.md index b78b7f91..028e9e74 100644 --- a/doc/docs/NLopt_Installation.md +++ b/doc/docs/NLopt_Installation.md @@ -158,3 +158,11 @@ however, it will disable algorithms implemented in C++ (StoGO and AGS algorithms The resulting library has the *same* interface as the ordinary NLopt library, and can *still* be called from ordinary C, C++, and Fortran programs. However, one no longer has to link with the C++ standard libraries, which can sometimes be convenient for non-C++ programs, and allows libnlopt to be compatible with multiple C++ compilers simultaneously. +LGPL solvers +------------ + +It is possible to build NLopt as fully permissive library by disabling the LGPL Luksan solvers with: + +```sh +cmake -DNLOPT_LUKSAN=OFF .. +``` diff --git a/src/api/optimize.c b/src/api/optimize.c index ab89e1d2..887d22fb 100644 --- a/src/api/optimize.c +++ b/src/api/optimize.c @@ -38,7 +38,9 @@ #include "cdirect.h" +#ifdef NLOPT_LUKSAN #include "luksan.h" +#endif #include "crs.h" @@ -590,17 +592,32 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf) } case NLOPT_LD_LBFGS: +#ifdef NLOPT_LUKSAN return luksan_plis(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage); +#else + printf("ERROR - attempting to use NLOPT_LD_LBFGS, but Luksan code disabled\n"); + return NLOPT_INVALID_ARGS; +#endif case NLOPT_LD_VAR1: case NLOPT_LD_VAR2: +#ifdef NLOPT_LUKSAN return luksan_plip(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage, algorithm == NLOPT_LD_VAR1 ? 1 : 2); +#else + printf("ERROR - attempting to use NLOPT_LD_VAR*, but Luksan code disabled\n"); + return NLOPT_INVALID_ARGS; +#endif case NLOPT_LD_TNEWTON: case NLOPT_LD_TNEWTON_RESTART: case NLOPT_LD_TNEWTON_PRECOND: case NLOPT_LD_TNEWTON_PRECOND_RESTART: +#ifdef NLOPT_LUKSAN return luksan_pnet(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage, 1 + (algorithm - NLOPT_LD_TNEWTON) % 2, 1 + (algorithm - NLOPT_LD_TNEWTON) / 2); +#else + printf("ERROR - attempting to use NLOPT_LD_TNEWTON*, but Luksan code disabled\n"); + return NLOPT_INVALID_ARGS; +#endif case NLOPT_GN_CRS2_LM: if (!finite_domain(n, lb, ub)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6106dba8..1815343a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -58,6 +58,13 @@ foreach (algo_index RANGE 29)# 43 if (CMAKE_HOST_SYSTEM_NAME MATCHES Windows) set_tests_properties (testopt_algo${algo_index}_obj${obj_index} PROPERTIES ENVIRONMENT "PATH=${PROJECT_BINARY_DIR}\\${CMAKE_BUILD_TYPE};$ENV{PATH}") # to load dll endif () + # Check if LUKSAN targets are available. + if (NOT NLOPT_LUKSAN) + set (list_of_algorithms_requiring_luksan 11 12 13 14 15 16 17 18) + if (algo_index IN_LIST list_of_algorithms_requiring_luksan) + set_tests_properties (testopt_algo${algo_index}_obj${obj_index} PROPERTIES DISABLED TRUE) + endif() + endif() endif () endforeach () endforeach ()