#include "pack.h" #include #include #include namespace fs = boost::filesystem; bool CPackBinary::startPack(const CmdResult& result) { result_ = result; auto dpends = getDepends(result_.binary, result.lib_dirs); auto should_copy = parseResult(dpends); return handleAndCopy(should_copy, result_.purpose_dir); } std::vector CPackBinary::getDepends(const std::string& path, const std::vector& dirs) { std::vector result; std::string cmds; cmds.append("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH"); for (const auto& item : dirs) { cmds.append(":" + item); } cmds.append(" && ldd " + path); auto* pf = popen(cmds.c_str(), "r"); if (pf == nullptr) { return result; } char buffer[1024]{}; std::string output{}; while (std::fgets(buffer, sizeof(buffer), pf)) { output.append(buffer); } fclose(pf); std::vector split; boost::split(split, output, boost::is_any_of("\t")); for (const auto& item : split) { result.push_back(item); } return result; } std::list CPackBinary::parseResult(const std::vector& result) { std::list ret; auto backup = result; for (auto& item : backup) { if (item.empty()) { continue; } if (boost::contains(item, "not found")) { std::cout << "未找到依赖:" << item << std::endl; continue; } boost::replace_all(item, "=>", ""); std::vector split; boost::split(split, item, boost::is_any_of(" ")); std::string h; if (split.size() == 4) { h = split[2]; } if (split.size() == 3) { h = split[1]; } if (boost::starts_with(h, "/lib")) { continue; } if (!h.empty()) { ret.push_back(h); std::cout << "依赖:" << h << std::endl; } } ret.push_back(result_.binary); return ret; } bool CPackBinary::handleAndCopy(const std::list& libs, const std::string& des) { auto filename = fs::path(result_.binary).filename().string(); auto dest_directory = fs::path(des).append(filename); try { fs::create_directories(dest_directory); for (const auto& item : libs) { auto item_name = fs::path(item).filename().string(); auto newpath = fs::path(dest_directory).append(item_name); fs::copy_file(item, newpath, fs::copy_options::overwrite_existing); } return true; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; return false; } }