gogins / csound-ac

A C++ library for algorithmic composition, designed to be used with Csound, with both C++ and Python interfaces.
GNU Lesser General Public License v2.1
6 stars 0 forks source link

Fix incorrect `rpath` entries #15

Closed gogins closed 1 year ago

gogins commented 1 year ago

Excellent reference for where to put things when not using a package manager: https://stackoverflow.com/questions/35337601/why-is-there-a-usr-local-opt-directory-created-by-homebrew-and-should-i-use-it. Normally:

Contents of archive go into /usr/opt/<package>.<version>. Symlinks are created from files in /usr/opt/<package>.<version> to versionless entries in /usr/local.

I'm trying to minimize maintenance for myself, so I'll just make sure that there is an rpath for /usr/local.

gogins commented 1 year ago

The playpen post processing is not working.

gogins commented 1 year ago

https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling

gogins commented 1 year ago

Finally somebody who seems to know how to actually explain things: https://github.com/qyang-nj/llios/blob/main/macho_parser/docs/LC_dylib.md which references an even clearer explanation:

@rpath While the above is sufficient for anything in theory, it can be troublesome in practice. The problem is that a single copy of a library can only be used in one way. If you want Foo.framework to work when embedded in an application or when installed to /Library/Frameworks, you have to provide two separate copies with two different install names. (Or manually tweak install names later on using install_name_tool.) This is doable, but annoying.

Starting in 10.5, Apple provides @rpath, which is a solution to this. When placed at the front of an install name, this asks the dynamic linker to search a list of locations for the library. That list is embedded in the application, and can therefore be controlled by the application's build process, not the framework's. A single copy of a framework can thus work for multiple purposes.

To make this work, Foo.framework's install name would be set to @rpath/Foo.framework/Versions/A/Foo. An application that intends to embed Foo.framework would then pass -rpath @executable_path/../Frameworks to the linker at build time, which tells the dynamic linker to search for @rpath frameworks there. An application that intends to install the framework would pass -rpath /Library/Frameworks, telling the dynamic linker to search there. An application that for some reason doesn't want to commit to one or the other at build time can just pass both sets of parameters, which will cause the dynamic linker to try both locations.

gogins commented 1 year ago

So what I need to do is put a number of LC_RPATH entries into the binary. I think LC_ID_DYLIB is OK already. I should put in LC_RPATH entries for /usr/local/lib, and also for ~.local/lib. See the this for how to that with CMake: https://stackoverflow.com/questions/40146437/how-to-set-multiple-rpath-directories-using-cmake-on-macos

gogins commented 1 year ago

After also adding -Wl,-rpath,/usr/local/lib to the playpen.ini build command for Darwin , everything compiles and runs, both Python and C++.