ld: rpath not resolved when linking indirect dependencies

Originator:tobias.hahn
Number:rdar://25313838 Date Originated:2016-03-23
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 7.3 (7D175)
Classification:Serious Bug Reproducible:Always
 
Summary:
When linking indirect dynamic libraries for flat namespace, ld loads all indirect dylibs. If an indirect dylib is linked using an @rpath install name, the linker does not resolve @rpath and produces a "file not found" error.

This is a regression in Xcode 7.3 (ld version ld64-264.3.101), it works as expected using Xcode 7.2.1 (ld version ld64-253.9).

(See the manpage for ld for a description of indirect dynamic libraries.)

Steps to Reproduce:
1. Unzip ld-bug.zip and cd into the directory
2. Run script.sh

Expected Results:
The script runs without error and produces libc.dylib. This is what happens using Xcode 7.2.1.

Actual Results:
The script fails at the last step with the following linker error:
ld: file not found: @rpath/liba.dylib for architecture x86_64

Version:
Mac OS X 10.11.4 / 15E65
Xcode 7.3 / 7D175

Notes:


Configuration:
Mac OS X 10.11.4
Xcode 7.3

Attachments:
'ld-bug.zip' was successfully uploaded.

Comments

It appears that the bug is related to the way ld resolves the library search paths. A possible workaround is to replace '-L.' with '-L./' in OTHER_LDFLAGS. Since the actual linker command line is often generated by a tool such as gyp, cmake etc., this workaround may not be feasible for all use cases.

By tobias.hahn at March 29, 2016, 11:42 a.m. (reply...)

@rpath

We’ve done some analysis of this bug, enough to come up with a horrible workaround, in https://crbug.com/597459.

c.c

void foo_b();
void foo_c();
void foo_c() { foo_b(); }
By tobias.hahn at March 23, 2016, 2:35 p.m. (reply...)

b.c

void foo_a();
void foo_b();
void foo_b() { foo_a(); }
By tobias.hahn at March 23, 2016, 2:35 p.m. (reply...)

a.c

void foo_a();
void foo_a() {}
By tobias.hahn at March 23, 2016, 2:35 p.m. (reply...)

script.sh

#!/bin/bash

clang -c a.c -o a.o
clang -c b.c -o b.o
clang -c c.c -o c.o

LDFLAGS="-dylib -arch x86_64 -macosx_version_min 10.11 -lSystem"
OTHER_LDFLAGS="-L. -flat_namespace -rpath @loader_path/"

ld $LDFLAGS $OTHER_LDFLAGS -dylib_install_name @rpath/liba.dylib -o liba.dylib a.o
ld $LDFLAGS $OTHER_LDFLAGS -dylib_install_name @rpath/libb.dylib -o libb.dylib b.o liba.dylib
ld $LDFLAGS $OTHER_LDFLAGS -dylib_install_name @rpath/libc.dylib -o libc.dylib c.o libb.dylib
By tobias.hahn at March 23, 2016, 2:33 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!