From 1d19df4af4970ad8080265d1b1734436fb428413 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT service" Date: Mon, 13 Apr 2009 21:01:05 +0200 Subject: [PATCH] import from svn --- .gitignore | 3 + _restrun | 14 + base/CCompilerParam.java | 282 +++++++++++++++ base/Command.java | 57 +++ base/EInstallFailed.java | 10 + base/EMissingDBFile.java | 10 + base/EParameterInvalid.java | 14 + base/EParameterMissing.java | 10 + base/EPkgConfigBrokenVariableReference.java | 10 + base/EPkgConfigError.java | 15 + base/EPkgConfigMissingProperty.java | 10 + base/EPkgConfigParseError.java | 14 + base/EPkgConfigUnhandledProperty.java | 10 + base/EUnhandledCompilerFlag.java | 10 + base/EUnitoolError.java | 14 + base/EVersionSyntaxError.java | 10 + base/Hacks.java | 8 + base/InstallerParam.java | 76 ++++ base/LibraryInfo.java | 36 ++ base/LinkerParam.java | 537 ++++++++++++++++++++++++++++ base/ManualPageInfo.java | 10 + base/ObjectInfo.java | 9 + base/PackageInfo.java | 30 ++ base/ToolConfig.java | 49 +++ base/ToolParam.java | 275 ++++++++++++++ base/ToolType.java | 67 ++++ build.xml | 193 ++++++++++ db/LibraryInfo.java | 93 +++++ db/LoadLibtool.java | 255 +++++++++++++ db/LoadLibtoolArchive.java | 223 ++++++++++++ db/LoadLibtoolObject.java | 86 +++++ db/LoadPkgConfig.java | 151 ++++++++ db/ObjectInfo.java | 11 + db/PackageInfo.java | 17 + db/QueryPkgConfig.java | 103 ++++++ db/StoreLibtool.java | 107 ++++++ db/StoreLibtoolArchive.java | 61 ++++ db/StoreLibtoolObject.java | 31 ++ db/StorePkgConfig.java | 170 +++++++++ db/UnitoolConf.java | 66 ++++ libtool/CmdCompile.java | 377 +++++++++++++++++++ libtool/CmdInstall.java | 144 ++++++++ libtool/CmdLink.java | 473 ++++++++++++++++++++++++ libtool/Main.java | 69 ++++ misc/libtool | 8 + tools/CCompiler.java | 76 ++++ tools/Gcc_cmdline.java | 289 +++++++++++++++ tools/LD_cmdline.java | 161 +++++++++ tools/LTLibraryInstaller.java | 228 ++++++++++++ tools/LinkExecutable.java | 61 ++++ tools/LinkSharedLibrary.java | 114 ++++++ tools/LinkStaticLibrary.java | 53 +++ tools/LinkerBase.java | 129 +++++++ unitool/Build.java | 17 + unitool/Install.java | 137 +++++++ unitool/Main.java | 13 + unitool/PIBuild.java | 54 +++ unitool/PkgConfigFixup.java | 72 ++++ unitool/Query.java | 54 +++ unitool/Unitool.java | 34 ++ 60 files changed, 5720 insertions(+) create mode 100644 .gitignore create mode 100755 _restrun create mode 100644 base/CCompilerParam.java create mode 100644 base/Command.java create mode 100644 base/EInstallFailed.java create mode 100644 base/EMissingDBFile.java create mode 100644 base/EParameterInvalid.java create mode 100644 base/EParameterMissing.java create mode 100644 base/EPkgConfigBrokenVariableReference.java create mode 100644 base/EPkgConfigError.java create mode 100644 base/EPkgConfigMissingProperty.java create mode 100644 base/EPkgConfigParseError.java create mode 100644 base/EPkgConfigUnhandledProperty.java create mode 100644 base/EUnhandledCompilerFlag.java create mode 100644 base/EUnitoolError.java create mode 100644 base/EVersionSyntaxError.java create mode 100644 base/Hacks.java create mode 100644 base/InstallerParam.java create mode 100644 base/LibraryInfo.java create mode 100644 base/LinkerParam.java create mode 100644 base/ManualPageInfo.java create mode 100644 base/ObjectInfo.java create mode 100644 base/PackageInfo.java create mode 100644 base/ToolConfig.java create mode 100644 base/ToolParam.java create mode 100644 base/ToolType.java create mode 100644 build.xml create mode 100644 db/LibraryInfo.java create mode 100644 db/LoadLibtool.java create mode 100644 db/LoadLibtoolArchive.java create mode 100644 db/LoadLibtoolObject.java create mode 100644 db/LoadPkgConfig.java create mode 100644 db/ObjectInfo.java create mode 100644 db/PackageInfo.java create mode 100644 db/QueryPkgConfig.java create mode 100644 db/StoreLibtool.java create mode 100644 db/StoreLibtoolArchive.java create mode 100644 db/StoreLibtoolObject.java create mode 100644 db/StorePkgConfig.java create mode 100644 db/UnitoolConf.java create mode 100644 libtool/CmdCompile.java create mode 100644 libtool/CmdInstall.java create mode 100644 libtool/CmdLink.java create mode 100644 libtool/Main.java create mode 100755 misc/libtool create mode 100644 tools/CCompiler.java create mode 100644 tools/Gcc_cmdline.java create mode 100644 tools/LD_cmdline.java create mode 100644 tools/LTLibraryInstaller.java create mode 100644 tools/LinkExecutable.java create mode 100644 tools/LinkSharedLibrary.java create mode 100644 tools/LinkStaticLibrary.java create mode 100644 tools/LinkerBase.java create mode 100644 unitool/Build.java create mode 100644 unitool/Install.java create mode 100644 unitool/Main.java create mode 100644 unitool/PIBuild.java create mode 100644 unitool/PkgConfigFixup.java create mode 100644 unitool/Query.java create mode 100644 unitool/Unitool.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f4ac092 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.class +.build +.svn diff --git a/_restrun b/_restrun new file mode 100755 index 0000000..64b93b0 --- /dev/null +++ b/_restrun @@ -0,0 +1,14 @@ +#!/bin/bash + +export SYSROOT=/opt/xcompiler/jail/sys-root + +make && \ + ./run-libtool \ + --mode=link /opt/xcompiler/jail/bin/gcc \ + -g -O2 -Wall \ + -o timescale \ + timescale.o \ + -L/opt/xcompiler/jail/sys-root/usr/lib \ + -L/usr/lib \ + -lpthread \ + /usr/lib/libpng.la diff --git a/base/CCompilerParam.java b/base/CCompilerParam.java new file mode 100644 index 0000000..0749262 --- /dev/null +++ b/base/CCompilerParam.java @@ -0,0 +1,282 @@ + +package org.de.metux.unitool.base; + +import org.de.metux.util.*; +import org.de.metux.propertylist.IPropertylist; + +public class CCompilerParam extends ToolParam +{ + public static final String cf_make_depend_target = "make-depend-target"; + public static final String cf_make_depend_output = "make-depend-output"; + public static final String cf_compiler_define = "compiler-define"; + public static final String cf_source = "source"; + public static final String cf_output_file = "output-file"; + public static final String cf_include_path = "include-path"; + public static final String cf_include_file = "include-file"; + public static final String cf_compiler_flag = "compiler-flag"; + public static final String cf_warning_flag = "warning-flag"; + public static final String flag_pic = "pic"; + public static final String flag_nopic = "nopic"; + public static final String cf_compiler_command = "tools/compiler/c-binobj/compiler-command"; + + public static final String flag_mkdepend_dummytargets = "mkdepend-dummy-targets"; + public static final String flag_mkdepend_default = "mkdepend-default"; + + public static final String flag_warn_pointer_arith = "warn-pointer-arith"; + public static final String flag_warn_strict_prototypes = "warn-strict-prototypes"; + public static final String flag_warn_missing_prototypes = "warn-missing-prototypes"; + public static final String flag_warn_missing_declarations = "warn-missing-declarations"; + public static final String flag_warn_declaration_after_statement = "warn-declaration-after-statement"; + public static final String flag_warn_cast_align = "warn-cast-align"; + public static final String flag_warn_nested_externs = "warn-nested-externs"; + public static final String flag_warn_write_strings = "warn-write-strings"; + public static final String flag_warn_no_cast_qual = "warn-no-cast-qual"; + public static final String flag_warn_all = "warn-all"; + public static final String flag_warn_unused = "warn-unused"; + public static final String flag_warn_error = "warn-error"; + public static final String flag_warn_no_unused = "warn-no-unused"; + public static final String flag_warn_no_format = "warn-no-format"; + public static final String flag_warn_inline = "warn-inline"; + + public CCompilerParam(ToolConfig cf) + { + super(cf); + } + + public CCompilerParam(ToolConfig cf, IPropertylist pr) + { + super(cf,pr); + } + + public void clearMkDependTarget() + { + remove(cf_make_depend_target); + } + + public void clearCompilerFlag() + { + remove(cf_compiler_flag); + } + + public void addWarningFlag(String flag) + { + add(cf_warning_flag,flag); + } + + public void addCompilerFlag(String flag) + { + add(cf_compiler_flag,flag); + } + + public void addCompilerFlag(String[] flag) + { + add(cf_compiler_flag,flag); + } + + public String[] getCompilerFlags() + { + return get_str_list(cf_compiler_flag); + } + + public String[] getWarningFlags() + { + return get_str_list(cf_warning_flag); + } + + public void setPIC(boolean f) + { + if (f) + addCompilerFlag(flag_pic); + else + addCompilerFlag(flag_nopic); + } + + public void setMkDependTarget(String target) + { + set(cf_make_depend_target, target); + } + + public String getMkDependTarget() + { + return get_str_def(cf_make_depend_target, null); + } + + public String getMkDependOutput() + { + return get_str_def(cf_make_depend_output, null); + } + + public void clearMkDependOutput() + { + remove(cf_make_depend_output); + } + + public void setMkDependOutput(String fn) + { + set(cf_make_depend_output, fn); + } + + public String[] getDefines() + { + return get_str_list(cf_compiler_define); + } + + public void addDefine(String def) + { + add(cf_compiler_define, def); + } + + public void clearDefine() + { + remove(cf_compiler_define); + } + + public void addDefine(String def[]) + { + add(cf_compiler_define,def); + } + + public String[] getSourceFiles() + { + return get_str_list(cf_source); + } + + public void addSourceFile(String fn) + { + add(cf_source,fn); + } + + public void clearSourceFile() + { + remove(cf_source); + } + + public void addSourceFile(String fn[]) + { + add(cf_source,fn); + } + + public void setCompilerCommand(String fn) + { + System.err.println("WARN: setCompilerCommand() is obsolete"); + set(cf_compiler_command,fn); + } + + public String getCompilerCommand() + { + return getConfigStr(cf_compiler_command); + } + + public void clearCompilerCommand() + { + remove(cf_compiler_command); + } + + public void setOutputFile(String fn) + { + set(cf_output_file,fn); + } + + public String getOutputFile() + { + return get(cf_output_file); + } + + public void clearOutputFile() + { + remove(cf_output_file); + } + + public void addIncludeFile(String str) + { + add(cf_include_file,str); + } + + public void addIncludeFile(String str[]) + { + add(cf_include_file,str); + } + + public void addIncludePath(String str) + { + add(cf_include_path,str); + } + + public void addIncludePath(String str[]) + { + add(cf_include_path,str); + } + + public void addIncludePath_enc_sysroot(String str) + { + addIncludePath(normalizer.enc_sysroot(str)); + } + + public void addIncludePath_enc_sysroot(String str[]) + { + if (str!=null) + for (int x=0; x "+pkg.include_pathes.toString()); + System.err.println(" include_pathes_private ==> "+pkg.include_pathes_private.toString()); + System.err.println(" cflags => "+pkg.cflags); + System.err.println(" cflags_private => "+pkg.cflags_private); + + addIncludePath(pkg.include_pathes); + addIncludePath(pkg.include_pathes_private); + } + + public void addPackageImport(PackageInfo pkg[]) + { + if (pkg!=null) + for (int x=0; x"+libinf.sysroot+" self->"+getSysroot()); + + if (libinf.link_static) + { + System.out.println("LinkerParam::addLibraryImport() linking static: "+libinf.library_name); + + if (StrUtil.isEmpty(libinf.arname)) + throw new RuntimeException("missing arname for static linking"); + + if (libinf.installed) + throw new RuntimeException("linking statically against installed libs not supported yet"); + else + { + String fullpath = libinf.prefix+libinf.uninstalled_libdir+libinf.arname; + System.out.println("addLibraryImport(): linking static against noninstalled: "+fullpath+" (arname="+libinf.arname+")"); + addStaticLink(fullpath); + } + } + else + { + + if (libinf.installed) + { + System.out.println("addLibraryImport(): linking dynamic against installed: "+libinf.module_name+" / "+libinf.library_name); + addLibraryPath_enc_sysroot(libinf.libdir); + } + else + { + System.out.println("addLibraryImport(): linking dynamically against an uninstalled so "+libinf.library_name+" "+libinf.cf+" "+libinf.dlname); + addLibraryPath_enc_sysroot(libinf.prefix+libinf.uninstalled_libdir); + } + + if (StrUtil.isEmpty(libinf.module_name)) + throw new RuntimeException("missing dynamic module name"); + + if (StrUtil.isEmpty(libinf.library_name)) + throw new RuntimeException("missing dynamic library name"); + + if ((libinf.cf!=null)&& + libinf.cf.startsWith("../") && + hack_link_intree_so_direct) + { + String objname = libinf.prefix+libinf.uninstalled_libdir+libinf.library_name+".so"; + + System.out.println("addLibraryImport(): enabled hack_link_intree_direct"); + System.out.println(" dlname="+libinf.dlname); + System.out.println(" library_name="+libinf.library_name); + System.out.println(" uninstalled_libdir="+libinf.uninstalled_libdir); + System.out.println(" prefix="+libinf.prefix); + System.out.println(" --> objname="+objname); + + addObjectLink(objname); + } + else + addSharedLink(libinf.module_name); + } + + if (libinf.search_pathes!=null) + for (int x=0; x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #!/bin/bash +UNITOOL_PREFIX="${prefix}" +UNITOOL_JVM="${java-runtime}" +UNITOOL_MAIN="org.de.metux.unitool.unitool.Main" + +export CLASSPATH="$CLASSPATH:${metux-runtime}:${unitool-runtime}" + +if [ ! "$SYSROOT" ]; then + echo "$0: Missing \$SYSROOT" + exit; +fi + +for i in $* ; do + echo "Processing: $i" + $UNITOOL_JVM $UNITOOL_MAIN \ + --pkgconfig-fixup \ + source "$i" \ + output "$i.out" \ + system-root "$SYSROOT" && mv "$i.out" "$i" +done + + + + + + #!/bin/bash +UNITOOL_PREFIX="${prefix}" +UNITOOL_JVM="${java-runtime}" +UNITOOL_MAIN="org.de.metux.unitool.unitool.Main" + +export CLASSPATH="$CLASSPATH:${metux-runtime}:${unitool-runtime}" +$UNITOOL_JVM $UNITOOL_MAIN "$@" + + + + + + + #!/bin/bash +UNITOOL_PREFIX="${prefix}" +UNITOOL_JVM="${java-runtime}" +UNITOOL_MAIN="org.de.metux.unitool.libtool.Main" + +export CLASSPATH="$CLASSPATH:${metux-runtime}:${unitool-runtime}" +$UNITOOL_JVM $UNITOOL_MAIN "$@" + + + + diff --git a/db/LibraryInfo.java b/db/LibraryInfo.java new file mode 100644 index 0000000..6bacce9 --- /dev/null +++ b/db/LibraryInfo.java @@ -0,0 +1,93 @@ + +package org.de.metux.unitool.db; + +import org.de.metux.unitool.base.LinkerParam; + +public class LibraryInfo +{ + public String sysroot=null; /* system root prefix */ + public String arname=null; /* name of the library archive (.a) file */ + public String name=null; /* library name (for -l) */ + public String dlname=null; /* dynamic library filename (w/ version) */ + public String prefix=null; /* prefix / subdir for filenames */ + + // take care that this arrays may also continue NULLs ! + public String[] dynamic_libnames=null; + public LibraryInfo[] dependencies=null; + public String[] dependency_names=null; + public String[] search_pathes=null; + + public int version_current = 0; + public int version_age = 0; + public int version_revision = 0; + + public String release = null; + + public boolean installed = false; + public boolean should_not_link = false; + public boolean link_static = false; + + public String param_dlopen = null; + public String param_dlpreopen = null; + public String libdir = null; + + // FIXME: only supports dynamic libraries + + public void store(LinkerParam param) + { + // FIXME we probably should compare the sysroot w/ the LinkerParam + if ((sysroot!=null) && (!sysroot.equals(""))) + param.setSysroot(sysroot); + + if (libdir!=null) + { + if (sysroot==null) + throw new RuntimeException("uuuh, no sysroot ?!"); + + param.addLibraryPath_enc_sysroot(libdir); + } + + if (link_static) + { + // we enforce static linking + param.addStaticLink(prefix+arname); + System.out.println("LibraryInfo.store(): linking static against: "+prefix+arname); + } + else + { + System.out.println("LibraryInfo.store(): linking dynamic against: "+name); + + if (name!=null) + param.addSharedLink(name); + else if (dlname!=null) + { + if (libdir==null) + param.addObjectLink(dlname); + else + param.addObjectLink(libdir+"/"+dlname); + } + else if (arname!=null) + { + if (libdir==null) + param.addObjectLink(arname); + else + param.addObjectLink(libdir+"/"+arname); + } + else + throw new RuntimeException("nothing to import!"); + } + + if (search_pathes!=null) + for (int x=0; x \""+ + shvar.value+"\"" + ); + } + + return inf; + } + + static public LibraryInfo load_archive( + String fn, + String sysroot, + String prefix + ) + throws FileNotFoundException, IOException + { + PathNormalizer norm = new PathNormalizer(); + norm.setSysroot(sysroot); + + sysroot = PathNormalizer.normalize_dir(sysroot); + + if (prefix==null) + prefix=""; + else if (prefix.length()==0); + else + prefix+="/"; + + System.out.println("Loading libtool library: "+fn+" (sysroot="+sysroot+" prefix="+prefix+")"); + + String search_path = ""; + + BufferedReader in = + new BufferedReader(new FileReader(fn)); + + String line; + LibraryInfo inf = new LibraryInfo(); + inf.sysroot = sysroot; + + while ((line=in.readLine())!=null) + { + ShellVariableDef shvar; + + try + { + shvar = new ShellVariableDef(line); + } + catch (ShellVariableDef.XEmpty e) + { + continue; + } + catch (ShellVariableDef.XParseFailed e) + { + throw new RuntimeException("parse error in "+fn+": "+e); + } + + if (shvar.value.length()==0) + continue; + + if (shvar.name.equals("dlname")) + inf.dlname = shvar.value; + else if (shvar.name.equals("library_names")) + inf.dynamic_libnames = StrSplit.split(shvar.value); + else if (shvar.name.equals("old_library")) + inf.arname = shvar.value; + else if (shvar.name.equals("release")) + inf.release = shvar.value; + else if (shvar.name.equals("age")) + inf.version_age = shvar.getInt(0); + else if (shvar.name.equals("revision")) + inf.version_revision = shvar.getInt(0); + else if (shvar.name.equals("current")) + inf.version_current = shvar.getInt(0); + else if (shvar.name.equals("installed")) + inf.installed = shvar.getBoolean(); + else if (shvar.name.equals("shouldnotlink")) + inf.should_not_link = shvar.getBoolean(); + else if (shvar.name.equals("dlopen")) + inf.param_dlopen = shvar.value; + else if (shvar.name.equals("dlpreopen")) + inf.param_dlpreopen = shvar.value; + else if (shvar.name.equals("libdir")) +// inf.libdir = PathNormalizer.normalize_dir(prefix+shvar.value); + inf.libdir = norm.enc_sysroot(prefix+shvar.value); + else if (shvar.name.equals("dependency_libs")) + { + inf.dependency_names = StrSplit.split(shvar.value); + if (inf.dependency_names.length>0) + { + inf.dependencies = new LibraryInfo[inf.dependency_names.length]; + for (int y=0; y library search path: "+dirname); + search_path += " "+dirname; + } + else if (dep.endsWith(".la")) + { + dep = new File(dep).getCanonicalPath(); + System.out.println("Canonical path: "+dep); + if (dep.startsWith("/")) + inf.dependencies[y] = load_archive(sysroot+dep, sysroot, prefix); + else + inf.dependencies[y] = load_archive(dep, sysroot, prefix); + } + else + throw new RuntimeException("["+inf.dlname+"] --> unhandled depedency type: "+dep); + } + } + } + else + throw new RuntimeException + ( + "Unhandled variable: \""+ + shvar.name+"\" => \""+ + shvar.value+"\"" + ); + + } + + inf.prefix = prefix; + inf.search_pathes = StrSplit.split(search_path); + + // get the library name + // FIXME! + + if (inf.module_name == null) + { + String basename = new File(fn).getName(); + + if (basename.startsWith("lib")) + basename = basename.substring(3); + else + System.err.println("guess_libname: libname does not start with .la - guessing probably wrong: "+basename); + + if (!basename.endsWith(".la")) + throw new RuntimeException("filename does not end with .la - cannot guess libname:" +basename); + inf.module_name = basename.substring(0,basename.length()-3); + } + + // we have to do some fixups ... + if (inf.installed) + { + throw new RuntimeException("loading of installed libs not handled yet: "+fn); + } + else + { + // we currently enfoce static linking against non-installed libs + // i don't see any way out of this now -- FIXME !!! + // at least problematic packages like SDL (which links several + // .a's together to one .so) should work this way. + if (inf.arname.length()!=0) + inf.arname = LoadLibtool.tmp_libdir+inf.arname; + + inf.link_static = true; + + if ((inf.dynamic_libnames!=null)&&(inf.dynamic_libnames.length!=0)) + for (int x=0; x0) + { + inf.dependencies = new LibraryInfo[inf.dependency_names.length]; + for (int y=0; y unhandled depedency type: "+dep); + } + } + } + else + throw new RuntimeException + ( + "Unhandled variable: \""+ + shvar.name+"\" => \""+ + shvar.value+"\"" + ); + } + + inf.search_pathes = StrSplit.split(search_path); + + // get the library name + // FIXME! + + if (StrUtil.isEmpty(inf.module_name)) + { + String basename = new File(fn).getName(); + + if (!basename.endsWith(".la")) + throw new RuntimeException("filename does not end with .la - cannot guess libname:" +basename); + + inf.library_name = basename.substring(0,basename.length()-3); + if (inf.library_name.startsWith("lib")) + inf.module_name = inf.library_name.substring(3); + else + inf.module_name = inf.library_name; + } + + if (StrUtil.isEmpty(inf.libdir)) + { + System.out.println("[INFO] "+fn+" has no (dynamic) libdir. linking statically"); + link_uninstalled_static = true; + inf.link_static = true; + } + + // we have to do some fixups ... + if (inf.installed) + { + throw new RuntimeException("loading of installed libs not handled yet: "+fn); + } + else + { + // we can pass via parameter how to link uninstalled libs + // the libtool frontend gets this from $LT_UNITOOL_LINK_UNINSTALLED_STATIC + // at least problematic packages like SDL (which links several + // .a's together to one .so) should work this way. + + // FIXME: is this really correct ? + inf.link_static = link_uninstalled_static; + + if (inf.dynamic_libnames!=null) + for (int x=0; x \""+ + shvar.value+"\"" + ); + } + + System.out.println("LoadLibtoolObject(): fn=\""+fn+"\" pic=\""+inf.object_pic+"\" nonpic=\""+inf.object_nonpic); + + return inf; + } +} diff --git a/db/LoadPkgConfig.java b/db/LoadPkgConfig.java new file mode 100644 index 0000000..373de3a --- /dev/null +++ b/db/LoadPkgConfig.java @@ -0,0 +1,151 @@ + +package org.de.metux.unitool.db; + +import org.de.metux.util.ShellVariableDef; +import org.de.metux.util.StrSplit; +import org.de.metux.util.StrReplace; +import org.de.metux.util.PathNormalizer; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.File; +import java.io.FileReader; + +import org.de.metux.unitool.base.PackageInfo; +import org.de.metux.unitool.base.EPkgConfigMissingProperty; +import org.de.metux.unitool.base.EPkgConfigParseError; +import org.de.metux.unitool.base.EPkgConfigUnhandledProperty; + +public class LoadPkgConfig +{ + /* load the first part: variables/properties */ + static private void __handle_variable(PackageInfo inf, String line) + throws EPkgConfigParseError + { + try + { + ShellVariableDef shvar = new ShellVariableDef(line); + inf.properties.setProperty(shvar.name,shvar.value); + } + catch (ShellVariableDef.XEmpty e) + { + throw new EPkgConfigParseError("emty line: "+e,e); + } + catch (ShellVariableDef.XParseFailed e) + { + throw new EPkgConfigParseError("parse failed: "+e,e); + } + } + + static private void __handle_major(PackageInfo inf, String line) + throws EPkgConfigParseError, EPkgConfigUnhandledProperty + { + int pos = line.indexOf(':'); + if (pos<1) + throw new EPkgConfigParseError("missing \":\" in line \""+line+"\""); + + String name = line.substring(0,pos).trim(); + String value = line.substring(pos+1).trim(); + + if (name.equals("Name")) + inf.name = value; + else if (name.equals("Description")) + inf.description = value; + else if (name.equals("Version")) + inf.version = value; + else if (name.equals("Cflags")) + inf.cflags = value; + else if (name.equals("Cflags.private")) + inf.cflags_private = value; + else if (name.equals("Libs")) + inf.ldflags = value; + else if (name.equals("Libs.private")) + inf.ldflags_private = value; + else if (name.equals("Requires")) + inf.requires = value; + else if (name.equals("Requires.private")) + inf.requires_private = value; + else if (name.equals("Conflicts")) + inf.conflicts = value; + else + throw new EPkgConfigUnhandledProperty(name,value); + } + + static private String _strip_comments(String str) + { + int pos = str.indexOf('#'); + if (pos==-1) + return str; + if (pos==0) + return ""; + return str.substring(0,pos); + } + + /* load the second part: major fields */ + static private void __load_lines( + PackageInfo inf, + BufferedReader in, + PathNormalizer norm + ) + throws IOException, EPkgConfigParseError, EPkgConfigUnhandledProperty + { + String line; + while (true) + { + /* go out when no more to read */ + if ((line=in.readLine())==null) + return; + + /* go out on newline */ + line = _strip_comments(line).trim(); + if (line.length()==0) + ; + else if (line.indexOf(':')>=0) + __handle_major(inf, line); + else if (line.indexOf('=')>=0) + __handle_variable(inf, line); + else + throw new EPkgConfigParseError("cannot parse line: \""+line+"\""); + } + } + + static private void __sanity_checks(PackageInfo inf) + throws EPkgConfigMissingProperty + { + /* sanity checks for several required fields */ + if (inf.name==null) + throw new EPkgConfigMissingProperty("Name"); + if (inf.description==null) + throw new EPkgConfigMissingProperty("Description"); + if (inf.version==null) + throw new EPkgConfigMissingProperty("Version"); + if (inf.cflags==null) + throw new EPkgConfigMissingProperty("Cflags"); + } + + static public PackageInfo load_package( + String absolute_filename, + String sysroot + ) + throws FileNotFoundException, IOException, + EPkgConfigMissingProperty, + EPkgConfigParseError, + EPkgConfigUnhandledProperty + { + PathNormalizer norm = new PathNormalizer(); + norm.setSysroot(sysroot); + + BufferedReader in = + new BufferedReader(new FileReader(absolute_filename)); + + String line; + PackageInfo inf = new PackageInfo(); + inf.sysroot = sysroot; + + __load_lines(inf,in,norm); + __sanity_checks(inf); + + return inf; + } +} diff --git a/db/ObjectInfo.java b/db/ObjectInfo.java new file mode 100644 index 0000000..a451656 --- /dev/null +++ b/db/ObjectInfo.java @@ -0,0 +1,11 @@ + +package org.de.metux.unitool.db; + +import org.de.metux.unitool.base.ToolParam; + +public class ObjectInfo +{ + public String lo_file; + public String object_pic; + public String object_nonpic; +} diff --git a/db/PackageInfo.java b/db/PackageInfo.java new file mode 100644 index 0000000..4961071 --- /dev/null +++ b/db/PackageInfo.java @@ -0,0 +1,17 @@ + +package org.de.metux.unitool.db; + +import org.de.metux.util.Stringtable; + +/* pkg-config style data record */ +public class PackageInfo +{ + public String name = null; + public String description = null; + public String version = null; + public String cflags = ""; + public String libs = ""; + public String sysroot = null; + + Stringtable properties = new Stringtable(); +} diff --git a/db/QueryPkgConfig.java b/db/QueryPkgConfig.java new file mode 100644 index 0000000..fceb50b --- /dev/null +++ b/db/QueryPkgConfig.java @@ -0,0 +1,103 @@ + +package org.de.metux.unitool.db; + +import org.de.metux.util.ShellVariableDef; +import org.de.metux.util.StrSplit; +import org.de.metux.util.StrReplace; +import org.de.metux.util.PathNormalizer; +import org.de.metux.util.StrUtil; +import org.de.metux.util.Environment; +import org.de.metux.util.Exec; +import org.de.metux.util.CmdLineSplitter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.File; +import java.io.FileReader; + +import org.de.metux.unitool.base.PackageInfo; +import org.de.metux.unitool.base.EPkgConfigMissingProperty; +import org.de.metux.unitool.base.EPkgConfigParseError; +import org.de.metux.unitool.base.EPkgConfigUnhandledProperty; + +public class QueryPkgConfig +{ + String query_command; + String path; + String sysroot; + + public QueryPkgConfig() + { + query_command = Environment.getenv("PKG_CONFIG"); + } + + public void setPath(String p) + { + path = p; + } + + public void setCommand(String cmd) + { + query_command = cmd; + } + + public void setSysroot(String sr) + { + sysroot = sr; + } + + public PackageInfo queryPackage(String pkgname, String minversion) + { + if (StrUtil.isEmpty(query_command)) + throw new RuntimeException("query_command not set"); + if (StrUtil.isEmpty(path)) + throw new RuntimeException("path not set"); + + String pkg_config = "export PKG_CONFIG_PATH=\""+path+"\" ; "+query_command; + String suffix = " || echo PKG_CONFIG_QUERY_ERROR"; + +// String cmd_cflags = pkg_config+" --cflags "+pkgname+suffix; +// String cmd_ldflags = pkg_config+" --libs "+pkgname+suffix; + + // we have to call pkgconfig + String cflags = new Exec().run_catch(pkg_config+" --cflags "+pkgname+suffix); + String ldflags = new Exec().run_catch(pkg_config+" --libs "+pkgname+suffix); + + if ((cflags.indexOf("PKG_CONFIG_QUERY_ERROR")!=-1) || + (ldflags.indexOf("PKG_CONFIG_QUERY_ERROR")!=-1)) + throw new RuntimeException("Query error"); + + PackageInfo pkg = new PackageInfo(); + if (!StrUtil.isEmpty(sysroot)) + pkg.sysroot = sysroot; + + /* process cflags */ + { + String elems[] = CmdLineSplitter.split(cflags); + for (int x=0; x\n"; + + // check if we have some variable + String res = ""; + int startpos = 0; + int endpos = -1; + while ((startpos=value.indexOf("${",endpos))>=0) + { + if ((endpos = value.indexOf("}",startpos))1) + throw new RuntimeException("more than one input given"); + + // if no source file has been passed, guess it from output filename + // we currently do not even support explicit source files + // ... lets see whether we need them at all ... + if (output_filename==null) + output_filename=PathNormalizer.replace_suffix(src[0],"o"); + + debug("output_filename=\""+output_filename); + } + + ObjectInfo objinf = new ObjectInfo(); + String dirname = PathNormalizer.dirname(output_filename); + String basename = PathNormalizer.basename(output_filename); + + // process output filename + if (output_filename.endsWith(".o")) + { + objinf.lo_file = output_filename.substring(0,output_filename.length()-2)+".lo"; + objinf.object_pic = (StrUtil.isEmpty(dirname) ? "" : "/")+LoadLibtoolArchive.tmp_libdir+"/"+basename; + objinf.object_nonpic = output_filename; + } + else if (output_filename.endsWith(".lo")) + { + dirname = PathNormalizer.dirname_slash(output_filename); + String objname = basename.substring(0,basename.length()-3)+".o"; + objinf.lo_file = output_filename; + objinf.object_pic = LoadLibtoolArchive.tmp_libdir+objname; + objinf.object_nonpic = objname; + } + else + throw new RuntimeException("compiler output file should end with .o: \""+output_filename+"\""); + + pic.setSysroot(sysroot); + pic.normalizer.addSkip(srcdir); + pic.setCompilerCommand(compiler_command); + pic.addDefine(defines.getNames()); + pic.addIncludePath_enc_sysroot(include_pathes.getNames()); + pic.addInitDirs(LoadLibtoolArchive.tmp_libdir); + pic.setOutputFile(dirname+objinf.object_pic); + pic.addVerbatim(verbatims.getNames()); + pic.addSourceFile(sources.getNames()); + pic.addCompilerFlag(compiler_flags.getNames()); + pic.setMkDependOutput(mkdepend_output); + pic.setMkDependTarget(mkdepend_target); + pic.setPIC(true); + + nopic.normalizer.addSkip(srcdir); + nopic.setSysroot(sysroot); + nopic.setCompilerCommand(compiler_command); + nopic.addDefine(defines.getNames()); + nopic.addIncludePath_enc_sysroot(include_pathes.getNames()); + nopic.addInitDirs(LoadLibtoolArchive.tmp_libdir); + nopic.setOutputFile(dirname+objinf.object_nonpic); + nopic.addVerbatim(verbatims.getNames()); + nopic.addSourceFile(sources.getNames()); + nopic.setMkDependOutput(mkdepend_output); + nopic.setMkDependTarget(mkdepend_target); + nopic.addCompilerFlag(compiler_flags.getNames()); + + new CCompiler().run(pic); + new CCompiler().run(nopic); + + // now write the .lo file + StoreLibtoolObject.store(objinf); + } +} diff --git a/libtool/CmdInstall.java b/libtool/CmdInstall.java new file mode 100644 index 0000000..741613b --- /dev/null +++ b/libtool/CmdInstall.java @@ -0,0 +1,144 @@ + +package org.de.metux.unitool.libtool; + +import java.io.File; + +import org.de.metux.util.Environment; +import org.de.metux.util.StrReplace; +import org.de.metux.util.FileOps; +import org.de.metux.util.PathNormalizer; + +import org.de.metux.propertylist.IPropertylist; + +import org.de.metux.unitool.base.ToolConfig; +import org.de.metux.unitool.base.ToolParam; +import org.de.metux.unitool.base.InstallerParam; +import org.de.metux.unitool.base.EParameterMissing; +import org.de.metux.unitool.base.EParameterInvalid; +import org.de.metux.unitool.db.LoadLibtoolArchive; +import org.de.metux.unitool.tools.LTLibraryInstaller; + +public class CmdInstall +{ + InstallerParam param; + String args[]; + ToolConfig config; + + CmdInstall(String[] argv, ToolConfig cf) throws Exception + { + config = cf; + args = argv; + } + + public String[] stripfirst(String par[]) + { + String n[] = new String[par.length]; + for (int x=0; x<(par.length-1); x++) + n[x] = par[x+1]; + return n; + } + + public void run_c() + throws EParameterMissing, EParameterInvalid + { + if (args[0].equals("-s")) + { + param.setInstallStrip(); + args = stripfirst(args); + run_c(); + return; + } + + if (args[0].equals("-m")) + { + System.err.println("Ignoring Mode: "+args[1]); + args = stripfirst(stripfirst(args)); + run_c(); + return; + } + + if (args[0].equals("-c")) + { + System.err.println("[LT-Install] Ignoring -c"); + args = stripfirst(args); + run_c(); + return; + } + + if (args[0].endsWith(".la") && args[1].endsWith(".la")) + { + System.out.println("LTLibraryInstaller Param: "+param); + param.setInstallSource(args[0]); + param.setInstallTarget(args[1]); + new LTLibraryInstaller().run(param); + } + else if (args[0].endsWith(".la")) + { + System.out.println("Assuming we wanna install .la to directory "+args[1]); + param.setInstallSource(args[0]); + param.setInstallTarget(args[1]+"/"+PathNormalizer.basename(args[0])); + new LTLibraryInstaller().run(param); + } + else + { + String src = args[0]; + String dst = args[1]; + String src_dirname = PathNormalizer.dirname(src); + String src_basename = PathNormalizer.basename(src); + System.out.println("Assuming we wanna install an binary: "+src); + + String real_src = + ((src_dirname.length()!=0) ? (src_dirname+"/") : "")+ + LoadLibtoolArchive.tmp_libdir+ + src_basename; + + System.out.println("Try_copy: real_src="+real_src); + System.out.println(" dst="+dst); + + if (new File(real_src).exists()) + { + System.out.println("OKAY; file exists. we can copy it.\n"); + FileOps.cp(real_src,dst); + } + else + throw new RuntimeException("Source file does not exist. Either build incomplete or parameter scheme not understood"); + } + } + + public void run() + throws EParameterMissing, EParameterInvalid + { + if (args.length<2) + throw new RuntimeException("missing installer command set"); + + if (args[1].equals("--finish")) + { + System.out.println("Installer: finishing -> nothing to do"); + return; + } + + param = new InstallerParam(config); + + param.setSysroot(Environment.getenv("SYSROOT")); + param.setInstallerCommand(args[1]); + param.normalizer.addSkip(Environment.getenv("SRCDIR")); + + System.out.println("Installer command: "+args[1]); + + args = stripfirst(stripfirst(args)); + + if (args[0].endsWith("/install-sh")) + args = stripfirst(args); + + if (args[0].equals("-c")) + { + args = stripfirst(args); + run_c(); + } + else + throw new RuntimeException("this kind of parameter not (yet) understood: \""+ + args[2]+"\" \""+args[3]+"\" \""+args[4]+"\"" ); + + // FIXME !!! + } +} diff --git a/libtool/CmdLink.java b/libtool/CmdLink.java new file mode 100644 index 0000000..755239b --- /dev/null +++ b/libtool/CmdLink.java @@ -0,0 +1,473 @@ +// +// FIXME: should handle the export-symbols-regex linker parameters +// by giving it to the actual tools +// + +package org.de.metux.unitool.libtool; + +import org.de.metux.util.Environment; +import org.de.metux.util.StrReplace; +import org.de.metux.util.FileOps; +import org.de.metux.util.PathNormalizer; +import org.de.metux.util.StrSplit; +import org.de.metux.util.StrUtil; +import org.de.metux.util.UniqueValues; + +import org.de.metux.propertylist.IPropertylist; + +import org.de.metux.unitool.base.ToolParam; +import org.de.metux.unitool.base.LinkerParam; +import org.de.metux.unitool.base.EUnitoolError; +import org.de.metux.unitool.base.LibraryInfo; +import org.de.metux.unitool.base.ObjectInfo; +import org.de.metux.unitool.base.ToolConfig; + +import org.de.metux.unitool.db.LoadLibtoolArchive; +import org.de.metux.unitool.db.LoadLibtoolObject; +import org.de.metux.unitool.db.StoreLibtoolArchive; + +import org.de.metux.unitool.tools.LinkSharedLibrary; +import org.de.metux.unitool.tools.LinkExecutable; +import org.de.metux.unitool.tools.LinkStaticLibrary; + +import java.io.IOException; +import java.util.Enumeration; + +public class CmdLink +{ + /* link libraries from within our sourcetree (aka addressed via + relative path) by directly passing library filename */ + boolean ltmagic_intree_link_direct = true; + + String sysroot; + String release; + LinkerParam param; + + boolean link_uninstalled_static = false; + boolean link_ar_recursive = Environment.getenv_bool("LT_UNITOOL_LINK_AR_RECURSIVE",false); + + ToolConfig config; + + String [] my_args; + + CmdLink(String[] argv, ToolConfig cf) throws Exception, EUnitoolError + { + my_args = argv; + config = cf; + } + + void processLibraryImport(String libs[], LinkerParam par, boolean uninstalled_static) + throws IOException + { + for (int x=0; x Parameter["+x+"]: "+current); + + if (current.equals("-Wall") || + current.equals("-Wpointer-arith") || + current.equals("-Wmissing-prototypes") + ) + System.err.println("NOTICE: ignoring useless parameter: "+current); + else if (current.equals("-include")) + System.err.println("NOTICE: ignoring useless parameter: -include "+my_args[++x]); + else if (current.startsWith("-I")) + System.err.println("NOTICE: ignoring useless parameter: "+current); + else if (current.equals("-g") || + current.equals("-O2") || + current.startsWith("-march=") || + current.startsWith("-mcpu=") || + current.equals("-export-dynamic") || + current.startsWith("-W") || + current.startsWith("-f") + ) + { + System.err.println("FIXME: adding verbatim: "+current); + param.addVerbatim(current); + } + else if (current.equals("-o")) + { + _output = my_args[++x]; + param.setOutputFile(_output); + } + // FIXME ! + else if (current.equals("-export-symbols")) + param.addExportSymbols(my_args[++x]); + else if (current.equals("-export-symbols-regex")) + param.addExportSymbolsRegex(my_args[++x]); + else if (current.equals("-no-undefined")) + param.addLinkFlag("no-undefined"); + else if (current.equals("-version-info")||current.equals("-version-number")) + param.setVersionInfo(my_args[++x]); + else if (current.equals("-pthread")) + param.addSharedLink("pthread"); + else if ((current.equals("-rpath"))||(current.equals("-R"))) + param.addRuntimeLibraryPath(my_args[++x]); + else if (current.equals("-release")) + release = my_args[++x]; + else if (current.startsWith("-D")) + ; // param.addDefine(current.substring(2)); + else if (current.startsWith("-L")) + param.addLibraryPath_enc_sysroot(current.substring(2)); + else if (current.startsWith("-l")) + param.addSharedLink(current.substring(2)); + else if (current.endsWith(".lo")) + { + ObjectInfo objinf = LoadLibtoolObject.load_lo(current); + // FIXME: we're currently only using PIC code + param.addObjectLink(objinf.object_pic); + } + else if (current.endsWith(".o")) + param.addObjectLink(current); + else if (current.endsWith(".la")) + param.addLibraryImport(current); + else if (current.endsWith(".a")) + param.addStaticLink(current); + else +// throw new RuntimeException("UNHANDLED PARAM: "+current); + { + System.err.println("WARN: adding verbatim parameter:"+current); + param.addVerbatim(current); + } + } + + /* process output file option */ + if (_output == null) + throw new RuntimeException("no output given"); + + if (_output.endsWith(".la")) + target_type_la(); + else if (_output.endsWith(".a")) + throw new RuntimeException("linking directly to .a files not supported"); + else if (_output.endsWith(".so")) + throw new RuntimeException("linking directly to .so files not supported"); + else if (_output.endsWith(".lo")) + throw new RuntimeException("linking to .lo files not supported"); + else if (_output.endsWith(".o")) + throw new RuntimeException("linking to .o files not supported"); + else + target_type_executable(); + } + + // create a shared library as .la file + + // library_name is w/ lib*, but module_name is without (ie. for -l) + public void target_type_la() + throws IOException + { + String output_la_file = param.getOutputFile(); + String output_basename = PathNormalizer.basename(output_la_file); + String output_dirname = PathNormalizer.dirname_slash(output_la_file); + String module_name; + + // library name without "lib" and ".so", just "foo" + String library_name = output_basename.substring(0,output_basename.lastIndexOf(".la")); + if (library_name.startsWith("lib")) + module_name = library_name.substring(3); + else + { + module_name = library_name; + System.err.println("CmdLink::target_type_la(): WARNING: output filename should start with \"lib\""); + } + + if (!StrUtil.isEmpty(release)) + library_name += "-"+release; + + System.out.println("LIBRARY: library_name="+library_name+" module="+module_name); + + // libfoo.so + libfoo.a + String shared_library_short = library_name+".so"; + String static_archive_file = library_name+".a"; + + FileOps.mkdir(LoadLibtoolArchive.tmp_libdir); + FileOps.mkdir(output_dirname+LoadLibtoolArchive.tmp_libdir); + + /* -- fetch out parameters -- */ + String par_objectlinks[] = param.getObjectLinks(); + String par_staticlinks[] = param.getStaticLinks(); + String par_verbatims[] = param.getVerbatims(); + String par_exportsymregex[] = param.getExportSymbolsRegex(); + String par_exportsymbols[] = param.getExportSymbols(); + String par_imports[] = param.getLibraryImports(); + String par_linkflag = param.getLinkFlag(); + String par_sysroot = param.getSysroot(); + + String rpath[] = param.getRuntimeLibraryPathes(); + if ((rpath==null)||(rpath.length==0)) + throw new RuntimeException("missing rpath"); + + if (rpath.length>1) + throw new RuntimeException("more than one rpath given"); + + LibraryInfo[] imports = new LibraryInfo[par_imports.length]; + for (int x=0; x Creating libtool library: "+output_la_file); + System.out.println(" module_name="+module_name); + System.out.println(" library_name="+library_name); + System.out.println(" arname="+static_archive_file); + System.out.println(" release="+release); + + // generate libtool information for uninstalled library + libinf.prefix = ""; + libinf.libdir = rpath[0]; + libinf.installed = false; + libinf.library_name = library_name; + libinf.module_name = module_name; + libinf.version_current = param.getVersionCurrent_i(); + libinf.version_age = param.getVersionAge_i(); + libinf.version_revision = param.getVersionRevision_i(); + libinf.arname = static_archive_file; + libinf.release = release; + libinf.search_pathes = param.getLibraryPathes(); + + if (libinf.search_pathes != null) + for (int x=0; x imported lib ("+imports[x].library_name+") is linked statically - skipping it from .la's dependency list" ); + else + deps += " "+par_imports[x]; + } + } + + for (int x=0; x\""+param.get(key)+"\""); + } + } +} diff --git a/libtool/Main.java b/libtool/Main.java new file mode 100644 index 0000000..bd926c8 --- /dev/null +++ b/libtool/Main.java @@ -0,0 +1,69 @@ + +package org.de.metux.unitool.libtool; + +import org.de.metux.unitool.db.UnitoolConf; +import org.de.metux.util.StrUtil; +import org.de.metux.propertylist.IPropertylist; +import org.de.metux.unitool.base.ToolConfig; + +public class Main +{ + static String tag; + static boolean silent = false; + + static void exit_err(String text) + { + System.err.println(text); + System.exit(1); + } + + static private String[] cutfirstarg(String argv[]) + { + String newarg[] = new String[argv.length-1]; + for (int x=0; x<(argv.length-1); x++) + newarg[x] = argv[x+1]; + return newarg; + } + + public static void main(String argv[]) throws Exception + { + if (argv.length==0) + exit_err("missing parameters"); + + // FIXME: should be used somewhere ? + if (argv[0].startsWith("--tag=")) + { + tag = argv[0].substring(6); + main(cutfirstarg(argv)); + return; + } + + if (argv[0].equals("--preserve-dup-deps")) + { + main(cutfirstarg(argv)); + return; + } + + if (argv[0].equals("--silent")) + { + silent = true; + main(cutfirstarg(argv)); + return; + } + + ToolConfig config = UnitoolConf.getToolConfig(); + + // load system + if (argv[0].equals("--mode=link")) + new CmdLink(argv,config).run(); + else if (argv[0].equals("--mode=compile")) + new CmdCompile(argv,config).run(); + else if (argv[0].equals("--mode=install")) + new CmdInstall(argv,config).run(); + else + exit_err("unsupported mode: "+argv[0]); + + System.exit(0); +// return 0; + } +} diff --git a/misc/libtool b/misc/libtool new file mode 100755 index 0000000..c56e089 --- /dev/null +++ b/misc/libtool @@ -0,0 +1,8 @@ +#!/bin/bash + +export TCPREFIX=/opt/xcompiler/jail/ +export SYSROOT=$TCPREFIX/jail/sys-root +export CC=$TCPREFIX/bin/gcc +export LD=$TCPREFIX/bin/ld + +/home/devel/projects/unitool-java/run-libtool $* diff --git a/tools/CCompiler.java b/tools/CCompiler.java new file mode 100644 index 0000000..8edf063 --- /dev/null +++ b/tools/CCompiler.java @@ -0,0 +1,76 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.EParameterMissing; +import org.de.metux.unitool.base.EUnhandledCompilerFlag; +import org.de.metux.unitool.base.CCompilerParam; +import org.de.metux.util.Exec; +import org.de.metux.util.Environment; +import java.util.Enumeration; +import org.de.metux.propertylist.*; +import org.de.metux.util.*; + +public class CCompiler +{ + public void run(CCompilerParam param) + throws EParameterMissing, EUnhandledCompilerFlag + { + // FIXME: verbatims + // FIXME: compiler-command + String sysroot = param.getSysroot(); + Gcc_cmdline gcc; + + // process init-dirs + FileOps.mkdir(param.getInitDirs()); + + // fetch linker command + String compiler_command = param.getCompilerCommand(); + if (StrUtil.isEmpty(compiler_command)) + compiler_command = Environment.getenv("CC"); + if (StrUtil.isEmpty(compiler_command)) + throw new EParameterMissing("compiler-command"); + + // FIXME !!! + gcc = new Gcc_cmdline(compiler_command+" -c "); + + gcc.warning_flag(param.getWarningFlags()); + gcc.compiler_flag(param.getCompilerFlags()); + gcc.verbatims(param.getVerbatims()); + gcc.mk_depend_output(param.getMkDependOutput()); + gcc.mk_depend_target(param.getMkDependTarget()); + gcc.output_filename(param.getOutputFile()); + gcc.addIncludePath(param.getIncludePathes_add_sysroot()); + gcc.addDefine(param.getDefines()); + gcc.srcs(param.getSourceFiles()); + gcc.addIncludeFile(param.getIncludeFiles()); + + param.clearVerbatim(); + param.clearMkDependOutput(); + param.clearMkDependTarget(); + param.clearOutputFile(); + param.clearIncludePath(); + param.clearDefine(); + param.clearSourceFile(); + param.clearCompilerFlag(); + param.clearCompilerCommand(); + param.clearSysroot(); + param.clearInitDirs(); + param.clearWarningFlag(); + param.clearIncludeFile(); + + for (Enumeration e=param.propertyNames(); e.hasMoreElements(); ) + { + String par = (String)e.nextElement(); + String val = (String)param.get(par); + throw new RuntimeException("tools/CCompiler: unhandled param: "+par+"=\""+val+"\""); + } + + String cmdline = gcc.toString(); + + Exec exec = new Exec(); + System.out.println("===> CCompiler: "+cmdline); + + if (!exec.run(cmdline)) + throw new RuntimeException("Exec failed: "+cmdline); + } +} diff --git a/tools/Gcc_cmdline.java b/tools/Gcc_cmdline.java new file mode 100644 index 0000000..689b0a9 --- /dev/null +++ b/tools/Gcc_cmdline.java @@ -0,0 +1,289 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.EUnhandledCompilerFlag; +import org.de.metux.util.HTMLEntities; +import org.de.metux.util.ShellEscape; +import org.de.metux.util.PathNormalizer; +import org.de.metux.util.FileOps; +import org.de.metux.util.StrUtil; +import org.de.metux.unitool.base.CCompilerParam; + +public class Gcc_cmdline +{ + String cmdline = ""; + PathNormalizer normalizer; + String warning_flags = ""; + + boolean create_pic = false; + boolean create_shared = false; + + public Gcc_cmdline(String s) + { + cmdline = s; + } + + public void setNormalizer(PathNormalizer n) + { + normalizer = n; + } + + public String toString() + { + return cmdline+ + warning_flags+ + (create_pic ? " -fPIC -DPIC " : "")+ + (create_shared ? " -shared " : ""); + } + + public void libpath(String p) + { + if (!StrUtil.isEmpty(p)) + cmdline += " -L"+normalizer.dec_sysroot(p); + } + + public void libpath(String[] par) + { + if (par!=null) + for (int x=0; x0) + cmdline += " -l"+par[x]; + } + + public void objlink(String[] par) + { + if (!StrUtil.isEmpty(par)) + for (int x=0; x0) + cmdline += " "+par[x]; + } + + public void linker_flag(String flag) + { + if (flag.equals("no-undefined")) + cmdline += " -no-undefined"; + else + throw new RuntimeException("unhandled flag: "+flag); + } + + public void warning_flag(String flag[]) + { + if (flag!=null) + for (int x=0; x0) + { + System.err.println("GCC-backend: adding verbatim: "+par[x]); + cmdline += " \""+par[x]+"\""; + } + } + + public void srcs(String[] par) + { + if (!StrUtil.isEmpty(par)) + for (int x=0; x0) + cmdline += " "+par[x]; + } + + public void mk_depend_output(String par) + { + if (!StrUtil.isEmpty(par)) + cmdline += " -MF "+par; + } + + public void mk_depend_target(String par) + { + if (!StrUtil.isEmpty(par)) + cmdline += " -MT "+par; + } + + public void shared(boolean sh) + { + create_shared = sh; + } + + public void setPIC(boolean flag) + { + create_pic = flag; + } + + public void exportSymbols(String re[]) + { + if (re!=null) + for (int x=0; x0) + addpar += " -l"+par[x]; + } + + public void objlink(String[] par) + { + if (!StrUtil.isEmpty(par)) + for (int x=0; x0) + addpar += " "+par[x]; + } + + public void linker_flag(String flag) + { + if (StrUtil.isEmpty(flag)) + return; + + if (flag.equals("no-undefined")) + prohibit_undefined = true; + else if (flag.equals("strip-debug")) + strip_debug = true; + else + throw new RuntimeException("unhandled flag: "+flag); + } + + public void linker_flag(String[] par) + { + if (par!=null) + for (int x=0; x0) + { + System.err.println("WARNING: LD: adding verbatim parameter \""+par[x]+"\" -- will be removed soon!"); + cmdline += " \""+par[x]+"\""; +// throw new RuntimeException(" !!! VERBATIM PARAMETERS NO LONGER SUPPORTED !!!: "+par[x]); + } + } +} diff --git a/tools/LTLibraryInstaller.java b/tools/LTLibraryInstaller.java new file mode 100644 index 0000000..3439cd1 --- /dev/null +++ b/tools/LTLibraryInstaller.java @@ -0,0 +1,228 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.LibraryInfo; +import org.de.metux.unitool.base.ToolParam; +import org.de.metux.unitool.base.InstallerParam; +import org.de.metux.unitool.base.EParameterMissing; +import org.de.metux.unitool.base.EParameterInvalid; +import org.de.metux.unitool.db.StoreLibtoolArchive; +import org.de.metux.unitool.db.LoadLibtoolArchive; + +import org.de.metux.util.Exec; +import org.de.metux.util.Environment; +import org.de.metux.util.StrUtil; +import org.de.metux.util.PathNormalizer; +import org.de.metux.util.FileOps; +import org.de.metux.util.StrSplit; +import org.de.metux.util.UniqueValues; + +import java.io.IOException; +import java.io.File; + +public class LTLibraryInstaller +{ + void __check_arname(LibraryInfo libinf) + { + String str = libinf.library_name+ + (StrUtil.isEmpty(libinf.release) ? "" : "-"+libinf.release)+ + ".a"; + + if (!libinf.arname.equals(str)) + System.err.println("arname may be broken: arname="+libinf.arname+" modname="+libinf.module_name+" libname="+libinf.library_name+" should be="+str); + } + + String __libdirs(LibraryInfo libinf, PathNormalizer norm) + { + String str = ""; + + if (!StrUtil.isEmpty(libinf.libdir)) + str += " -L"+libinf.libdir; + + if (libinf.search_pathes!=null) + for (int x=0; x selected to be linked statically. no dependency filed."); + if (!StrUtil.isEmpty(cur.libdir)) + throw new RuntimeException("uuh, why is libdir set ?"); + } + else + { + System.out.println(" ==> selected to be linked dynamically "+cur.library_name+" / "+cur.module_name); + + // we have no libtool file for it. + if (StrUtil.isEmpty(cur.cf)) + { + add_dep = __libdirs(cur, norm) + " -l"+cur.module_name; + } + // libtool'ed library + else + { + if (StrUtil.isEmpty(cur.libdir)) + throw new RuntimeException("uuh, why is libdir empty ?!"); + add_dep = cur.libdir+"/"+PathNormalizer.basename(cur.cf); + } + } + + System.out.println(" ==> adding: "+add_dep); + return add_dep; + } + + public void run(InstallerParam param) + throws EParameterMissing, EParameterInvalid + { + LibraryInfo libinf; + String installer_cmd = param.getInstallerCommand(); + String la_source = param.getInstallSource(); + String la_target = param.getInstallTarget(); + + // FIXME ! + if (!la_source.endsWith(".la")) + throw new RuntimeException("*.la as source expected"); + + if (!la_target.endsWith(".la")) + throw new RuntimeException("*.la as target expected"); + + String parent = new File(la_target).getParent(); + if (parent==null) + throw new RuntimeException("parent is null ! ("+la_target+")"); + + String dirname=PathNormalizer.dirname(la_source); + try + { + libinf = LoadLibtoolArchive.load_archive( + la_source, param.getSysroot(), dirname, false); + } + catch (IOException e) + { + throw new RuntimeException("loading .la archive failed"+e,e); + } + + if (!StrUtil.isEmpty(libinf.dlname)) + if (libinf.dlname.equals("null")) + throw new RuntimeException("someone messed up dlname"); + else + throw new RuntimeException("why isn't dlname null ?: "+libinf.dlname); + + libinf.dlname = libinf.library_name+".so."+libinf.version_current+"."+libinf.version_age+"."+libinf.version_revision; + + __check_arname(libinf); + + // libinf.dlname has the form libfoo.so.1 + String so_source = + (StrUtil.isEmpty(libinf.prefix) ? "" : libinf.prefix+"/")+ + libinf.uninstalled_libdir+ + libinf.library_name+ + (StrUtil.isEmpty(libinf.release) ? "" : "-"+libinf.release)+ + ".so"; + + String so_link2 = libinf.library_name+".so"; + String so_link1 = libinf.library_name+".so."+libinf.version_current; + String so_name = libinf.library_name+".so."+libinf.version_current+"."+libinf.version_age+"."+libinf.version_revision; + String so_target = parent+"/"+libinf.dlname; + + // do some fixes in the .la file + libinf.installed = true; + libinf.dlname = so_link1; + libinf.dynamic_libnames = new String[3]; + libinf.dynamic_libnames[0] = so_name; + libinf.dynamic_libnames[1] = so_link1; + libinf.dynamic_libnames[2] = so_link2; + + System.out.println( + "LTLibraryInstaller: processing .la file: "+la_source+"\n"+ + " parent="+parent+"\n"+ + " so_target="+so_target+"\n"+ + " so_source="+so_source+"\n"+ + " libdir="+libinf.libdir + ); + if (libinf.search_pathes == null) + System.out.println(" No search pathes"); + else + for (int x=0; x ExecutableLinker: "+cmdline); + Exec exec = new Exec(); + + if (!exec.run(cmdline)) + throw new RuntimeException("Exec failed: "+cmdline); + } +} + diff --git a/tools/LinkSharedLibrary.java b/tools/LinkSharedLibrary.java new file mode 100644 index 0000000..61ed1dc --- /dev/null +++ b/tools/LinkSharedLibrary.java @@ -0,0 +1,114 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.LinkerParam; +import org.de.metux.util.Exec; +import org.de.metux.util.Environment; +import org.de.metux.util.StrUtil; +import org.de.metux.util.StrReplace; + +public class LinkSharedLibrary extends LinkerBase +{ + // FIXME: put this into the unitool config file + public String dl_filename_mask_noversion = "lib{MODULE_NAME}.so"; + public String dl_filename_mask_version = "lib{MODULE_NAME}.so.{VERSION_INFO}"; + + public LinkSharedLibrary(LinkerParam p) + { + super(p); + } + + public void run() + { + LD_cmdline ld; + + // we do not use the "linker-command" property anylonger + // those things are now completely encapsulated behind unitool + String linker_command = + param.config.getConfigStr( + LinkerParam.cf_linker_dll_command, + Environment.getenv("LD")); + + // FIXME !!! + param.addRuntimeLibraryPath("/usr/lib"); + + // fetch linker command + if (StrUtil.isEmpty(linker_command)) + throw new RuntimeException("missing propery "); + + // first we have to get all static links handled + handle_static_libs(); + + // filter out duplicate objects + filter_objects(); + + ld = new LD_cmdline(linker_command,param.normalizer); + +// boolean flag_strip_debug = false; + + String flags[] = param.getLinkFlags(); +// if (flags!=null) +// { +// for (int x=0; x SharedLibraryLinker: "+cmdline); + Exec exec = new Exec(); + + if (!exec.run(cmdline)) + throw new RuntimeException("Exec failed: "+cmdline); + } +} diff --git a/tools/LinkStaticLibrary.java b/tools/LinkStaticLibrary.java new file mode 100644 index 0000000..ed4a96f --- /dev/null +++ b/tools/LinkStaticLibrary.java @@ -0,0 +1,53 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.LinkerParam; +import org.de.metux.unitool.db.LoadLibtoolArchive; +import org.de.metux.util.Exec; +import org.de.metux.util.FileOps; +import java.io.File; + +public class LinkStaticLibrary extends LinkerBase +{ + public LinkStaticLibrary(LinkerParam p) + { + super(p); + } + + public void run() + { + String output = param.getOutputFile(); + + if (output.length()==0) + throw new RuntimeException("missing property "); + + // first step: create archive + FileOps.mkdir(LoadLibtoolArchive.tmp_libdir); + String cmdline_ar = "pwd && "+ar_command()+" cru "+output; + + /* -- now extract the .a files and add them to the list -- */ + /* -- MUST be done before we're handling objects -- */ + handle_static_libs(); + + /* --- add all direct object links to the command list --- */ + filter_objects(); + + { + String input[] = param.getObjectLinks(); + if (input.length==0) + throw new RuntimeException("missing property "); + for (int x=0; x LinkStaticLibrary: (ar) "+cmdline_ar); + if (!(new Exec().run(cmdline_ar))) + throw new RuntimeException("Exec failed: "+cmdline_ar); + + // now call ranlib + String commandline = ranlib_command()+" "+output; + System.out.println("==> LinkStaticLibrary: (ranlib) "+commandline); + if (!(new Exec().run(cmdline_ar))) + throw new RuntimeException("Exec failed: "+commandline); + } +} diff --git a/tools/LinkerBase.java b/tools/LinkerBase.java new file mode 100644 index 0000000..f808722 --- /dev/null +++ b/tools/LinkerBase.java @@ -0,0 +1,129 @@ + +package org.de.metux.unitool.tools; + +import org.de.metux.unitool.base.LinkerParam; +import org.de.metux.util.FileStock; +import org.de.metux.util.Exec; +import org.de.metux.util.Environment; +import org.de.metux.util.rm; +import org.de.metux.util.StrUtil; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +public class LinkerBase +{ + public LinkerParam param; + public String cmd_ar = null; + public String cmd_ranlib = null; + + public LinkerBase(LinkerParam p) + { + param = p; + } + + public String ar_command() + { + if (cmd_ar != null) + return cmd_ar; + + // fetch ar/ranlib command + cmd_ar = Environment.getenv("AR"); + + if (StrUtil.isEmpty(cmd_ar)) + throw new RuntimeException("missing env $AR"); + + return cmd_ar; + } + + public String ranlib_command() + { + if (cmd_ranlib != null) + return cmd_ranlib; + + // fetch ar/ranlib command + cmd_ranlib = Environment.getenv("RANLIB"); + + if (StrUtil.isEmpty(cmd_ranlib)) + throw new RuntimeException("missing env $RANLIB"); + + return cmd_ranlib; + } + + public void ar_x(String filename, String target) + { + if (filename==null) + throw new NullPointerException("filename == null"); + if (filename.length()==0) + throw new NullPointerException("filename == \"\""); + if (target==null) + throw new NullPointerException("target == null"); + if (target.length()==0) + throw new NullPointerException("target == \"\""); + + // fixme: use an java class for that + new Exec().run("rm -R "+target+" ; mkdir -p "+target); + String cmdline = "cd "+target+" && "+ar_command()+" x "+filename; + System.out.println("AR-X: executing: "+cmdline); + new Exec().run(cmdline); + } + + public void handle_static(String arname) + { + if (StrUtil.isEmpty(arname)) + return; + + String subdir = ".DIR-"+arname.replace('/','+'); + + // fixme: use our java classes for us +// rm.remove_recursive(subdir); + + // extract the .a archive + ar_x(new File(arname).getAbsolutePath(), subdir); + + /* now list all filenames in our working dir and + add them to our object list */ + File subs[] = new File(subdir).listFiles(); + for (int x=0; x