ROOT Dynamic Library Path

Hi,

Previously I was able to create libraries to extend the functionality of ROOT. By adding their path to (DY)LD_LIBRARY_PATH one could simply type gSystem->Load("libRary.dylib"). This unfortunately is no longer possible on Mac OSX 10.12 as the use of DYLD_LIBRARY_PATH has been depreciated. I could simply put the whole path to the library, but asking other users to do this becomes unreasonable. I see a message when one evokes the gSystem::Load method without the proper path that there may be a internal search path:

Error in <TRint::ProcessLine>: macro libRary.dylib not found in path .:/opt/root/root-6.08.06/macros:

Is there anyway to extend this path? Possibly the LIBRARY_PATH used by gcc? My preference here is that the user would setup there environment in some way and upon evoking root the library will be available for use without any further input.

Thanks

Hi,

That’s Apple’s “System Integrity Protection”. AFAIK, LD_LIBRARY_PATH is only ignored for binaries in /usr etc: https://support.apple.com/en-us/HT204899. If your ROOT is in /opt I would have expected it to work.

Either way, installing it into /home/your-user/root/ should also fix this.

Cheers, Axel.

Hi,

It is worse then that. The export command ignores all DYLD_ environment variables and as I understand it all protected processes continuously purge these variables as well. This makes the variable useless as it is always being unset. https://developer.apple.com/library/content/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html

Yeah but the important part is protected processes. Putting it into $HOME should leave ROOT unprotected. Which is a good thing :wink: Just try!

Axel.

I will give it a try, but I’m not sure I understand. For example, if I use the thisroot.sh script to setup the root environment and then I run a simple ls it will unset the DYLD_LIBRARY_PATH and then I’m back to square one. (This is similar to what I wanted to do: user loads a bash script to setup the environment for additional ROOT libraries and then starts root.)

Also, it is unreasonable for me to ask all the other users of the software to install ROOT into $HOME, so it is not a great solution.

Hi,

Calling ls doesn’t unset the env var in the current process, but only in sub-processes. E.g. if you use python's subprocess, or make. So it all depends on the location of ROOT. I see three options:

  • sign ROOT (unlikely, involves lots of Apple interaction)
  • install ROOT into an unprotected area
  • disable SIP.

Out of those, the second looks like the most reasonable.

Cheers, Axel.

Alright, to me they all sound unreasonable.

  • signing ROOT, I haven’t had success with this in the past and asking a user to do it would be too difficult.
  • install ROOT into an unprotected area, many users use package managers to install ROOT and I can’t decide where they put it.
  • disable SIP, although some users would do this, I’m not sure 100% will and especially for the gains in this project.

Thanks for the help. Looks like I’m stuck at the moment.

To get back to the original question though where are these directories coming from? They surely are not in my DYLD_LIBRARY_PATH:

[0] gSystem->Load("libRary.dylib")
Error in <TRint::ProcessLine>: macro libRary.dylib not found in path .:/opt/root/root-6.08.06/macros:

Hi,

Right - good question, that should also allow us to solve this.

First of all I’d like to understand why I get a different error message:

root [6] gSystem->Load("libhpxkjlkjl.kjdlkjfg")
Error in <TMacOSXSystem::FindDynamicLibrary>: libhpxkjlkjl.kjdlkjfg[.so | .dll | .dylib | .sl | .dl | .a] does not exist in ...

That’s what I’d expect to see. And I get this in both ROOT 6-08-00-patches and the master. So either we changed something since 6.08.06 that I am not aware of, or your ROOT isn’t the ROOT version I expect it to be.

Cheers, Axel.

Ahh my bad. I thought .L library.dylib and gSystem->Load("library.dylib") executed the same code, this is not the case:

root [0] gSystem->Load("libRary.dylib")
Error in <TMacOSXSystem::FindDynamicLibrary>: libRary.dylib does not exist in /opt/root/root-6.08.06/lib:::.:/opt/root/root-6.08.06/lib::/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:
(int) -1
root [1] .L libRary.dylib
Error in <TRint::ProcessLine>: macro libRary.dylib not found in path .:/opt/root/root-6.08.06/macros:

I was replying away from my production machine and just tossed the two outputs into a code block without trying it, should have checked. I was confused as the either of the following work for loading libraries:

root [2] .L ~/library/install/lib/libRary.dylib
root [3] gSystem->Load("~/library/install/lib/libRary.dylib")
(int) 1

Okay, good. Do you have a ROOT install in /opt such that we can try things out?

If so, could you run

LD_LIBRARY_PATH=foo:$LD_LIBRARY_PATH root -l -b
root [0] printf("%s\n", getenv("LD_LIBRARY_PATH"))

and send the output?

Axel.

With LD_LIBRARY_PATH on Mac OS X 10.12 Sierra

$ LD_LIBRARY_PATH=foo:$LD_LIBRARY_PATH root -l -b
root [0] printf("%s\n", getenv("LD_LIBRARY_PATH"))
foo:
(int) 5

and with DYLD_LIBRARY_PATH

DYLD_LIBRARY_PATH=foo:$DYLD_LIBRARY_PATH root -l -b
root [0] printf("%s\n", getenv("DYLD_LIBRARY_PATH"))
/opt/root/root-6.08.06/lib:foo:
(int) 32

For completeness:

$ DYLD_LIBRARY_PATH=~/library/install/lib/ root -l
root [0] printf("%s\n", getenv("DYLD_LIBRARY_PATH"))
/opt/root/root-6.08.06/lib:/Users/user/library/install/lib/
(int) 66
root [1] .L libRary.dylib
Error in <TRint::ProcessLine>: macro libRary.dylib not found in path .:/opt/root/root-6.08.06/macros:
root [2] gSystem->Load("libRary.dylib")
(int) 0
root [3]

It seems that the .L libRary.dylib command does not follow DYLD_LIBRARY_PATH, but will use absolute paths and gSystem::Load works for either case.

Or you use (DY)LD_LIBRARY_PATH and gSystem->Load("libRary.dylib") - that works, too, right? Is that an option? Problem solved?

I believe this issue has been resolved. The misunderstanding was two fold:

  1. Mac OS X 10.12 does not display the value of [DY]LD_* environemnt variables when using printenv. Tis leads one to thinking that those environment variables are not set.
  2. .L libRary.dylib does not follow [DY]LD_LIBRARY_DIR, but will load libraries if it finds them. This is confusing as it sometimes works and sometimes doesn’t. The error message provided lists search paths for macros not libraries. The solution here is to use gSystem::Load which is often confused as the same command, but will follow the [DY]LD_LIBRARY_PATH.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.