Closed mtikekar closed 4 years ago
The short answer is that I think you can achieve the effect you want by running install_name_tool against your executable using a computed relative path (or an absolute one if you want to try the idea). You would have to assume that the placeholder install name for libA.dylib
would remain @loader_path/libA.dylib
.
The recipe involving install_name_tool and @loader_path/
is awkward. An equivalent, or more flexible, alternative would be welcomed.
The main limitation to my making progress here is my lack of experience with, and lack of access to, OSX. I'll admit right away that I don't understand @rpath
. The name, and man 1 dyld, suggest that it is similar to the ELF feature, but I don't immediately see how to make use of it. Linking a library libA.dylib
with -install_name @rpath/libA.dylib
seems clear enough. But I'm not sure what to give when linking a dependent library. Maybe -rpath @loader_path/../../moduleA/lib
? I don't have access to an OSX host, so it's difficult for me to experiment.
Turns out the following patch was good enough:
diff --git a/src/setuptools_dso/dsocmd.py b/src/setuptools_dso/dsocmd.py
index 70b15bc..8fc9f73 100644
--- a/src/setuptools_dso/dsocmd.py
+++ b/src/setuptools_dso/dsocmd.py
@@ -140,7 +140,9 @@ class dso2libmixin:
else:
raise RuntimeError("Something wierd happened. Please report. %s"%full)
- self._osx_changes.append(('@loader_path/'+fullname, '@loader_path/%s/%s'%(os.path.relpath(dsopath, mypath), fullname)))
+ p = os.path.relpath(dsopath, mypath)
+ if p != '.':
+ soargs.add('-Wl,-rpath,@loader_path/%s' % p)
# In theory '-dylib_file A:B' asks the linker to do the equivlaent of:
# install_name_tool -change A B
@@ -341,7 +343,7 @@ class build_dso(dso2libmixin, Command):
if sys.platform == 'darwin':
# we always want to produce relocatable (movable) binaries
# this install_name will be replaced below (cf. 'install_name_tool')
- extra_args.extend(['-install_name', '@loader_path/%s'%solibbase])
+ extra_args.extend(['-install_name', '@rpath/%s'%solibbase, '-Wl,-rpath,@loader_path'])
elif sys.platform == "win32":
# The .lib is considered "temporary" for extensions, but not for us
The way I see it, if you link libA.dylib
with -install_name @rpath/libA.dylib
and link any dependent library with -rpath /path/to/libA.dylib
, you get the the ELF-equivalent behaviour. And if you're using $ORIGIN
to make it relocatable, you simply use @loader_path
instead.
Can you make a pull request? I'd like to see the CI tests pass.
I don't have access to an OSX host, so it's difficult for me to experiment.
@mdavidsaver, FYI not having a physical Mac, I'm using https://github.com/kholia/OSX-KVM on a Linux host to verify how my Pygolang works under OSX. OSX-KVM works relatively ok.
(I see there are some changes on OSX-KVM side; For me it is working as of 64fcc1ef "Batch update for December - 2019", i.e. before switch to "open core")
(OpenCore turned out to be another bootloader, not a new development model)
I'm trying to use setuptools_dso to build a package that needs its DSOs to be available for linking in third-party executables which are outside the package. On MacOS, the DSOs are being built with
@loader_path/libname.dylib
as their install_names which makes it impossible for the external executables to load them.Is it possible to build the DSOs with
@rpath/libname.dylib
so that external executables can also load them? I noticed that you're usinginstall_name_tool
to change the change the names of the dependencies from@loader_path/libname.dylib
to@loader_path/relpath/libname.dylib
. Instead of doing that, you can just addrelpath
to rpath when building and remove theinstall_name_tool
step.