Using macports to create binary package
ryandesign at macports.org
Fri Jul 20 19:01:55 UTC 2018
On Jul 20, 2018, at 13:24, Manav Bhatia wrote:
> No GUI. My app is a terminal application with plenty of dependencies. My users are at places and on systems without root access.
> I am not sure what the best approach is here, but I am looking at various options where I can distribute precompiled binaries.
> Dylibbundler sounds interesting but I have no experience to try to judge its limitations.
> I am also looking at CPack (from cmake), which seems to have some promise as it is cross-platform compatible, so I can use the same cmake configuration script to create bundles on Mac and Linux.
> I need these to work in non-standard, non-root locations.
> This should not be so difficult.
It's important to realize that macOS and Linux use different executable formats. Mac uses Mach-O, and Linux uses ELF, and they are not the same, and they were designed with different goals in mind and different capabilities. So a solution that works on Linux won't necessarily work on macOS, and vice versa.
On macOS, a library contains the absolute path to where it is installed. The is called its "install_name" and it is set at build time. If the library is later moved on disk, install_name_tool must be used to update the library's install_name to its new location. Similarly, any program (or other library) that links with that library does so by its install_name. If the library is moved, install_name_tool must be used to update the reference to the library in the program (or other library).
It is also possible to set install_names that are relative to one of several different places, instead of absolute. For example, you could set the install_name to be relative to the path of the program that loaded it. This is not appropriate for libraries that are meant to be used by many different programs that might be in many different locations -- this is the situation we have in MacPorts, which is why MacPorts does not attempt to use relative paths for libraries. But if you are creating a standalone package for one program (or a few related programs), such that you can dictate the relative paths between all the programs and libraries, and you want that standalone package to be relocatable, then you could use relative paths in the install_names.
dylibbundler automates the process of running the necessary install_name_tool commands to change absolute install_names to relative ones. However I believe it also assumes that what it is producing is a standard macOS application bundle. If you're not producing an app but instead just a directory of programs and libraries, you will have to see if you can use dylibbundler's various flags to produce the desired file layout.
For the purposes of dylibbundler, it does not matter if the programs and libraries that it is changing came from our build server's binaries or were compiled by you on your computer. However, for your project, it may matter. For example, you may wish to distribute something that runs on 10.9 or later, but you are running on 10.13. The binaries compiled on our build server for 10.13 are intended for use on 10.13 only. If you want to compile something on 10.13 that can still run on 10.9, you have to set MACOSX_DEPLOYMENT_TARGET to 10.9. MacPorts allows you to specify this in macports.conf, but for it to take effect, you have to compile ports yourself; binaries you get from us won't respect that setting. Alternately, you could prepare your package on a system running 10.9. You'll be able to use MacPorts 10.9 binaries, and they should work on later systems, though of course they won't be able to use any capabilities introduced in later macOS versions.
As Craig said, making the programs and libraries use relative install_names may not be all you need to do. The absolute install path might also be baked into the programs in other ways. You can grep all of the files you plan to distribute and see if they contain the old install path. If so, you'll have to investigate what needs to be done to fix it. Unfortunately, there is not a one-size-fits-all solution for this.
More information about the macports-users