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