mklibs patches for cross environment
At CodeSourcery we're enhancing mklibs for use as a general-purpose tool
for reducing shared libraries for root filesystems together with EGLIBC
<http://www.eglibc.org/> in a cross-compilation environment. In the
process we've added some features to mklibs useful in such an environment,
and fixed a couple of bugs in mklibs-readelf. The patch is appended; if
the new features aren't of interest because they aren't relevant to how
Debian uses mklibs, we'll distribute the patch from the EGLIBC website,
but I hope at least the mklibs-readelf bugfixes will be of use.
The features added are:
* --sysroot, to locate all libraries and other related input files
relative to a specified root directory rather than /. (This is different
from the existing --root option.)
* --gcc-options, to pass multilib options to gcc when relinking.
* --libdir, to use names such as "lib64" or "lib32" in place of lib in the
default directory names.
The mklibs-readelf bugs fixed are:
* One place failed to convert endianness of data from the input file, so
causing failures when host and target have different endianness.
* Certain fields were uninitialized (for some input files) but later
compared against NULL, relying on the uninitialized data happening to be
0; fixed by explicitly initializing them.
Index: src/mklibs.1
===================================================================
--- src/mklibs.1 (revision 51247)
+++ src/mklibs.1 (working copy)
@@ -28,6 +28,16 @@
\fB\-\-target \fITARGET
Prepend \fITARGET\fB\-\fR to the gcc and binutils calls.
.TP
+\fB\-\-sysroot \fISYSROOT
+Locate libraries and associated files relative to \fISYSROOT\fR.
+.TP
+\fB\-\-gcc\-options \fIOPTIONS
+Pass \fIOPTIONS\fR to the compiler when relinking.
+.TP
+\fB\-\-libdir \fIDIR
+Use \fIDIR\fR (for example, \fBlib64\fR) in place of \fBlib\fR in
+default library paths.
+.TP
\fB\-v\fR, \fB\-\-verbose
Explain what is being done.
.TP
Index: src/mklibs-readelf/elf.cpp
===================================================================
--- src/mklibs-readelf/elf.cpp (revision 51247)
+++ src/mklibs-readelf/elf.cpp (working copy)
@@ -114,6 +114,9 @@
this->sections.resize (this->shnum);
+ section_GNU_VERDEF = NULL;
+ section_GNU_VERNEED = NULL;
+ section_GNU_VERSYM = NULL;
for (unsigned int i = 0; i < this->shnum; i++)
{
section *temp;
@@ -149,6 +152,7 @@
this->segments.resize (this->phnum);
+ segment_INTERP = NULL;
for (unsigned int i = 0; i < this->phnum; i++)
{
segment *temp;
@@ -376,7 +380,7 @@
this->versyms.reserve (max);
for (unsigned int i = 0; i < max; i++)
- this->versyms.push_back (versyms[i]);
+ this->versyms.push_back (convert<_data, typeof (versyms[i])> () (versyms[i]));
}
template <typename _class, typename _data>
Index: src/mklibs.py
===================================================================
--- src/mklibs.py (revision 51247)
+++ src/mklibs.py (working copy)
@@ -185,8 +185,8 @@
# Find complete path of a library, by searching in lib_path
def find_lib(lib):
for path in lib_path:
- if os.access(path + "/" + lib, os.F_OK):
- return path + "/" + lib
+ if os.access(sysroot + path + "/" + lib, os.F_OK):
+ return sysroot + path + "/" + lib
return ""
@@ -194,7 +194,7 @@
def find_pic(lib):
base_name = so_pattern.match(lib).group(1)
for path in lib_path:
- for file in glob.glob(path + "/" + base_name + "_pic.a"):
+ for file in glob.glob(sysroot + path + "/" + base_name + "_pic.a"):
if os.access(file, os.F_OK):
return resolve_link(file)
return ""
@@ -203,7 +203,7 @@
def find_pic_map(lib):
base_name = so_pattern.match(lib).group(1)
for path in lib_path:
- for file in glob.glob(path + "/" + base_name + "_pic.map"):
+ for file in glob.glob(sysroot + path + "/" + base_name + "_pic.map"):
if os.access(file, os.F_OK):
return resolve_link(file)
return ""
@@ -230,6 +230,9 @@
print >> outfd, " --libc-extras-dir DIRECTORY look for libc extra files in DIRECTORY"
print >> outfd, " --target TARGET prepend TARGET- to the gcc and binutils calls"
print >> outfd, " --root ROOT search in ROOT for library rpaths"
+ print >> outfd, " --sysroot ROOT prepend ROOT to all paths for libraries"
+ print >> outfd, " --gcc-options OPTIONS pass OPTIONS to gcc"
+ print >> outfd, " --libdir DIR use DIR (e.g. lib64) in place of lib in default paths"
print >> outfd, " -v, --verbose explain what is being done"
print >> outfd, " -h, --help display this help and exit"
sys.exit(was_err)
@@ -264,7 +267,8 @@
# Argument parsing
opts = "L:DnvVhd:r:l:"
longopts = ["no-default-lib", "dry-run", "verbose", "version", "help",
- "dest-dir=", "ldlib=", "libc-extras-dir=", "target=", "root="]
+ "dest-dir=", "ldlib=", "libc-extras-dir=", "target=", "root=",
+ "sysroot=", "gcc-options=", "libdir="]
# some global variables
lib_rpath = []
@@ -274,9 +278,13 @@
include_default_lib_path = "yes"
default_lib_path = ["/lib/", "/usr/lib/", "/usr/X11R6/lib/"]
libc_extras_dir = "/usr/lib/libc_pic"
+libc_extras_dir_default = True
+libdir = "lib"
target = ""
root = ""
+sysroot = ""
force_libs = []
+gcc_options = []
so_pattern = re.compile("((lib|ld).*)\.so(\..+)*")
script_pattern = re.compile("^#!\s*/")
@@ -300,12 +308,19 @@
ldlib = arg
elif opt == "--libc-extras-dir":
libc_extras_dir = arg
+ libc_extras_dir_default = False
elif opt == "--target":
target = arg + "-"
elif opt in ("-r", "--root"):
root = arg
+ elif opt == "--sysroot":
+ sysroot = arg
elif opt in ("-l",):
force_libs.append(arg)
+ elif opt == "--gcc-options":
+ gcc_options.extend(string.split(arg, " "))
+ elif opt == "--libdir":
+ libdir = arg
elif opt in ("--help", "-h"):
usage(0)
sys.exit(0)
@@ -316,8 +331,11 @@
print "WARNING: unknown option: " + opt + "\targ: " + arg
if include_default_lib_path == "yes":
- lib_path.extend(default_lib_path)
+ lib_path.extend([a.replace("/lib/", "/" + libdir + "/") for a in default_lib_path])
+if libc_extras_dir_default:
+ libc_extras_dir = libc_extras_dir.replace("/lib/", "/" + libdir + "/")
+
if ldlib == "LDLIB":
ldlib = os.getenv("ldlib")
@@ -344,6 +362,8 @@
if not ldlib:
sys.exit("E: Dynamic linker not found, aborting.")
+ldlib = sysroot + ldlib
+
debug(DEBUG_NORMAL, "I: Using", ldlib, "as dynamic linker.")
# Check for rpaths
@@ -514,8 +534,8 @@
if soname in ("libc.so.6", "libc.so.6.1"):
# force dso_handle.os to be included, otherwise reduced libc
# may segfault in ptmalloc_init due to undefined weak reference
- extra_pre_obj.append(libc_extras_dir + "/soinit.o")
- extra_post_obj.append(libc_extras_dir + "/sofini.o")
+ extra_pre_obj.append(sysroot + libc_extras_dir + "/soinit.o")
+ extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o")
symbols.add(ProvidedSymbol('__dso_handle', 'Base', True))
map_file = find_pic_map(library)
@@ -524,6 +544,7 @@
# compile in only used symbols
cmd = []
+ cmd.extend(gcc_options)
cmd.append("-nostdlib -nostartfiles -shared -Wl,-soname=" + soname)
cmd.extend(["-u%s" % a.linker_name() for a in symbols])
cmd.extend(["-o", dest_path + "/" + so_file_name + "-so"])
@@ -532,7 +553,7 @@
cmd.extend(extra_post_obj)
cmd.extend(extra_flags)
cmd.append("-lgcc")
- cmd.extend(["-L%s" % a for a in [dest_path] + lib_path])
+ cmd.extend(["-L%s" % a for a in [dest_path] + [sysroot + b for b in lib_path]])
cmd.append(library_depends_gcc_libnames(so_file))
command(target + "gcc", *cmd)
--
Joseph S. Myers
joseph@codesourcery.com
Reply to: