[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: