From 8fa693ba4c6c12f11b641cff6c75962505ff7269 Mon Sep 17 00:00:00 2001 From: Rick Guo Date: Thu, 10 Sep 2026 11:22:14 +0800 Subject: [PATCH 1/2] formula: add stevengj/nlopt --- stevengj/nlopt/v2.6.1/nlopt_llar.gox | 171 +++++++++++++++++++++++++++ stevengj/nlopt/versions.json | 1 + 2 files changed, 172 insertions(+) create mode 100644 stevengj/nlopt/v2.6.1/nlopt_llar.gox create mode 100644 stevengj/nlopt/versions.json diff --git a/stevengj/nlopt/v2.6.1/nlopt_llar.gox b/stevengj/nlopt/v2.6.1/nlopt_llar.gox new file mode 100644 index 0000000..9481a91 --- /dev/null +++ b/stevengj/nlopt/v2.6.1/nlopt_llar.gox @@ -0,0 +1,171 @@ +import ( + "os" + "path/filepath" + "strings" +) + +const consumerSource = `#include + +static double objective(unsigned n, const double *x, double *grad, void *data) +{ + return x[0] * x[0]; +} + +int main(void) +{ + nlopt_opt opt = nlopt_create(NLOPT_LN_COBYLA, 1); + if (!opt) + return 1; + if (nlopt_set_min_objective(opt, objective, NULL) < 0) + return 1; + if (nlopt_set_xtol_rel(opt, 1e-6) < 0) + return 1; + + double x = 1.0; + double minf; + if (nlopt_optimize(opt, &x, &minf) < 0) + return 1; + nlopt_destroy(opt); + return 0; +} +` + +id "stevengj/nlopt" + +fromVer "v2.6.1" + +defaults { + "shared": "OFF", + "fPIC": "ON", + "enable_cxx_routines": "ON", +} + +filter => { + for name, values in target.options { + if name != "shared" && name != "fPIC" && name != "enable_cxx_routines" { + return false + } + for value in values { + if value != "ON" && value != "OFF" { + return false + } + } + } + return true +} + +onBuild ctx => { + installDir := ctx.outputDir + shared := target.options["shared"][0] == "ON" + fPIC := target.options["fPIC"][0] == "ON" + enableCxxRoutines := target.options["enable_cxx_routines"][0] == "ON" + + // NLopt versions before 2.8.0 force -fPIC for static builds. Conan removes + // those assignments so its fPIC option controls the build. + cmakeLists := filepath.join(ctx.SourceDir, "CMakeLists.txt") + source := string(os.readFile(cmakeLists)!) + source = strings.replace(source, `set (CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")`, "", 1) + source = strings.replace(source, `set (CMAKE_CXX_FLAGS "-fPIC ${CMAKE_CXX_FLAGS}")`, "", 1) + os.writeFile(cmakeLists, []byte(source), 0o644)! + for scriptPath in filepath.glob(filepath.join(ctx.SourceDir, "cmake", "generate-*.cmake"))! { + script := string(os.readFile(scriptPath)!) + script = strings.replace(script, "cmake_minimum_required (VERSION 2.8.11)", "cmake_minimum_required (VERSION 3.5)", 1) + script = strings.replace(script, "cmake_minimum_required (VERSION 3.2)", "cmake_minimum_required (VERSION 3.5)", 1) + os.writeFile(scriptPath, []byte(script), 0o644)! + } + + c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir) + c.define "CMAKE_INSTALL_LIBDIR", "lib" + c.define "CMAKE_POLICY_VERSION_MINIMUM", "3.5" + c.defineBool "BUILD_SHARED_LIBS", shared + c.defineBool "CMAKE_POSITION_INDEPENDENT_CODE", fPIC + c.defineBool "NLOPT_CXX", enableCxxRoutines + c.defineBool "NLOPT_FORTRAN", false + c.defineBool "NLOPT_PYTHON", false + c.defineBool "NLOPT_OCTAVE", false + c.defineBool "NLOPT_MATLAB", false + c.defineBool "NLOPT_GUILE", false + c.defineBool "NLOPT_SWIG", false + c.defineBool "NLOPT_TESTS", false + c.defineBool "WITH_THREADLOCAL", true + c.configure + c.build + c.install + + licenseDir := filepath.join(installDir, "licenses") + os.mkdirAll(licenseDir, 0o755)! + os.writeFile(filepath.join(licenseDir, "COPYING"), os.readFile(filepath.join(ctx.SourceDir, "COPYING"))!, 0o644)! + + for subdir, name in { + "ags": "COPYRIGHT", + "bobyqa": "COPYRIGHT", + "cobyla": "COPYRIGHT", + "direct": "COPYING", + "esch": "COPYRIGHT", + "luksan": "COPYRIGHT", + "newuoa": "COPYRIGHT", + "slsqp": "COPYRIGHT", + "stogo": "COPYRIGHT", + } { + subdirDir := filepath.join(licenseDir, subdir) + os.mkdirAll(subdirDir, 0o755)! + sourcePath := filepath.join(ctx.SourceDir, "src", "algs", subdir, name) + os.writeFile(filepath.join(subdirDir, name), os.readFile(sourcePath)!, 0o644)! + } + + osName := target.require["os"][0] + libs := ["-L$${libdir}", "-lnlopt"] + if osName == "linux" || osName == "freebsd" { + libs <- "-lm" + } + if !shared && enableCxxRoutines { + if osName == "darwin" { + libs <- "-lc++" + } else if osName != "windows" { + libs <- "-lstdc++" + } + } + + cflags := ["-I$${includedir}"] + if osName == "windows" && shared { + cflags <- "-DNLOPT_DLL" + } + + pcDir := filepath.join(installDir, "lib", "pkgconfig") + os.mkdirAll(pcDir, 0o755)! + pc := pkgconfig.new( + name = "NLopt", + description = "nonlinear optimization library", + version = "2.6.1", + libs = libs, + cflags = cflags, + )! + out := os.create(filepath.join(pcDir, "nlopt.pc"))! + pc.writeTo(out)! + out.close()! + + pkgconfig.use installDir + ctx.setMetadata pkgconfig.lookup("nlopt")! +} + +onTest ctx => { + installDir := ctx.outputDir + testDir := filepath.join(ctx.SourceDir, "_llar_consumer") + os.mkdirAll(testDir, 0o755)! + + consumer := filepath.join(testDir, "consumer.c") + os.writeFile(consumer, []byte(consumerSource), 0o644)! + + pkgconfig.use installDir + flagsFile := filepath.join(testDir, "nlopt.flags") + os.writeFile(flagsFile, []byte(pkgconfig.lookup("nlopt")!), 0o644)! + + binary := filepath.join(testDir, "consumer") + cc! consumer, "-o", binary, "@"+flagsFile + + if target.options["shared"][0] == "ON" { + os.setenv("LD_LIBRARY_PATH", filepath.join(installDir, "lib"))! + os.setenv("DYLD_LIBRARY_PATH", filepath.join(installDir, "lib"))! + } + exec! binary +} diff --git a/stevengj/nlopt/versions.json b/stevengj/nlopt/versions.json new file mode 100644 index 0000000..b9474f8 --- /dev/null +++ b/stevengj/nlopt/versions.json @@ -0,0 +1 @@ +{"path":"stevengj/nlopt","deps":{}} From fd42984945ae1db699816c4d913c3f6943643fbe Mon Sep 17 00:00:00 2001 From: Rick Guo Date: Thu, 10 Sep 2026 13:36:31 +0800 Subject: [PATCH 2/2] fix(nlopt): honor caller PIC option without source rewrite --- stevengj/nlopt/v2.6.1/nlopt_llar.gox | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/stevengj/nlopt/v2.6.1/nlopt_llar.gox b/stevengj/nlopt/v2.6.1/nlopt_llar.gox index 9481a91..7de8569 100644 --- a/stevengj/nlopt/v2.6.1/nlopt_llar.gox +++ b/stevengj/nlopt/v2.6.1/nlopt_llar.gox @@ -1,7 +1,6 @@ import ( "os" "path/filepath" - "strings" ) const consumerSource = `#include @@ -60,25 +59,16 @@ onBuild ctx => { fPIC := target.options["fPIC"][0] == "ON" enableCxxRoutines := target.options["enable_cxx_routines"][0] == "ON" - // NLopt versions before 2.8.0 force -fPIC for static builds. Conan removes - // those assignments so its fPIC option controls the build. - cmakeLists := filepath.join(ctx.SourceDir, "CMakeLists.txt") - source := string(os.readFile(cmakeLists)!) - source = strings.replace(source, `set (CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")`, "", 1) - source = strings.replace(source, `set (CMAKE_CXX_FLAGS "-fPIC ${CMAKE_CXX_FLAGS}")`, "", 1) - os.writeFile(cmakeLists, []byte(source), 0o644)! - for scriptPath in filepath.glob(filepath.join(ctx.SourceDir, "cmake", "generate-*.cmake"))! { - script := string(os.readFile(scriptPath)!) - script = strings.replace(script, "cmake_minimum_required (VERSION 2.8.11)", "cmake_minimum_required (VERSION 3.5)", 1) - script = strings.replace(script, "cmake_minimum_required (VERSION 3.2)", "cmake_minimum_required (VERSION 3.5)", 1) - os.writeFile(scriptPath, []byte(script), 0o644)! - } - c := cmake.new(ctx.SourceDir, filepath.join(ctx.SourceDir, "_build"), installDir) c.define "CMAKE_INSTALL_LIBDIR", "lib" c.define "CMAKE_POLICY_VERSION_MINIMUM", "3.5" c.defineBool "BUILD_SHARED_LIBS", shared c.defineBool "CMAKE_POSITION_INDEPENDENT_CODE", fPIC + if !shared && !fPIC { + // The v2.6.1 CMakeLists probes HAS_FPIC before adding a global -fPIC + // flag. Pre-seed that probe so fPIC=OFF remains caller-controlled. + c.defineBool "HAS_FPIC", false + } c.defineBool "NLOPT_CXX", enableCxxRoutines c.defineBool "NLOPT_FORTRAN", false c.defineBool "NLOPT_PYTHON", false