From 93746d19b9052c130b4721ff3edc000a1b42540d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Tue, 24 Mar 2020 22:00:24 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@977 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- utils/deploy_tool/main.cpp | 226 ++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 89 deletions(-) diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index bd5df2dd..90a4d90d 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -30,10 +30,17 @@ void usage() { piCout << Cyan << "Version PIP" << Bold << PIPVersion(); piCout << ""; piCout << "Copy all dependencies of to directory "; - piCout << "If depend on QtCore library, then copy all basic Qt plugins, "; + piCout << "You can specify any file or directory as ."; + piCout << "In case of directory it will be scan recursively."; + piCout << ""; + piCout << "If QtCore dependency found, copy all basic Qt plugins,"; piCout << " and "; piCout << ""; - piCout << Green << Bold << "Usage:" << Default << "\"deploy_tool [-hvfC] [--dependencies [--prefix ]] [-p ] [-s ] [-S ] [-l ] [-D ] [-L | -W | -M ] [-d ] [-q ] [-a ] [-S ] [-P ] -o [ ...]\"" << NewLine; + piCout << Green << Bold << "Usage:" << Default << "\"deploy_tool [-hvfC] [--dependencies [--prefix ]] " + "[-p ] [-s ] [-S ] [-l ] " + "[-D ] [-L | -W | -M ] " + "[-d ] [-q ] [-a ] [-S ] " + "[-P ] [--sql ] -o [ ...]\"" << NewLine; piCout << Green << Bold << "Details:"; piCout << Bold << "Debug control"; piCout << "-h " << Green << "- display this message and exit"; @@ -47,7 +54,7 @@ void usage() { piCout << "-W " << Green << "- \"objdump\" path, overrides \"ldd\""; piCout << "-M " << Green << "- \"otool\" path, overrides \"ldd\""; piCout << "-D " << Green << "- \"dpkg\" path, default \"/usr/bin/dpkg\""; - piCout << "-d " << Green << "- dependepcies depth, default 1"; + piCout << "-d " << Green << "- maximum dependepcies depth, default 5"; piCout << "-q " << Green << "- path where Qt root dir, default takes from \"qmake -v\""; piCout << "-C, --Conf " << Green << "- make \"qt.conf\""; //piCout << "-Q, --Qt-force " << Green << "- force add Qt root dir, default takes from \"qmake -v\""; @@ -60,17 +67,39 @@ void usage() { piCout << ""; piCout << Bold << "Input control"; piCout << " ... " << Green << "- executable to process"; - piCout << "-S " << Green << "- add Qt styles (e.g. \"oxygen,breeze\"), default \"\""; - piCout << "-P " << Green << "- add Qt platforms (e.g. \"win,mini\"), default by host system"; - piCout << "-a " << Green << "- additional libs, separated by \";\""; + piCout << "-S " << Green << "- set Qt styles (e.g. \"oxygen,breeze\"), default \"*\""; + piCout << "-P " << Green << "- set Qt platforms (e.g. \"win,mini\"), default by host system"; + piCout << "--sql " << Green << "- set Qt sql drivers (e.g. \"sqlite\"), default \"*\""; + piCout << "-a " << Green << "- additional libs, separated by \";\". Libraries will be searched in "; } +struct QtDep { + QtDep(const PIString & l = PIString(), const PIStringList & p = PIStringList()): lib(l), plugins(p) {} + PIString lib; + PIStringList plugins; +}; +QtDep qt_deps[] = { + QtDep("core" , PIStringList() << "platforms"), + QtDep("gui" , PIStringList() << "imageformats"), + QtDep("widgets" , PIStringList() << "styles"), + QtDep("sql" , PIStringList() << "sqldrivers"), + QtDep("positioning" , PIStringList() << "position"), + QtDep("location" , PIStringList() << "geoservices"), + QtDep("multimedia" , PIStringList() << "audio" << "mediaservice" << "playlistformats"), + QtDep("printsupport" , PIStringList() << "printsupport"), + QtDep("virtualkeyboard", PIStringList() << "platforminputcontexts"), + QtDep("sensors" , PIStringList() << "sensors" << "sensorgestures"), + QtDep("texttospeech" , PIStringList() << "texttospeech"), + QtDep("serialbus" , PIStringList() << "canbus"), + QtDep() +}; -int depth = 1; -bool need_qt = false, fake = false, is_ldd = true, is_deps = false; + +int depth = 5; +bool fake = false, is_ldd = true, is_deps = false, need_qt = false; PIString ldd, readelf, objdump, otool, dpkg, out_dir, qt_dir, out_plugins_dir; -PIStringList styles, lib_dirs, add_libs, platforms; -PISet all_libs, miss_libs, all_deps, frameworks, miss_frameworks; +PIStringList styles, lib_dirs, add_libs, platforms, sqldrivers; +PISet all_libs, miss_libs, all_deps, frameworks, miss_frameworks, qt_plugins; PIString findLib(const PIString & l) { @@ -84,6 +113,42 @@ PIString findLib(const PIString & l) { } +PIString execute(const PIString & cmd) { + FILE * fp = popen(cmd.dataAscii(), "r"); + PIString ret; + if (fp) { + const int sz = 256; + char in[sz]; + memset(in, 0, sz); + while (true) { + int r = fread(in, 1, sz, fp); + if (r <= 0) break; + ret += PIString(in, r); + } + pclose(fp); + } + return ret; +} + + +void checkQtLib(PIString lib) { + if (lib.startsWith("lib")) lib.cutLeft(3); + if (lib.startsWith("qt5")) lib.cutLeft(3); + if (lib.startsWith("qt")) lib.cutLeft(2); + if (lib.find(".")) lib = lib.left(lib.find(".")); + //piCout << "checkQt" << lib; + for (int i = 0; ; ++i) { + if (qt_deps[i].lib.isEmpty()) break; + if (qt_deps[i].lib == lib) { + qt_plugins << qt_deps[i].plugins; + //piCout << "add qt plugins" << qt_deps[i].plugins << "now" << qt_plugins; + need_qt = true; + break; + } + } +} + + void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { ++cur_depth; if (cur_depth > depth) return; @@ -97,11 +162,7 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { } PIStringList lines; if (is_ldd) { - PIProcess proc; - proc.setGrabOutput(true); - proc.exec(ldd, file); - proc.waitForFinish(5000); - lines = PIString(proc.readOutput()).split("\n"); + lines = execute(ldd + " " + file).split("\n"); } else { PIString cmd; if (!readelf.isEmpty()) { @@ -117,20 +178,7 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { cmd += " | grep -o \".*(\""; } //piCout << cmd; - FILE * fp = popen(cmd.dataAscii(), "r"); - PIString vs; - if (fp) { - const int sz = 256; - char in[sz]; - memset(in, 0, sz); - while (true) { - int r = fread(in, 1, sz, fp); - if (r <= 0) break; - vs += PIString(in, r); - } - pclose(fp); - } - lines = vs.split("\n"); + lines = execute(cmd).split("\n"); if (!objdump.isEmpty()) { piForeach (PIString & l, lines) { l.trim().cutLeft(9).trim(); @@ -157,8 +205,7 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { } } frameworks << l; - if (l.contains("QtCore") || l.contains("Qt5Core")) - need_qt = true; + checkQtLib(l.toLowerCase()); continue; } } @@ -173,7 +220,7 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { continue; } } else { - l.cutLeft(1).cutRight(1); + l.cutLeft(1).cutRight(1).trim(); if (l.isEmpty()) continue; if (!otool.isEmpty()) { PIFile::FileInfo fi; @@ -182,25 +229,24 @@ void procLdd(PIString file, bool ext_lib = false, int cur_depth = 0) { } PIString flp = findLib(l); if (flp.isEmpty()) { - piCout << "Can`t find" << l; + //piCout << "Can`t find" << l; + miss_libs << l; continue; } l = flp; } if (all_libs[l]) continue; - if (!need_qt) { - PIFile::FileInfo fi; - fi.path = l; - PIString ln = fi.name(); - if (ln.contains("QtCore") || ln.contains("Qt5Core")) - need_qt = true; - } + PIFile::FileInfo fi; + fi.path = l; + checkQtLib(fi.name().toLowerCase()); cur_libs << l; all_libs << l; } PIVector clibs = cur_libs.toVector(); + if (!clibs.isEmpty()) + piCout << " new dependencies:\n -" << PIStringList(clibs).join("\n - "); piForeachC (PIString & l, clibs) { - procLdd(l, cur_depth); + procLdd(l, false, cur_depth); } } @@ -221,14 +267,7 @@ void procQt() { //piCout << "qmake ..."; PIString vs; if (qt_dir.isEmpty()) { - FILE * fp = popen("qmake -v", "r"); - if (fp) { - char in[1024]; - memset(in, 0, 1024); - if (fread(in, 1, 1024, fp)) - vs = in; - pclose(fp); - } + vs = execute("qmake -v"); if (vs.isEmpty()) { piCout << "Can`t exec \"qmake -v\"!"; return; @@ -236,8 +275,7 @@ void procQt() { } else vs = "QMake version ?.?\nUsing Qt version ?.?.? in " + qt_dir; PIStringList vsl = vs.split("\n"); - PIStringList pdirs; - pdirs << "imageformats" << "sqldrivers"; + PIStringList pdirs = qt_plugins.toVector(); if (!fake && !is_deps) PIDir(out_plugins_dir).make(true); piForeach (PIString l, vsl) { @@ -259,42 +297,29 @@ void procQt() { else qdir += "/plugins/"; #endif - piForeachC (PIString & p, pdirs) { - copyWildcard(qdir + p + "/*", out_plugins_dir + p); + piForeachC (PIString & plugin, pdirs) { + PIStringList filters("*"); + if (plugin == "platforms") filters = platforms; + if (plugin == "styles") filters = styles; + if (plugin == "sqldrivers") filters = sqldrivers; + piForeachC (PIString & f, filters) { + copyWildcard(qdir + plugin + "/" + f, out_plugins_dir + plugin); + PIVector copied = PIDir(out_plugins_dir + plugin).entries(); + piForeachC (PIFile::FileInfo & fi, copied) { + if (fi.isFile()) + procLdd(fi.path); + } + } } - piForeachC (PIString & s, platforms) { - copyWildcard(qdir + "platforms/*" + s + "*", out_plugins_dir + "platforms"); - } - piForeachC (PIString & s, styles) { - copyWildcard(qdir + "styles/*" + s + "*", out_plugins_dir + "styles"); - } - } - } - pdirs << "platforms" << "styles"; - piForeachC (PIString & p, pdirs) { - PIVector fil = PIDir(out_plugins_dir + p).entries(); - piForeachC (PIFile::FileInfo & f, fil) { - if (f.isFile()) - procLdd(f.path); + piBreak; } } } bool procDpkg(const PIString & l) { - PIString vs, cmd = dpkg + " -S " + l + " 2> /dev/null"; - FILE * fp = popen(cmd.dataAscii(), "r"); - if (fp) { - const int sz = 256; - char in[sz]; - memset(in, 0, sz); - while (true) { - int r = fread(in, 1, sz, fp); - if (r <= 0) break; - vs += PIString(in, r); - } - pclose(fp); - } + PIString cmd = dpkg + " -S " + l + " 2> /dev/null"; + PIString vs = execute(cmd); if (!vs.isEmpty()) { vs = vs.left(vs.find(":")); if (!vs.isEmpty()) @@ -321,6 +346,7 @@ int main(int argc, char * argv[]) { cli.addArgument("search_path", true); cli.addArgument("Styles", true); cli.addArgument("Platforms", true); + cli.addArgument("sql", PIChar('\0'), true); cli.addArgument("ldd", true); cli.addArgument("Lreadelf", true); cli.addArgument("Wobjdump", true); @@ -329,7 +355,7 @@ int main(int argc, char * argv[]) { cli.addArgument("depth", true); cli.addArgument("qtdir", true); cli.addArgument("add_libs", true); - if (cli.hasArgument("help") || cli.argumentValue("output").isEmpty() || (cli.optionalArguments().size_s() < 1)) { + if (cli.hasArgument("help") || cli.argumentValue("output").isEmpty() || cli.optionalArguments().isEmpty()) { usage(); return 0; } @@ -338,7 +364,6 @@ int main(int argc, char * argv[]) { fake = cli.hasArgument("fake"); piDebug = cli.hasArgument("verbose"); is_deps = cli.hasArgument("dependencies"); - PIString bin = cli.optionalArguments()[0]; out_dir = cli.argumentValue("output"); lib_dirs = cli.argumentValue("search_path").split(";"); add_libs = cli.argumentValue("add_libs").split(";"); @@ -350,7 +375,8 @@ int main(int argc, char * argv[]) { dpkg = cli.argumentValue("Dpkg"); if (dpkg.isEmpty()) dpkg = "/usr/bin/dpkg"; - out_plugins_dir = out_dir + "plugins/"; + out_plugins_dir = out_dir; + if (!out_plugins_dir.endsWith("/")) out_plugins_dir.append('/'); if (!cli.argumentValue("pqt_out_plugins").isEmpty()) { out_plugins_dir = cli.argumentValue("pqt_out_plugins"); if (!out_plugins_dir.endsWith("/")) @@ -365,23 +391,45 @@ int main(int argc, char * argv[]) { return 1; } if (etcnt > 0) is_ldd = false; - if (!cli.argumentValue("Platforms").isEmpty()) - qplatforms = cli.argumentValue("Platforms"); - platforms = qplatforms.split(","); piForeach (PIString & s, lib_dirs) { if (!s.endsWith("/")) s += "/"; } if (out_dir.isEmpty()) out_dir = "."; if (!out_dir.endsWith("/")) out_dir += "/"; if (ldd.isEmpty()) ldd = "/usr/bin/ldd"; + + if (!cli.argumentValue("Platforms").isEmpty()) + qplatforms = cli.argumentValue("Platforms"); + platforms = qplatforms.split(","); styles = cli.argumentValue("Styles").split(","); + if (styles.isEmpty()) styles << ""; + sqldrivers = cli.argumentValue("sql").split(","); + if (sqldrivers.isEmpty()) sqldrivers << ""; + + platforms .forEachInplace([](PIString i)->PIString{if (!i.startsWith("*")) i.prepend("*"); if (!i.endsWith("*")) i.append("*"); return i;}); + styles .forEachInplace([](PIString i)->PIString{if (!i.startsWith("*")) i.prepend("*"); if (!i.endsWith("*")) i.append("*"); return i;}); + sqldrivers.forEachInplace([](PIString i)->PIString{if (!i.startsWith("*")) i.prepend("*"); if (!i.endsWith("*")) i.append("*"); return i;}); + if (!fake) PIDir(out_dir).make(); if (!cli.argumentValue("depth").isEmpty()) depth = cli.argumentValue("depth").toInt(); + PIStringList files; + cli.optionalArguments().forEach([&](const PIString & a){ + if (PIDir::isExists(a)) { + PIDir(a).allEntries().forEach([&](const PIFile::FileInfo & fi){ + if (fi.isFile()) + files << fi.path; + }); + } else { + if (PIFile::isExists(a)) + files << a; + } + }); + //piCout << files; if (depth > 0) - procLdd(bin); + files.forEach([&](const PIString & f){procLdd(f);}); piForeach (PIString & s, add_libs) { if (s.isEmpty()) continue; piCout << s << "->" << findLib(s); @@ -424,9 +472,9 @@ int main(int argc, char * argv[]) { } else { piCout << "copied" << clibs.size_s() << "files"; if (!miss_libs.isEmpty()) - piCout << "Missing libraries:\n - " << PIStringList(miss_libs.toVector()).join("\n - "); + piCout << "Missing libraries:\n -" << PIStringList(miss_libs.toVector()).join("\n - "); if (!miss_frameworks.isEmpty()) - piCout << "Missing frameworks:\n - " << PIStringList(miss_frameworks.toVector()).join("\n - "); + piCout << "Missing frameworks:\n -" << PIStringList(miss_frameworks.toVector()).join("\n - "); } return 0;