gcc / libgomp and @rpath on OS X

0 views
Skip to first unread message

Dougal Sutherland

unread,
May 9, 2016, 4:43:52 AM5/9/16
to conda - Public
Hi,

I'm having some trouble getting a conda package built properly using OpenMP on OS X.

My setup is basically:

My build requirements include gcc; install requirements include libgcc.
In build.sh, I set CC=gcc.
The python extension (via cython) that uses OpenMP is then built with gcc, and it all builds seemingly successfully.
When conda-build then goes to import the module in testing, though, I get:

ImportError: dlopen(/Users/dsutherl/.python-eggs/mmd-0.1.1-py2.7-macosx-10.5-x86_64.egg-tmp/mmd/_mmd.so, 2): Library not loaded: @rpath/./libgomp.1.dylib
  Referenced from: /Users/dsutherl/.python-eggs/mmd-0.1.1-py2.7-macosx-10.5-x86_64.egg-tmp/mmd/_mmd.so
  Reason: image not found

libgomp.1.dylib is in the expected place (anaconda/lib/), but @rpath seems to not be pointing there.

(I see the same behavior if I try to install with a homebrew-installed GCC with anaconda; it works with homebrew-installed GCC against system python, and also in anaconda on Linux.)

Is there something else I need to do to get this to work? I'm finding the documentation about @rpath in general on OSX to be quite cryptic.

The current version of the package + recipe, which is quite small and so nearly a minimal example, is here.

Thanks,
Dougal

Stuart Berg

unread,
May 12, 2016, 12:14:37 PM5/12/16
to Dougal Sutherland, conda - Public
Hi Dougal,

The problem you're seeing isn't related to OpenMP specifically.  You could see the same issue for any .dylib file that is linked with a relative path.

First, here's the "tl;dr" solution:

In your build.sh script, pass --single-version-externally-managed to setup.py:

$PYTHON setup.py --single-version-externally-managed install

Explanation:

The issue here is that zipped python eggs aren't really well suited for python extension modules.  As a workaround, eggs extract their contents to an "egg cache":
http://stackoverflow.com/questions/2192323/what-is-the-python-egg-cache-python-egg-cache

...but that's basically a hacky workaround that doesn't work nicely in all cases.  Instead of creating a zipped .egg file, you can just tell setup.py to install the *unzipped* egg contents by using the option shown above.

So, in your case, _mmd.so thinks it lives in your conda environment's lib folder, and therefore it has a relative path to locate libgomp.dylib.  But in reality, it doesn't live there -- it has been copied to the egg cache (/Users/dsutherl/.python-eggs).  Now the relative paths in that _mmd.so make no sense any more.  Using the option shown above, the egg cache is avoided entirely, and therefore all the necessary files are still in the correct locations relative to each other.

Best,
Stuart



--
You received this message because you are subscribed to the Google Groups "conda - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to conda+un...@continuum.io.
To post to this group, send email to co...@continuum.io.
Visit this group at https://groups.google.com/a/continuum.io/group/conda/.

Stuart Berg

unread,
May 12, 2016, 3:31:02 PM5/12/16
to Dougal Sutherland, conda - Public
Hi again,

I'm generally curious about why more users don't seem to encounter this issue, so I took a closer look at your recipe.  To follow up on my last email:

1) The "fix" I posted in my last email was not quite correct (oops).  The correct line to use is:

$PYTHON setup.py install --single-version-externally-managed --record=/dev/null

2) I see you already found an equivalent solution to your problem (actually, a better one).[1]  Within setup.py, you just write setup(..., zip_safe=False).  Thanks for the example; that's what I'll do in my own projects from now on.

3) In addition to the zip_safe fix, you also added some special calls to install_name_tool.[1]  As far as I can tell, these lines are unnecessary.  (I was able to build your recipe without them.)  Did you encounter some new problem that these lines fixed?  Or are you just opting for the "belt and suspenders" solution in this case... :-)

Best,
Stuart

Dougal Sutherland

unread,
May 12, 2016, 3:58:47 PM5/12/16
to Stuart Berg, conda - Public
Hi Stuart,

Thanks for the info. I thought that the install_name_tool stuff would help – and in fact I think it helps when I build the package not with conda but just in-place during development – but apparently after I rewrite it to an absolute path, conda-build then rewrites it again back to nearly what it started as. (This is why I didn't send a followup email, actually, because I wanted to figure out what was going on there.)

I didn't know about the egg cache; I added zip_safe=False just so that I could run install_name_tool on the output. :)  But this all makes much more sense to me now – thanks!

– Dougal

Sean Robertson

unread,
May 20, 2016, 11:55:23 AM5/20/16
to conda - Public
Hello,

I'm having a similar problem, so please let me know if I can do anything to help. My post is here

Sean

Sean Robertson

unread,
Jun 2, 2016, 11:55:34 AM6/2/16
to conda - Public
Hello,

I figured out my problem, so I'll pay it forward here. Distutils extensions don't like to set rpath on OSX even if you set runtime_library_dirs. Instead, I added the rpath to the linker flags and it worked fine!

Best,
Sean

Stuart Berg

unread,
Jun 2, 2016, 1:30:12 PM6/2/16
to Sean Robertson, conda - Public
I added the rpath to the linker flags and it worked fine!

Nice!  Someone attempted to permanently resolve that issue via conda-build PR #808 [1], but that PR had to be reverted due to conda-build #841 [2].  Someday when we resolve the bug in install_name_tool or simply drop support for OS X 10.7, you won't have to remember to set the rpath in your linker flags.

-Stuart
Reply all
Reply to author
Forward
0 new messages