Bug#701036: mklibs: Fix incorrect interaction between --sysroot and --root
Package: mklibs
Version: 0.12
Tags: patch
The "--sysroot SYSROOT" option preappends SYSROOT to all library paths,
but the "--root RPATHROOT" option preappends RPATHROOT to all rpath
searches. If these flags are used together rpaths have 2 absolutes roots
preappended to them: <sysroot>/<root>/<rpath>, which doesn't make sense.
The patch below adjust this behavior by not preappending <sysroot> to
rpath searches.
Test case
-----------
In this test case the compiler used is the stock Debian GCC, and the
directory "sysroot" is a copy of the system sysroot /lib* and /usr/lib*
directories. This is sufficient to demonstrate the issue, although a
cross compiler and corresponding sysroot might make be a more realistic
use case.
joe@debian:~$ cat foo.c
int foo() {
return 0;
}
joe@debian:~$ cat test.c
int main (void) {
foo();
timer_settime();
}
joe@debian:~$ cat Makefile
.PHONY: all
all: rootfs/lib/foo/libfoo.so a.out mklibs.out
rootfs/lib/foo/libfoo.so: foo.c
mkdir -p rootfs/lib/foo/
$(CC) -shared $^ -o $@ $(CFLAGS)
a.out: test.c
$(CC) -Lrootfs/lib/foo -Wl,-rpath,/lib/foo -lfoo -lrt $^ -o $@ $(CFLAGS)
mklibs.out: a.out
mklibs --sysroot $(PWD)/sysroot --root $(PWD)/rootfs -d . $^ | tee mklibs.out
Output from make
-----------------
mkdir -p rootfs/lib/foo/
cc -shared foo.c -o rootfs/lib/foo/libfoo.so
cc -Lrootfs/lib/foo -Wl,-rpath,/lib/foo -lfoo -lrt test.c -o a.out
mklibs --sysroot /home/joe/sysroot --root /home/joe/rootfs -d . a.out | tee mklibs.out
Library not found: libfoo.so in path: /lib/:/usr/lib/:/usr/X11R6/lib/:/home/joe/rootfs//lib/foo
I: Using sysroot/lib64/ld-linux-x86-64.so.2 as dynamic linker.
I: library reduction pass 1
5 symbols, 5 unresolved
Because find_libs preappends "sysroot" to all search paths, mklibs is
actually looking in /home/joe/sysroot/home/joe/rootfs/lib/foo. The patch
below makes things work:
mkdir -p rootfs/lib/foo/
cc -shared foo.c -o rootfs/lib/foo/libfoo.so
cc -Lrootfs/lib/foo -Wl,-rpath,/lib/foo -lfoo -lrt test.c -o a.out
mklibs --sysroot sysroot --root /home/joe/rootfs -d . a.out | tee mklibs.out
I: Using sysroot/lib64/ld-linux-x86-64.so.2 as dynamic linker.
I: library reduction pass 1
5 symbols, 5 unresolved
I: library reduction pass 2
69 symbols, 30 unresolved
I: library reduction pass 3
122 symbols, 22 unresolved
I: library reduction pass 4
122 symbols, 3 unresolved
I: library reduction pass 5
122 symbols, 3 unresolved
diff --git a/src/mklibs b/src/mklibs
index ef15147..03b00f1 100755
--- a/src/mklibs
+++ b/src/mklibs
@@ -233,6 +233,9 @@ def find_lib(lib):
for path in lib_path:
if os.access(sysroot + path + "/" + lib, os.F_OK):
return sysroot + path + "/" + lib
+ for path in lib_rpath:
+ if os.access(path + "/" + lib, os.F_OK):
+ return path + "/" + lib
return ""
@@ -243,6 +246,10 @@ def find_pic(lib):
for file in glob.glob(sysroot + path + "/" + base_name + "_pic.a"):
if os.access(file, os.F_OK):
return resolve_link(file)
+ for path in lib_rpath:
+ for file in glob.glob(path + "/" + base_name + "_pic.a"):
+ if os.access(file, os.F_OK):
+ return resolve_link(file)
return ""
# Find a PIC .map file for the library
@@ -252,6 +259,10 @@ def find_pic_map(lib):
for file in glob.glob(sysroot + path + "/" + base_name + "_pic.map"):
if os.access(file, os.F_OK):
return resolve_link(file)
+ for path in lib_rpath:
+ for file in glob.glob(path + "/" + base_name + "_pic.map"):
+ if os.access(file, os.F_OK):
+ return resolve_link(file)
return ""
def extract_soname(so_file):
@@ -447,8 +458,6 @@ for obj in objects.values():
else:
print "warning: " + obj + " may need rpath, but --root not specified"
-lib_path.extend(lib_rpath)
-
passnr = 1
available_libs = []
previous_pass_unresolved = set()
@@ -543,7 +552,7 @@ while 1:
path = find_lib(library)
if not path:
sys.exit("Library not found: " + library + " in path: "
- + ':'.join(lib_path))
+ + ':'.join(lib_path + lib_rpath))
symbols = provided_symbols(path)
library_symbols[library] = {}
library_symbols_used[library] = set()
@@ -624,6 +633,7 @@ while 1:
cmd.extend(extra_flags)
cmd.append("-lgcc")
cmd.extend(["-L%s" % a for a in [dest_path] + [sysroot + b for b in lib_path if sysroot == "" or b not in ("/" + libdir + "/", "/usr/" + libdir + "/")]])
+ cmd.extend(["-L%s" % a for a in lib_rpath])
cmd.append(library_depends_gcc_libnames(so_file))
command(target + "gcc", *cmd)
Reply to: