diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index bdcecf83..b323f277 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -66,7 +66,7 @@ void usage() { piCout << Green << Bold << "Usage:" << Default << "\"deploy_tool [-hvfC] [--dependencies [--prefix ]] " "[--qt-plugins-dir ] [-s ] [--ignore ] [-S ] " "[-l ] [-D ] [--dpkg-workdir ] [-L | -W | -M ] " - "[--name-tool ] [--rpath ] [-d ] [-q ] [-a ] [-S ] " + "[--name-tool ] [--rpath] [-d ] [-q ] [-a ] [-S ] " "[-P ] [--qt-plugins ] [--qt-modules ] [--qt-conf-dir ] -o [ ...]\"" << NewLine; piCout << Green << Bold << "Details:"; piCout << Bold << "Debug control"; @@ -85,7 +85,7 @@ void usage() { piCout << "--dpkg-workdir " << Green << "- dpkg \"admindir\" path, default \"\""; piCout << "--name-tool " << Green << "- \"install_name_tool\" path, default \"install_name_tool\""; piCout << "--strip " << Green << "- \"strip\" path, default \"strip\""; - piCout << "--rpath " << Green << "- set rpath for input files to \"rpath\" using \"patchelf\" if non-empty"; + piCout << "--rpath " << Green << "- set rpath for copied files using \"patchelf\""; piCout << "-d " << Green << "- maximum dependepcies depth, default 8"; piCout << ""; piCout << Bold << "Qt control"; @@ -130,9 +130,9 @@ QtDep qt_deps[] = { int depth = 8; -bool fake = false, is_ldd = true, is_deps = false, need_qt = false, make_qt_format = true; +bool fake = false, is_ldd = true, is_deps = false, need_qt = false, make_qt_format = true, rpath = false; PIString ldd, readelf, objdump, otool, dpkg, nametool, strip, out_dir, qt_dir, dpkg_workdir; -PIString qt_pref, qt_suff, qt_conf_dir, qt_plugins_dir, rpath; +PIString qt_pref, qt_suff, qt_conf_dir, qt_plugins_dir, target_dir; PIStringList styles, lib_dirs, add_libs, platforms, sqldrivers, input_files, plugin_libs, qt_add_libs; PISet all_libs, miss_libs, all_deps, frameworks, framework_libs, miss_frameworks, qt_plugins, ignore_libs, qt_libs; PIMap qt_filters; @@ -490,20 +490,32 @@ void patchNameTool() { } -void patchRPath(const PIString & file, bool eval) { - PIString rp = rpath; - if (eval) { - PIFile::FileInfo fi(file); - rp = PIDir(fi.dir()).relative(out_dir); - if (rp.isEmpty()) rp = "."; - rp.prepend("\\$ORIGIN/"); - } - PIString cmd = "patchelf --set-rpath \"" + rp + "\" \"" + file + "\""; - piCout << "set rpath" << file << "to" << rp; +void patchRPathFile(const PIFile::FileInfo & file) { + PIString fo = execute("file \"" + file.path + "\""); + if (!fo.contains("ELF") || !fo.contains("executable")) return; + PIString rp = "\\$ORIGIN:\\$ORIGIN/lib"; + PIString arp = PIDir(file.dir()).relative(out_dir); + if (!arp.isEmpty() && arp != "." && arp != "lib") + rp.append(":\\$ORIGIN/" + arp); + PIString cmd = "patchelf --set-rpath \"" + rp + "\" \"" + file.path + "\" 2> /dev/null"; + piCout << "set rpath" << file.path << "to" << rp; execute(cmd); } +void patchRPath() { + PIStringList dirs({out_dir, target_dir, qt_plugins_dir}); + dirs.removeDuplicates().removeStrings(PIString()); + piForeachC (PIString & d, dirs) { + PIVector files = PIDir(d).allEntries(); + piForeachC (PIFile::FileInfo & f, files) { + if (f.isDir()) continue; + patchRPathFile(f.path); + } + } +} + + int main(int argc, char * argv[]) { PICLI cli(argc, argv); //piCout << cli.rawArguments(); @@ -528,7 +540,7 @@ int main(int argc, char * argv[]) { cli.addArgument("Wobjdump", true); cli.addArgument("Motool", true); cli.addArgument("name-tool", PIChar('\0'), true); - cli.addArgument("rpath", PIChar('\0'), true); + cli.addArgument("rpath", PIChar('\0')); cli.addArgument("strip", PIChar('\0'), true); cli.addArgument("Dpkg", true); cli.addArgument("dpkg-workdir", PIChar('\0'), true); @@ -555,7 +567,7 @@ int main(int argc, char * argv[]) { otool = cli.argumentValue("Motool"); nametool = cli.argumentValue("name-tool"); strip = cli.argumentValue("strip"); - rpath = cli.argumentValue("rpath"); + rpath = cli.hasArgument("rpath"); if (nametool.isEmpty()) nametool = "install_name_tool"; if (strip.isEmpty()) @@ -650,22 +662,20 @@ int main(int argc, char * argv[]) { cli.optionalArguments().forEach([&](const PIString & a){ if (PIDir::isExists(a)) { + if (target_dir.isEmpty()) + target_dir = a; PIDir(a).allEntries().forEach([&](const PIFile::FileInfo & fi){ if (fi.isFile()) input_files << fi.path; }); } else { + if (target_dir.isEmpty()) + target_dir = PIFile::FileInfo(a).dir(); if (PIFile::isExists(a)) input_files << a; } }); - if (!rpath.isEmpty()) { - input_files.forEach([&](const PIString & f){ - patchRPath(f, false); - }); - } - //piCout << files; if (depth > 0) { input_files.forEach([&](const PIString & f){procLdd(f);}); @@ -713,12 +723,6 @@ int main(int argc, char * argv[]) { } } - if (!rpath.isEmpty()) { - plugin_libs.forEach([&](const PIString & f){ - patchRPath(f, true); - }); - } - #ifdef WINDOWS out_dir.replaceAll("/", "\\"); #endif @@ -757,6 +761,9 @@ int main(int argc, char * argv[]) { if (!otool.isEmpty()) patchNameTool(); + if (rpath) + patchRPath(); + if (is_deps) { PICout(PICoutManipulators::AddNone) << cli.argumentValue("prefix"); PICout(PICoutManipulators::AddNewLine) << PIStringList(all_deps.toVector()).join(", ");