Opened 3 years ago

Closed 17 months ago

#63428 closed enhancement (wontfix)

openimageio: Also install static libraries

Reported by: MarkCallow (Mark Callow) Owned by: MarcusCalhoun-Lopez (Marcus Calhoun-Lopez)
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc: cooljeanius (Eric Gallager), mascguy (Christopher Nielsen)
Port: openimageio

Description

There is no static variant of openimageio. I found a statement in a message on the mailing list that said there are dynamic and static variants of all libraries. I don't know if this is truly a requirement.

I want to start using llibOpenImageIO in my CLI application. On macOS. since the app is signed, any .dylibs it loads also have to be signed which means I would have to include signed copies of the .dylibs with the application. Even if this were not the case, I would not want to have to tell users they have to install macports to run it. Installation of the signed .dylibs has the potential to interfere with somebody's macports installation. I would prefer therefore to include the code in the app by linking to static libraries.

Please add a static variant or just add static libraries to the build.

Change History (7)

comment:1 Changed 3 years ago by jmroot (Joshua Root)

Owner: set to MarcusCalhoun-Lopez
Port: openimageio added
Status: newassigned

comment:2 Changed 3 years ago by ryandesign (Ryan Carsten Schmidt)

Summary: No static variant of openimageioopenimageio: Also install static libraries
Type: defectenhancement

In MacPorts, a "variant" is a method by which a user can select which optional features of a port they want to install. "port variants foo" shows you the available variants of the port named "foo". We create variants sparingly. We want ports to have good defaults that match the needs of most users. Variants are only added when there are heavy optional features that most users would not want, or when the user may want to choose between multiple conflicting options, such as which branch of python the port should use.

Ports that install libraries that are intended to be used by others should always install dynamic libraries. Ports that link with other ports' libraries generally do so by dynamic linking. In most ports using the autotools build system, installing both dynamic and static libraries is the default, and if it is not the default, then it can usually be enabled with a simple configure flag (--enable-static and/or --enable-shared, whichever one(s) are not enabled by default in that project). This fact is probably why in MacPorts we recommend that ports should also install static libraries if possible, in case a user wants to use them for their own purposes. Unfortunately, other newer build systems, notably cmake, require the user to decide whether to build dynamic or static libraries and do not offer the ability to do both at once (unless the individual project that uses cmake has added custom code to their CMakeLists.txt to completely bypass the standard cmake way of creating libraries, and I can only think of one project that has done that (mongo-c-driver)). Therefore most ports that build using cmake can only install dynamic libraries. openimageio builds using cmake, therefore it probably can only offer dynamic libraries, not static libraries.

We would never offer variants for whether a port should install static or dynamic libraries. That would be giving users an opportunity to shoot themselves in the foot, and we try not to offer those opportunities. Consider port libao which offers an audio library called libao.4.dylib and which does not currently install a static library. Other ports in MacPorts that use libao link with libao.4.dylib. If we were to offer conflicting static and dynamic variants, then a user might install the port with the static variant instead of the dynamic variant. The port would then install libao.a but not libao.4.dylib, and that would break all of the ports that link with libao.4.dylib, and we don't want that.

A global solution to the problem of cmake only offering static or dynamic libraries would be to redesign the cmake portgroup so that it performs the entire configuration and build process twice: once for static libraries, a second time for dynamic libraries. This would be a big redesign of the cmake portgroup which would have the potential to introduce new bugs in the portgroup code or to reveal ways in which any of the hundreds of ports that already use the cmake portgroup are not compatible with that change. Testing those hundreds of ports after such a change would take a very long time, and committing the change without testing it thoroughly could just end up pushing undiscovered problems onto users. Even if there are no bugs and everything works correctly, running two configurations and builds instead of one will make builds slower. Also, not all ports that use the cmake build system use the cmake portgroup; those that don't would not benefit from the improvement. We do already have two different versions of the cmake portgroup and ports can decide which one to use. We could introduce the redesign in a new third version of the portgroup and ports could opt in to it over time as time permits. As far as I know, nobody has yet begun to work on such a redesign. A different approach could be to work with the developers of cmake to get them to offer an option to build both types of libraries in a single build. I haven't looked if anyone has yet proposed such a thing.

Since modifying the port to offer static libraries is going to be a problem, let's focus on what you actually need. You can use dynamic libraries from your program. If it were a normal app bundle, it would be a trivial matter of placing the libraries into a directory within your app bundle's Contents directory and changing the libraries' install names (and the references to them in your program) to use @executable_path. The dylibbundler program, installable via the dylibbundler port, automates these tasks for you. I'm not familiar with the process of signing, but I'm assuming that's not an insurmountable obstacle. If your program is just a command line program without an app bundle, that's not as nicely contained, but you can still create a directory at any path relative to where your program is installed, put the libraries in there, and dynamically link to them. Installing standalone software into /opt/<programname> is common, so if your program is called foo, then it could be reasonable for your installer to install your program at /opt/foo/bin/foo and its copies of libopenimageio and other libraries in /opt/foo/lib. If you use @executable_path, either manually or using dylibbundler, then the user can move or rename /opt/foo as desired. Another option that as far as I know Apple recommends would be for you to put your command line program and its libraries into an app bundle anyway. Many apps I have installed come with command line programs and libraries within their bundle. I don't think I've encountered one that's just a CLI without a GUI, but presumably there could be a way for you to write a very small GUI program that does nothing other than display a dialog referring the user to documentation about how to use the CLI, so that something useful happens if the user double-clicks your app.

Last edited 3 years ago by ryandesign (Ryan Carsten Schmidt) (previous) (diff)

comment:3 Changed 3 years ago by MarkCallow (Mark Callow)

@ryandesign, thank you for the comprehensive explanation of the issues.

let's focus on what you actually need.

Yes, making an app bundle is not an issue except for determining the full list of dylibs to include. This is needed for non-app-bundle builds too. OIIO appears to have a fairly lengthy dependency list. It sounds like dylibbundler will help with this. Thanks for the pointer. I'll look into it.

I am making a command line application that currently gets installed in /usr/local/{bin,lib}. I prefer not to have to update people's $PATH as would be necessary if installing somewhere under /opt. I've been thinking about putting the libraries in /usr/local/lib/<myapp>_support if static libraries are not possible, as appears to be the case. My app is signed and notarized which means it has to use the hardened run-time. I have read, but not verified myself, that relative paths to dylibs are not permitted in the hardened runtime so I may not be able to use @executable_path but that is a detail.

comment:4 Changed 3 years ago by kencu (Ken)

Don't forget that you are 100% in control of what happens on your local build.

If you need openimageio to be a static library for your project, make it so in your own local repo, build and distribute your app with the static library included, and then that is just how it is for you. Make all the libraries static if you so choose.

Just because MacPorts has standardized on dylibs does not mean you must do so for your own uses and purposes.

I have literally hundreds of my own applications and modifications that are appropriate for my local use, that for one reason or another I feel are not right for MacPorts in general.

Keep it straight if you do (custom prefix, etc) but MacPorts is very malleable and you can make it do a very great many things that are right for you.

comment:5 Changed 2 years ago by cooljeanius (Eric Gallager)

Cc: cooljeanius added

comment:6 Changed 17 months ago by mascguy (Christopher Nielsen)

Cc: mascguy added

comment:7 Changed 17 months ago by mascguy (Christopher Nielsen)

Resolution: wontfix
Status: assignedclosed

Per the earlier comments, static libs don't make sense for mass-consumption. But you're welcome to modify the port locally, and change to your needs.

Note: See TracTickets for help on using tickets.