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
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to