diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -760,7 +760,15 @@ resolveDylibPath((root + path).str())) return loadDylib(*dylibPath, umbrella); - // TODO: Expand @loader_path, @executable_path, @rpath etc, handle -dylib_path + // TODO: Expand @loader_path, @rpath etc, handle -dylib_file + SmallString<128> newPath; + if (config->outputType == MH_EXECUTE && + path.consume_front("@executable_path/")) { + // ld64 allows overriding this with the undocumented flag -executable_path. + // lld doesn't currently implement that flag. + path::append(newPath, sys::path::parent_path(config->outputFile), path); + path = newPath; + } if (currentTopLevelTapi) { for (InterfaceFile &child : diff --git a/lld/test/MachO/link-search-at-executable-path.s b/lld/test/MachO/link-search-at-executable-path.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/link-search-at-executable-path.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 + +# RUN: rm -rf %t; split-file %s %t +# RUN: mkdir %t/subdir + +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/foo.s -o %t/foo.o +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/bar.s -o %t/bar.o +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/main.s -o %t/main.o + +# RUN: %lld -dylib -install_name @executable_path/libfoo.dylib %t/foo.o -o %t/subdir/libfoo.dylib + +# RUN: %lld -dylib -reexport_library %t/subdir/libfoo.dylib %t/bar.o -o %t/libbar.dylib + +## When linking executables, @executable_path/ in install_name should be replaced +## by the path of the executable. +# RUN: %lld -lSystem %t/main.o %t/libbar.dylib -o %t/subdir/test + +## This doesn't work for non-executables. +# RUN: not %lld -dylib -lSystem %t/main.o %t/libbar.dylib -o %t/subdir/libtest.dylib 2>&1 | FileCheck --check-prefix=ERR %s + +## It also doesn't help if the needed reexport isn't next to the library. +# RUN: not %lld -lSystem %t/main.o %t/libbar.dylib -o %t/test 2>&1 | FileCheck --check-prefix=ERR %s +# ERR: error: unable to locate re-export with install name @executable_path/libfoo.dylib + +#--- foo.s +.globl _foo +_foo: + retq + +#--- bar.s +.globl _bar +_bar: + retq + +#--- main.s +.section __TEXT,__text +.global _main +_main: + callq _foo + callq _bar + ret