libprima / prima

PRIMA is a package for solving general nonlinear optimization problems without using derivatives. It provides the reference implementation for Powell's derivative-free optimization methods, i.e., COBYLA, UOBYQA, NEWUOA, BOBYQA, and LINCOA. PRIMA means Reference Implementation for Powell's methods with Modernization and Amelioration, P for Powell.
http://libprima.net
BSD 3-Clause "New" or "Revised" License
291 stars 35 forks source link

Static vs shared libs? #125

Closed nbelakovski closed 6 months ago

nbelakovski commented 6 months ago

Pinging @jschueller, please feel free to ping others as well.

We currently build shared libraries, and there was some non-trivial effort to set this up correctly across multiple platforms as seen in https://github.com/libprima/prima/issues/70 and https://github.com/libprima/prima/pull/77.

However, with Python bindings this becomes a bit of a challenge since we need to ship the shared libraries along with the built python module (itself a shared library). Maybe there are routine ways to handle this, but I know this can be frustrating even when you think you have it figured out, and triply so on Windows.

Building static libs would mean that we could link them statically into the Python module and then we'd only have a single file to distribute which would be much easier.

I'm wondering why we build shared libs in the first place? Admittedly linking the static library into each of the examples balloons them from some 50kB up to ~1.7MB each in my testing, but a) since these libraries are not used in embedded applications, where even 50kB of space can be a lot, this seems to be a non-issue, and b) I would imagine most users are only building a handful of executables linking this code, perhaps just 1. I'm no expert on shared vs static so I would appreciate if others have additional viewpoints to contribute.

If there's a strong reason to have shared libraries, we could build both static and shared libraries. It'll take a few extra lines of CMake but nothing outlandish.

To summarize:

  1. Do we need shared libraries or can we switch the build to default to static libraries?
  2. If we do need shared libraries, are there any issues with building both shared and static, and if not would the naming convention primaf_static and primaf_shared be reasonable?
jschueller commented 6 months ago
nbelakovski commented 6 months ago

Why does shared ease inclusion in linux distros and conda?

jschueller commented 6 months ago

they only use shared libs there, so it matches our default

nbelakovski commented 6 months ago

Are there some docs about linux distros only using shared libraries? This seems like a strange thing for linux to enforce and it's been a while, but I was under the impression I had installed static libs on linux distros before (perhaps when installed the -dev version of a package).

jschueller commented 6 months ago

there are some exceptions of course

nbelakovski commented 6 months ago

This discussion wasn't quite as robust as I was hoping, but I think it does not matter as much as I initially thought. Since BUILD_SHARED_LIBS is an option, I can simply set it to False when making the Python bindings, and basically sidestep this whole issue.