diff --git a/src/Dependency.cpp b/src/Dependency.cpp index 99ff049..00ebd79 100644 --- a/src/Dependency.cpp +++ b/src/Dependency.cpp @@ -21,41 +21,6 @@ #include "Settings.h" #include "Utils.h" -static inline std::string filePrefix(std::string in) -{ - return in.substr(0, in.rfind("/")+1); -} - -static inline std::string stripPrefix(std::string in) -{ - return in.substr(in.rfind("/")+1); -} - -static inline std::string getFrameworkRoot(std::string in) -{ - return in.substr(0, in.find(".framework")+10); -} - -static inline std::string getFrameworkPath(std::string in) -{ - return in.substr(in.rfind(".framework/")+11); -} - -// trim from end (in place) -static inline void rtrim_in_place(std::string& s) -{ - s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { - return !std::isspace(c); - }).base(), s.end()); -} - -// trim from end (copying) -static inline std::string rtrim(std::string s) -{ - rtrim_in_place(s); - return s; -} - // the paths to search for dylibs, store it globally to parse the environment variables only once std::vector paths; @@ -93,7 +58,7 @@ void initSearchPaths() // if some libs are missing prefixes, then more stuff will be necessary to do bool missing_prefixes = false; -Dependency::Dependency(std::string path) +Dependency::Dependency(std::string path) : is_framework(false) { char original_file_buffer[PATH_MAX]; std::string original_file; @@ -125,7 +90,8 @@ Dependency::Dependency(std::string path) if (!Settings::isPrefixBundled(prefix)) return; - if (path.find(".framework") != std::string::npos) { + if (getOriginalPath().find(".framework") != std::string::npos) { + is_framework = true; original_file = path; std::string framework_root = getFrameworkRoot(original_file); std::string framework_path = getFrameworkPath(original_file); @@ -172,14 +138,6 @@ Dependency::Dependency(std::string path) new_name = filename; } -void Dependency::print() -{ - std::cout << "\n * " << filename << " from " << prefix << "\n"; - - for (size_t n=0; n " << symlinks[n] << "\n";; -} - std::string Dependency::getInstallPath() { return Settings::destFolder() + new_name; @@ -208,19 +166,25 @@ bool Dependency::mergeIfSameAs(Dependency& dep2) return false; } +void Dependency::print() +{ + std::cout << "\n * " << filename << " from " << prefix << "\n"; + + for (size_t n=0; n " << symlinks[n] << "\n";; +} + void Dependency::copyYourself() { std::string original_path = getOriginalPath(); std::string dest_path = getInstallPath(); std::string inner_path = getInnerPath(); std::string install_path = dest_path; - bool framework = false; if (Settings::verboseOutput()) std::cout << "original path: " << original_path << std::endl; - if (original_path.find(".framework") != std::string::npos) { - framework = true; + if (is_framework) { std::string framework_root = getFrameworkRoot(original_path); std::string framework_path = getFrameworkPath(original_path); std::string framework_name = stripPrefix(framework_root); @@ -243,7 +207,7 @@ void Dependency::copyYourself() copyFile(original_path, dest_path); - if (framework) { + if (is_framework) { std::string headers_path = dest_path + std::string("/Headers"); std::string headers_realpath = headers_path; char buffer[PATH_MAX]; diff --git a/src/Dependency.h b/src/Dependency.h index c457787..8a9273a 100644 --- a/src/Dependency.h +++ b/src/Dependency.h @@ -8,33 +8,34 @@ class Dependency { public: Dependency(std::string path); - // void initSearchPaths(); - void print(); - std::string getOriginalFileName() const { return filename; } std::string getOriginalPath() const { return prefix + filename; } + std::string getInstallPath(); std::string getInnerPath(); + bool isFramework() { return is_framework; } + void addSymlink(std::string s); size_t symlinksCount() const { return symlinks.size(); } std::string getSymlink(int i) const { return symlinks[i]; } std::string getPrefix() const { return prefix; } - void copyYourself(); - void fixFileThatDependsOnMe(std::string file); - // Compares the given dependency with this one. If both refer to the same file, // it returns true and merges both entries into one. bool mergeIfSameAs(Dependency& dep2); + void print(); + void copyYourself(); + void fixFileThatDependsOnMe(std::string file); + private: + bool is_framework; // origin std::string filename; std::string prefix; std::vector symlinks; - // installation std::string new_name; }; diff --git a/src/DylibBundler.cpp b/src/DylibBundler.cpp index aa4a883..18f7a3e 100644 --- a/src/DylibBundler.cpp +++ b/src/DylibBundler.cpp @@ -34,11 +34,6 @@ void changeLibPathsOnFile(std::string file_to_fix) deps_in_file[n].fixFileThatDependsOnMe(file_to_fix); } -bool isRpath(const std::string& path) -{ - return path.find("@rpath") == 0 || path.find("@loader_path") == 0; -} - void collectRpaths(const std::string& filename) { if (!fileExists(filename)) { @@ -163,6 +158,9 @@ void addDependency(std::string path, std::string filename) if (!Settings::isPrefixBundled(dep.getPrefix())) return; + if (dep.isFramework()) + frameworks.insert(dep.getOriginalFileName()); + if (!in_deps) deps.push_back(dep); @@ -252,40 +250,6 @@ void collectSubDependencies() } } -void createDestDir() -{ - std::string dest_folder = Settings::destFolder(); - std::cout << "* Checking output directory " << dest_folder << "\n"; - - bool dest_exists = fileExists(dest_folder); - - if (dest_exists && Settings::canOverwriteDir()) { - std::cout << "* Erasing old output directory " << dest_folder << "\n"; - std::string command = std::string("rm -r ") + dest_folder; - if (systemp(command) != 0) { - std::cerr << "\n\n/!\\ ERROR: An error occured while attempting to overwrite dest folder\n"; - exit(1); - } - dest_exists = false; - } - - if (!dest_exists) { - if (Settings::canCreateDir()) { - std::cout << "* Creating output directory " << dest_folder << "\n\n"; - std::string command = std::string("mkdir -p ") + dest_folder; - if (systemp(command) != 0) { - std::cerr << "\n/!\\ ERROR: An error occured while creating dest folder\n"; - exit(1); - } - } - else { - std::cerr << "\n\n/!\\ ERROR: Dest folder does not exist. Create it or pass the appropriate flag for automatic dest dir creation\n"; - exit(1); - } - } - -} - void doneWithDeps_go() { const size_t deps_size = deps.size(); diff --git a/src/DylibBundler.h b/src/DylibBundler.h index a76ec63..d5f655f 100644 --- a/src/DylibBundler.h +++ b/src/DylibBundler.h @@ -3,10 +3,17 @@ #include +void changeLibPathsOnFile(std::string file_to_fix); + +void collectRpaths(const std::string& filename); +void collectRpathsForFilename(const std::string& filename); +std::string searchFilenameInRpaths(const std::string& rpath_dep); +void fixRpathsOnFile(const std::string& original_file, const std::string& file_to_fix); + +void addDependency(std::string path, std::string filename); void collectDependencies(std::string filename); void collectSubDependencies(); + void doneWithDeps_go(); -bool isRpath(const std::string& path); -std::string searchFilenameInRpaths(const std::string& rpath_dep); #endif diff --git a/src/Utils.cpp b/src/Utils.cpp index 20f8704..47dc062 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -11,81 +11,39 @@ #include "Dependency.h" #include "Settings.h" -void tokenize(const std::string& str, const char* delim, std::vector* vectorarg) +std::string filePrefix(std::string in) { - std::vector& tokens = *vectorarg; - std::string delimiters(delim); - - // skip delimiters at beginning. - std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); - // find first "non-delimiter". - std::string::size_type pos = str.find_first_of(delimiters, lastPos); - - while (pos != std::string::npos || lastPos != std::string::npos) { - // found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - // skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - // find next "non-delimiter" - pos = str.find_first_of(delimiters, lastPos); - } + return in.substr(0, in.rfind("/")+1); } -bool fileExists(std::string filename) +std::string stripPrefix(std::string in) { - if (access(filename.c_str(), F_OK) != -1) { - return true; // file exists - } - else { - std::string delims = " \f\n\r\t\v"; - std::string rtrimmed = filename.substr(0, filename.find_last_not_of(delims)+1); - std::string ftrimmed = rtrimmed.substr(rtrimmed.find_first_not_of(delims)); - if (access(ftrimmed.c_str(), F_OK) != -1) - return true; - else - return false; // file doesn't exist - } + return in.substr(in.rfind("/")+1); } -void copyFile(std::string from, std::string to) +std::string getFrameworkRoot(std::string in) { - bool overwrite = Settings::canOverwriteFiles(); - if (fileExists(to) && !overwrite) { - std::cerr << "\n\nError: File " << to << " already exists. Remove it or enable overwriting\n"; - exit(1); - } - - std::string overwrite_permission = std::string(overwrite ? "-f " : "-n "); - - // copy file to local directory - std::string command = std::string("cp -R ") + overwrite_permission + from + std::string(" ") + to; - if (from != to && systemp(command) != 0) { - std::cerr << "\n\nError: An error occured while trying to copy file " << from << " to " << to << "\n"; - exit(1); - } - - // give it write permission - std::string command2 = std::string("chmod -R +w ") + to; - if (systemp(command2) != 0) { - std::cerr << "\n\nError: An error occured while trying to set write permissions on file " << to << "\n"; - exit(1); - } + return in.substr(0, in.find(".framework")+10); } -void deleteFile(std::string path, bool overwrite) +std::string getFrameworkPath(std::string in) { - std::string overwrite_permission = std::string(overwrite ? "-f " : " "); - std::string command = std::string("rm -r ") + overwrite_permission + path; - if (systemp(command) != 0) { - std::cerr << "\n\nError: An error occured while trying to delete " << path << "\n"; - exit(1); - } + return in.substr(in.rfind(".framework/")+11); } -void deleteFile(std::string path) +// trim from end (in place) +void rtrim_in_place(std::string& s) { - bool overwrite = Settings::canOverwriteFiles(); - deleteFile(path, overwrite); + s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { + return !std::isspace(c); + }).base(), s.end()); +} + +// trim from end (copying) +std::string rtrim(std::string s) +{ + rtrim_in_place(s); + return s; } std::string systemOutput(const std::string& cmd) @@ -132,6 +90,121 @@ int systemp(const std::string& cmd) return system(cmd.c_str()); } +void tokenize(const std::string& str, const char* delim, std::vector* vectorarg) +{ + std::vector& tokens = *vectorarg; + std::string delimiters(delim); + + // skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (pos != std::string::npos || lastPos != std::string::npos) { + // found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + +bool fileExists(std::string filename) +{ + if (access(filename.c_str(), F_OK) != -1) { + return true; // file exists + } + else { + std::string delims = " \f\n\r\t\v"; + std::string rtrimmed = filename.substr(0, filename.find_last_not_of(delims)+1); + std::string ftrimmed = rtrimmed.substr(rtrimmed.find_first_not_of(delims)); + if (access(ftrimmed.c_str(), F_OK) != -1) + return true; + else + return false; // file doesn't exist + } +} + +bool isRpath(const std::string& path) +{ + return path.find("@rpath") == 0 || path.find("@loader_path") == 0; +} + +void copyFile(std::string from, std::string to) +{ + bool overwrite = Settings::canOverwriteFiles(); + if (fileExists(to) && !overwrite) { + std::cerr << "\n\nError: File " << to << " already exists. Remove it or enable overwriting\n"; + exit(1); + } + + std::string overwrite_permission = std::string(overwrite ? "-f " : "-n "); + + // copy file to local directory + std::string command = std::string("cp -R ") + overwrite_permission + from + std::string(" ") + to; + if (from != to && systemp(command) != 0) { + std::cerr << "\n\nError: An error occured while trying to copy file " << from << " to " << to << "\n"; + exit(1); + } + + // give it write permission + std::string command2 = std::string("chmod -R +w ") + to; + if (systemp(command2) != 0) { + std::cerr << "\n\nError: An error occured while trying to set write permissions on file " << to << "\n"; + exit(1); + } +} + +void deleteFile(std::string path, bool overwrite) +{ + std::string overwrite_permission = std::string(overwrite ? "-f " : " "); + std::string command = std::string("rm -r ") + overwrite_permission + path; + if (systemp(command) != 0) { + std::cerr << "\n\nError: An error occured while trying to delete " << path << "\n"; + exit(1); + } +} + +void deleteFile(std::string path) +{ + bool overwrite = Settings::canOverwriteFiles(); + deleteFile(path, overwrite); +} + +void createDestDir() +{ + std::string dest_folder = Settings::destFolder(); + std::cout << "* Checking output directory " << dest_folder << "\n"; + + bool dest_exists = fileExists(dest_folder); + + if (dest_exists && Settings::canOverwriteDir()) { + std::cout << "* Erasing old output directory " << dest_folder << "\n"; + std::string command = std::string("rm -r ") + dest_folder; + if (systemp(command) != 0) { + std::cerr << "\n\n/!\\ ERROR: An error occured while attempting to overwrite dest folder\n"; + exit(1); + } + dest_exists = false; + } + + if (!dest_exists) { + if (Settings::canCreateDir()) { + std::cout << "* Creating output directory " << dest_folder << "\n\n"; + std::string command = std::string("mkdir -p ") + dest_folder; + if (systemp(command) != 0) { + std::cerr << "\n/!\\ ERROR: An error occured while creating dest folder\n"; + exit(1); + } + } + else { + std::cerr << "\n\n/!\\ ERROR: Dest folder does not exist. Create it or pass the appropriate flag for automatic dest dir creation\n"; + exit(1); + } + } +} + std::string getUserInputDirForFile(const std::string& filename) { const size_t searchPathCount = Settings::searchPathCount(); diff --git a/src/Utils.h b/src/Utils.h index 4c2d35e..75da119 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -6,18 +6,31 @@ // class Library; +std::string filePrefix(std::string in); +std::string stripPrefix(std::string in); + +std::string getFrameworkRoot(std::string in); +std::string getFrameworkPath(std::string in); + +// trim from end (in place) +void rtrim_in_place(std::string& s); +// trim from end (copying) +std::string rtrim(std::string s); + +// executes a command in the native shell and returns output in string +std::string systemOutput(const std::string& cmd); +// like 'system', runs a command on the system shell, but also prints the command to stdout. +int systemp(const std::string& cmd); + void tokenize(const std::string& str, const char* delimiters, std::vector*); bool fileExists(std::string filename); +bool isRpath(const std::string& path); void copyFile(std::string from, std::string to); void deleteFile(std::string path, bool overwrite); void deleteFile(std::string path); -// executes a command in the native shell and returns output in string -std::string systemOutput(const std::string& cmd); - -// like 'system', runs a command on the system shell, but also prints the command to stdout. -int systemp(const std::string& cmd); +void createDestDir(); std::string getUserInputDirForFile(const std::string& filename); #endif