As this has cost me almost three months it might be interesting for others who
also might not have
known all these details on the different platforms.
RPATH (run path) is available on Linux and MacOS for binaries/libraries. When a
binary/library is
linked against other libraries dlopen() is responsible to find and link those
other linked libraries
following the platforms rules (e.g. looking up /usr/lib, /usr/local/lib,
/usr/lib64,
/usr/local/lib64 etc.). If RPATH is defined in the loaded library dlopen() will
consult the RPATH
directories in the given order to resolve the external links.
ooRexx defines RPATH for its binaries/libraries to be
"@executable_path/../lib". This has the effect
of looking up the sibling directory "lib" which works for the ooRexx
executables in "bin" as well as
for libraries in "lib" as libraries get always resolved to "lib". It does not
matter where the
binaries are located in this system as the path to the "lib" directory is
always relative to the
location of the binary. This works on Linux and MacOS.
In the case that there is a need to add multiple paths to RPATH things become
different on Linux and
MacOS as it has turned out, the error message would not be specific and
generally just state that
the image was not found, quite unRexxish causing lots of troubles and lost time!
Multiple RPATH directores became necessary for libBSF4ooRexx.{so|dylib} to
allow flexible ("stick")
deployments of BSF4ooRexx in combination with ooRexx which needs to be
successfully found in order
to link to the ooRexx libraries. The following use cases should be covered when
loading
libBSF4ooRexx.{so|dylib} (which may be triggered by Java at the time a Java
program requests an
ooRexx scripting engine):
1. All binaries and ooRexx libraries are stored in the same physical directory
(no matter where),
2. the binaries are in some directory (like "bin") the ooRexx libraries in the
sibling directory
"lib" (which is the standard ooRexx layout and used in the definition for
its RPATH),
3. use the standard ooRexx installation, the ooRexx libraries get installed
to: "/usr/[local/]lib[64]",
4. an optional installation of ooRexx available in "/opt/ooRexx/lib",
5. on MacOS a Framework installation
("/Library/Frameworks/ooRexx.framework/Libraries")
Whichever ooRexx libraries get found first, win. This way it can be assured
that if a BSF4ooRexx
application includes a specific version of ooRexx that that version gets used.
If a BSF4ooRexx
application just has a need for ooRexx it also can use the installed version of
ooRexx, etc.
The Linux version of BSF4ooRexx defines the following RPATH therefore (using
$ORIGIN for the
directory from which the binary/library got loaded from):
RPATH =
-rpath,$$'ORIGIN':$$'ORIGIN'/../lib:/usr/local/lib64:/usr/lib64:/usr/local/lib:/usr/lib:/opt/ooRexx/lib
which works on Linux. The RPATH is a colon separated list of directories to
look up for resolving
external links.
---
The MacOS version of BSF4ooRexx defined RPATH got defined to be (using
@loader_path for the
directory from which the library got loaded from):
RPATH =
@loader_path:@loader_path/../lib:/usr/local/lib:/opt/oorexx/lib:/Library/Frameworks/ooRexx.framework/Libraries
This seemed to have worked on Intel MacOS, but not on M1 (the Apple ARM chip
for its new series of
computers) where simply the ooRexx libraries were not found, not even in
/usr/local/lib where they
were available. Short of an M1 computer I worked with a student who already had
one (quite
surprising many students own an M1 already) and it took almost three months to
get to the source of
the problem: setting the MacOS RPATH does not handle colon-delimited PATHs
correctly. The MacOS
dlopen() takes the RPATH definition as a single path.
So in order to define multiple RPATH directories to look-up it is necessary to
give separate -rpath
definitions at link time! (On Linux it is also possible to define separate
-rpath definitions, which
seem to be merged into a single, colon-delimited RPATH.)
Here the working MacOS RPATH definition ($RPATH being used in the link command):
RPATH =-rpath @loader_path -rpath @loader_path/../lib -rpath /usr/local/lib
-rpath
/opt/ooRexx/lib -rpath /Library/Frameworks/ooRexx.framework/Libraries
For the record the mulitple rpath definitions for Linux would look like:
RPATH=-rpath,$$'ORIGIN',-rpath,$$'ORIGIN'/../lib,-rpath,/usr/local/lib64,-rpath,/usr/lib64,-rpath,/usr/local/lib,-rpath,/usr/lib,-rpath,/opt/ooRexx/lib
---
Here links to RPATH for Linux (watch out, RPATH gets now automatically changed
to RUNPATH at link
time, unless you define the "--disable-new-dtags" switch!), MacOS, but also to
CMake which allows
multiple RPATH directories (but you must delimit them with a semi-colon ; and
not with a colon :):
CMAKE related:
* CMAKE RPATH handling:
<https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling>
* About CMAKE with mulitple RPATH directories on MacOS:
<https://stackoverflow.com/questions/40146437/how-to-set-multiple-rpath-directories-using-cmake-on-macos>
Linux related:
* Michael Kerrisk, "Building and Using Shared Libraries on Linux - Shared
Libraries: The Dynamic
Linker": <http://man7.org/training/download/shlib_dynlinker_slides.pdf>
* Luke Chen, "Creating relocatable Linux executables by setting RPATH with
$ORIGIN":
<https://nehckl0.medium.com/creating-relocatable-linux-executables-by-setting-rpath-with-origin-45de573a2e98>
MacOS related:
* Marcin Krzyżanowski, "@rpath what?" (MacOS):
<https://blog.krzyzanowskim.com/2018/12/05/rpath-what/>
* Chris Hamons, "Fun with rpath, otool, and install_name_tool" (MacOS):
<https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172>
* "@executable path, @load path and @rpath" (MacOS):
<https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath>
---rony
_______________________________________________
Oorexx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/oorexx-devel