only parallelize for loops in doneWithDeps_go. reformat entire project

This commit is contained in:
SCG82 2019-12-12 08:46:03 -08:00
parent 6625f27f0e
commit 2b2b669a2c
10 changed files with 214 additions and 600 deletions

View File

@ -1,27 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <algorithm>
#include <functional>
#include <cctype>
@ -34,7 +10,6 @@ THE SOFTWARE.
#include "Utils.h"
#include "Settings.h"
#include "DylibBundler.h"
#include "ParallelFor.h"
#include <stdlib.h>
#include <sstream>
@ -72,25 +47,21 @@ void initSearchPaths()
if (dyldLibPath != 0)
searchPaths = dyldLibPath;
dyldLibPath = std::getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
if (dyldLibPath != 0)
{
if (dyldLibPath != 0) {
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
searchPaths += ":";
searchPaths += dyldLibPath;
}
dyldLibPath = std::getenv("DYLD_FALLBACK_LIBRARY_PATH");
if (dyldLibPath != 0)
{
if (dyldLibPath != 0) {
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
searchPaths += ":";
searchPaths += dyldLibPath;
}
if (!searchPaths.empty())
{
if (!searchPaths.empty()) {
std::stringstream ss(searchPaths);
std::string item;
while (std::getline(ss, item, ':'))
{
while (std::getline(ss, item, ':')) {
if (item[item.size()-1] != '/')
item += "/";
paths.push_back(item);
@ -124,8 +95,7 @@ Dependency::Dependency(std::string path)
prefix = original_file.substr(0, original_file.rfind("/")+1);
addSymlink(path);
}
else
{
else {
filename = stripPrefix(path);
prefix = path.substr(0, path.rfind("/")+1);
}
@ -133,17 +103,14 @@ Dependency::Dependency(std::string path)
//check if the lib is in a known location
if (!prefix.empty() && prefix[prefix.size()-1] != '/')
prefix += "/";
if (prefix.empty() || !fileExists(prefix+filename))
{
if (prefix.empty() || !fileExists(prefix+filename)) {
//the paths contains at least /usr/lib so if it is empty we have not initialized it
if (paths.empty())
initSearchPaths();
//check if file is contained in one of the paths
for (size_t i=0; i<paths.size(); ++i)
{
if (fileExists(paths[i]+filename))
{
for (size_t i=0; i<paths.size(); ++i) {
if (fileExists(paths[i]+filename)) {
std::cout << "FOUND " << filename << " in " << paths[i] << std::endl;
prefix = paths[i];
missing_prefixes = true; //the prefix was missing
@ -153,8 +120,7 @@ Dependency::Dependency(std::string path)
}
//If the location is still unknown, ask the user for search path
if (!Settings::isPrefixIgnored(prefix) && (prefix.empty() || !fileExists(prefix+filename)))
{
if (!Settings::isPrefixIgnored(prefix) && (prefix.empty() || !fileExists(prefix+filename))) {
std::cerr << "\n/!\\ WARNING : Library " << filename << " has an incomplete name (location unknown)" << std::endl;
missing_prefixes = true;
@ -196,8 +162,7 @@ void Dependency::addSymlink(std::string s)
// it returns true and merges both entries into one.
bool Dependency::mergeIfSameAs(Dependency& dep2)
{
if (dep2.getOriginalFileName().compare(filename) == 0)
{
if (dep2.getOriginalFileName().compare(filename) == 0) {
const int samount = getSymlinkAmount();
for (int n=0; n<samount; n++)
dep2.addSymlink(getSymlink(n));
@ -212,8 +177,7 @@ void Dependency::copyYourself()
// Fix the lib's inner name
std::string command = std::string("install_name_tool -id ") + getInnerPath() + " " + getInstallPath();
if (systemp(command) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to change identity of library " << getInstallPath() << std::endl;
exit(1);
}
@ -223,46 +187,38 @@ void Dependency::fixFileThatDependsOnMe(std::string file_to_fix)
{
// for main lib file
std::string command = std::string("install_name_tool -change ") + getOriginalPath() + " " + getInnerPath() + " " + file_to_fix;
if (systemp(command) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
// for symlinks
const int symamount = symlinks.size();
for(int n=0; n<symamount; n++)
{
for(int n=0; n<symamount; n++) {
command = std::string("install_name_tool -change ") + symlinks[n] + " " + getInnerPath() + " " + file_to_fix;
if(systemp(command) != 0)
{
if(systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
}
// FIXME - hackish
if (missing_prefixes)
{
if (missing_prefixes) {
// for main lib file
command = std::string("install_name_tool -change ") + filename + " " + getInnerPath() + " " + file_to_fix;
if (systemp(command) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
// for symlinks
const int symamount = symlinks.size();
for(int n=0; n<symamount; n++)
{
for(int n=0; n<symamount; n++) {
command = std::string("install_name_tool -change ") + symlinks[n] + " " + getInnerPath() + " " + file_to_fix;
if (systemp(command) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
}//next
}// end if(missing_prefixes)
}
}
}

View File

@ -1,41 +1,15 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _depend_h_
#define _depend_h_
#include <string>
#include <vector>
class Dependency
{
class Dependency {
// origin
std::string filename;
std::string prefix;
std::vector<std::string> symlinks;
// installation
std::string new_name;
public:
@ -47,7 +21,7 @@ public:
std::string getOriginalPath() const{ return prefix+filename; }
std::string getInstallPath();
std::string getInnerPath();
void addSymlink(std::string s);
int getSymlinkAmount() const{ return symlinks.size(); }
@ -56,11 +30,10 @@ public:
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);
};
#endif
#endif

View File

@ -1,27 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "DylibBundler.h"
#include <iostream>
#include <cstdio>
@ -36,7 +12,6 @@ THE SOFTWARE.
#include "Dependency.h"
#include "ParallelFor.h"
std::vector<Dependency> deps;
std::set<std::string> rpaths;
std::map<std::string, std::vector<std::string> > rpaths_per_file;
@ -46,15 +21,9 @@ void changeLibPathsOnFile(std::string file_to_fix)
std::cout << "\n* Fixing dependencies on " << file_to_fix.c_str() << std::endl;
const int dep_amount = deps.size();
std::cout << "changeLibPaths: # of deps: " << dep_amount << std::endl;
parallel_for(dep_amount, [&](int start, int end)
{
for(int i=start; i<end; ++i)
{
deps[i].fixFileThatDependsOnMe(file_to_fix);
}
});
for (int n=0; n<dep_amount; n++) {
deps[n].fixFileThatDependsOnMe(file_to_fix);
}
}
bool isRpath(const std::string& path)
@ -64,8 +33,7 @@ bool isRpath(const std::string& path)
void collectRpaths(const std::string& filename)
{
if (!fileExists(filename))
{
if (!fileExists(filename)) {
std::cerr << "\n/!\\ WARNING : can't collect rpaths for nonexistent file '" << filename << "'\n";
return;
}
@ -78,17 +46,14 @@ void collectRpaths(const std::string& filename)
size_t pos = 0;
bool read_rpath = false;
while (pos < lc_lines.size())
{
while (pos < lc_lines.size()) {
std::string line = lc_lines[pos];
pos++;
if (read_rpath)
{
if (read_rpath) {
size_t start_pos = line.find("path ");
size_t end_pos = line.find(" (");
if (start_pos == std::string::npos || end_pos == std::string::npos)
{
if (start_pos == std::string::npos || end_pos == std::string::npos) {
std::cerr << "\n/!\\ WARNING: Unexpected LC_RPATH format\n";
continue;
}
@ -100,8 +65,7 @@ void collectRpaths(const std::string& filename)
continue;
}
if (line.find("LC_RPATH") != std::string::npos)
{
if (line.find("LC_RPATH") != std::string::npos) {
read_rpath = true;
pos++;
}
@ -110,8 +74,7 @@ void collectRpaths(const std::string& filename)
void collectRpathsForFilename(const std::string& filename)
{
if (rpaths_per_file.find(filename) == rpaths_per_file.end())
{
if (rpaths_per_file.find(filename) == rpaths_per_file.end()) {
collectRpaths(filename);
}
}
@ -122,23 +85,19 @@ std::string searchFilenameInRpaths(const std::string& rpath_file)
std::string fullpath;
std::string suffix = rpath_file.substr(7, rpath_file.size()-6);
for (std::set<std::string>::iterator it = rpaths.begin(); it != rpaths.end(); ++it)
{
for (std::set<std::string>::iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
std::string path = *it + "/" + suffix;
if (realpath(path.c_str(), buffer))
{
if (realpath(path.c_str(), buffer)) {
fullpath = buffer;
break;
}
}
if (fullpath.empty())
{
if (fullpath.empty()) {
std::cerr << "\n/!\\ WARNING : can't get path for '" << rpath_file << "'\n";
fullpath = getUserInputDirForFile(suffix) + suffix;
if (realpath(fullpath.c_str(), buffer)) {
if (realpath(fullpath.c_str(), buffer))
fullpath = buffer;
}
}
return fullpath;
@ -149,27 +108,19 @@ void fixRpathsOnFile(const std::string& original_file, const std::string& file_t
std::vector<std::string> rpaths_to_fix;
std::map<std::string, std::vector<std::string> >::iterator found = rpaths_per_file.find(original_file);
if (found != rpaths_per_file.end())
{
rpaths_to_fix = found->second;
}
int start = 0;
int end = rpaths_to_fix.size();
std::cout << "# of rpaths to fix: " << rpaths_to_fix.size() << std::endl;
// parallel_for(rpaths_to_fix.size(), [&](int start, int end)
// {
for(int i=start; i<end; ++i)
{
std::string command = std::string("install_name_tool -rpath ") +
rpaths_to_fix[i] + " " + Settings::inside_lib_path() + " " + file_to_fix;
if (systemp(command) != 0)
{
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
for (size_t i=0; i < rpaths_to_fix.size(); ++i) {
std::string command =
std::string("install_name_tool -rpath ")
+ rpaths_to_fix[i] + " "
+ Settings::inside_lib_path() + " "
+ file_to_fix;
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
exit(1);
}
// });
}
}
void addDependency(std::string path)
@ -178,31 +129,30 @@ void addDependency(std::string path)
// we need to check if this library was already added to avoid duplicates
const int dep_amount = deps.size();
for(int n=0; n<dep_amount; n++)
{
if(dep.mergeIfSameAs(deps[n])) return;
}
for (int n=0; n<dep_amount; n++)
if (dep.mergeIfSameAs(deps[n]))
return;
if(!Settings::isPrefixBundled(dep.getPrefix())) return;
if (!Settings::isPrefixBundled(dep.getPrefix()))
return;
deps.push_back(dep);
}
/**
* Fill vector 'lines' with dependencies of given 'filename'
*/
// Fill vector 'lines' with dependencies of given 'filename'
void collectDependencies(std::string filename, std::vector<std::string>& lines)
{
// execute "otool -L" on the given file and collect the command's output
std::string cmd = "otool -L " + filename;
std::string output = system_get_output(cmd);
if(output.find("can't open file")!=std::string::npos or output.find("No such file")!=std::string::npos or output.size()<1)
if (output.find("can't open file") != std::string::npos
|| output.find("No such file") != std::string::npos
|| output.size() < 1)
{
std::cerr << "Cannot find file " << filename << " to read its dependencies" << std::endl;
exit(1);
}
// split output
tokenize(output, "\n", &lines);
}
@ -216,81 +166,53 @@ void collectDependencies(std::string filename)
std::cout << "."; fflush(stdout);
const int line_amount = lines.size();
int start = 0;
int end = line_amount;
std::cout << "collectDeps: # of lines: " << line_amount << std::endl;
// parallel_for(line_amount, [&](int start, int end)
// {
for(int i=start; i<end; ++i)
{
std::cout << "."; fflush(stdout);
if(lines[i][0] != '\t')
continue; // only lines beginning with a tab interest us
if(lines[i].find(".framework") != std::string::npos)
continue; //Ignore frameworks, we cannot handle them
// trim useless info, keep only library name
std::string dep_path = lines[i].substr(1, lines[i].rfind(" (") - 1);
if(isRpath(dep_path))
collectRpathsForFilename(filename);
addDependency(dep_path);
}
// pthread_exit(NULL);
// });
for (int n=0; n<line_amount; n++) {
std::cout << "."; fflush(stdout);
if (lines[n][0] != '\t')
continue; // only lines beginning with a tab interest us
if (lines[n].find(".framework") != std::string::npos)
continue; //Ignore frameworks, we cannot handle them
// trim useless info, keep only library name
std::string dep_path = lines[n].substr(1, lines[n].rfind(" (") - 1);
if (isRpath(dep_path))
collectRpathsForFilename(filename);
addDependency(dep_path);
}
}
void collectSubDependencies()
{
// print status to user
int dep_amount = deps.size();
// recursively collect each dependency's dependencies
while(true)
{
while (true) {
dep_amount = deps.size();
int start = 0;
int end = deps.size();
std::cout << "collectSubDeps: # of deps: " << dep_amount << std::endl;
// parallel_for(dep_amount, [&](int start, int end)
// {
for(int i=start; i<end; ++i)
{
std::cout << "."; fflush(stdout);
std::vector<std::string> lines;
std::string original_path = deps[i].getOriginalPath();
if (isRpath(original_path))
original_path = searchFilenameInRpaths(original_path);
collectRpathsForFilename(original_path);
collectDependencies(original_path, lines);
for (int n=0; n<dep_amount; n++) {
std::cout << "."; fflush(stdout);
std::vector<std::string> lines;
std::string original_path = deps[n].getOriginalPath();
if (isRpath(original_path))
original_path = searchFilenameInRpaths(original_path);
const int line_amount = lines.size();
int s = 0;
int e = line_amount;
std::cout << "collectSubDeps: # of lines: " << line_amount << std::endl;
// parallel_for(line_amount, [&](int s, int e)
// {
for(int j=s; j<e; ++j)
{
if(lines[j][0] != '\t')
continue; // only lines beginning with a tab interest us
if(lines[j].find(".framework") != std::string::npos)
continue; //Ignore frameworks, we cannot handle them
collectRpathsForFilename(original_path);
collectDependencies(original_path, lines);
// trim useless info, keep only library name
std::string dep_path = lines[j].substr(1, lines[j].rfind(" (") - 1);
if (isRpath(dep_path))
collectRpathsForFilename(searchFilenameInRpaths(dep_path));
addDependency(dep_path);
}
// });
const int line_amount = lines.size();
for (int n=0; n<line_amount; n++) {
if (lines[n][0] != '\t')
continue; // only lines beginning with a tab interest us
if (lines[n].find(".framework") != std::string::npos)
continue; //Ignore frameworks, we cannot handle them
// trim useless info, keep only library name
std::string dep_path = lines[n].substr(1, lines[n].rfind(" (") - 1);
if (isRpath(dep_path))
collectRpathsForFilename(searchFilenameInRpaths(dep_path));
addDependency(dep_path);
}
// });
}
if(deps.size() == dep_amount)
if (deps.size() == dep_amount)
break; // no more dependencies were added on this iteration, stop searching
}
}
@ -303,33 +225,26 @@ void createDestDir()
// ----------- check dest folder stuff ----------
bool dest_exists = fileExists(dest_folder);
if(dest_exists and Settings::canOverwriteDir())
{
if (dest_exists and Settings::canOverwriteDir()) {
std::cout << "* Erasing old output directory " << dest_folder.c_str() << std::endl;
std::string command = std::string("rm -r ") + dest_folder;
if( systemp( command ) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while attempting to overwrite dest folder." << std::endl;
exit(1);
}
dest_exists = false;
}
if(!dest_exists)
{
if(Settings::canCreateDir())
{
if (!dest_exists) {
if (Settings::canCreateDir()) {
std::cout << "* Creating output directory " << dest_folder.c_str() << std::endl;
std::string command = std::string("mkdir -p ") + dest_folder;
if( systemp( command ) != 0)
{
if (systemp(command) != 0) {
std::cerr << "\n\nError : An error occured while creating dest folder." << std::endl;
exit(1);
}
}
else
{
else {
std::cerr << "\n\nError : Dest folder does not exist. Create it or pass the appropriate flag for automatic dest dir creation." << std::endl;
exit(1);
}
@ -342,42 +257,27 @@ void doneWithDeps_go()
std::cout << std::endl;
const int dep_amount = deps.size();
// print info to user
for(int n=0; n<dep_amount; n++)
for (int n=0; n<dep_amount; n++)
deps[n].print();
std::cout << std::endl;
// copy files if requested by user
if(Settings::bundleLibs())
{
if (Settings::bundleLibs()) {
createDestDir();
// for(int n=0; n<dep_amount; n++)
std::cout << "donewithDeps_go: # of deps: " << dep_amount << std::endl;
int start = 0;
int end = dep_amount;
// parallel_for(dep_amount, [&](int start, int end)
// {
for(int i=start; i<end; ++i)
{
parallel_for(dep_amount, [&](int start, int end) {
for (int i=start; i<end; ++i) {
deps[i].copyYourself();
changeLibPathsOnFile(deps[i].getInstallPath());
fixRpathsOnFile(deps[i].getOriginalPath(), deps[i].getInstallPath());
}
// });
});
}
const int fileToFixAmount = Settings::fileToFixAmount();
std::cout << "# of files to fix: " << fileToFixAmount << std::endl;
int s = 0;
int e = fileToFixAmount;
// parallel_for(fileToFixAmount, [&](int start, int end)
// {
for(int i=s; i<e; ++i)
{
parallel_for(fileToFixAmount, [&](int start, int end) {
for (int i=start; i<end; ++i) {
changeLibPathsOnFile(Settings::fileToFix(i));
fixRpathsOnFile(Settings::fileToFix(i), Settings::fileToFix(i));
}
// });
});
}

View File

@ -1,27 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _crawler_
#define _crawler_

View File

@ -1,10 +1,10 @@
#ifndef _parallel_for_h_
#define _parallel_for_h_
#include <algorithm>
#include <thread>
#include <functional>
#include <vector>
// #include <pthread.h>
// typedef void *(*THREADFUNCPTR)(void *);
/**
* @param nb_elements size of your for loop
@ -21,59 +21,24 @@ static void parallel_for(unsigned nb_elements,
std::function<void (int start, int end)> functor,
bool use_threads = true)
{
// unsigned nb_threads_hint = std::thread::hardware_concurrency();
// unsigned nb_threads = nb_threads_hint == 0 ? 8 : (nb_threads_hint);
unsigned nb_threads = 8;
unsigned nb_threads_hint = std::thread::hardware_concurrency();
unsigned nb_threads = nb_threads_hint == 0 ? 8 : nb_threads_hint;
unsigned batch_size = nb_elements / nb_threads;
unsigned batch_remainder = nb_elements % nb_threads;
// std::vector<std::thread> my_threads(nb_threads);
std::vector<std::thread> my_threads(nb_threads+1);
// pthread_t threads[nb_threads];
// pthread_attr_t attr;
int rc;
int i;
void *status;
// Initialize and set thread joinable
// pthread_attr_init(&attr);
// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
std::vector<std::thread> my_threads(nb_threads);
if (use_threads) {
// Multithread execution
for(unsigned i = 0; i < nb_threads; ++i) {
// for (i = 0; i < nb_threads; ++i) {
for (unsigned i = 0; i < nb_threads; ++i) {
int start = i * batch_size;
my_threads[i] = std::thread(functor, start, start+batch_size);
// rc = pthread_create(&threads[i], &attr, (THREADFUNCPTR)&functor, (void *)i);
// if (rc) {
// std::cout << "Error:unable to create thread," << rc << std::endl;
// exit(-1);
// }
// std::cout << "pthread created" << std::endl;
}
// free attribute and wait for the other threads
// pthread_attr_destroy(&attr);
// for (i = 0; i < nb_threads; ++i) {
// rc = pthread_join(threads[i], &status);
// if (rc) {
// std::cout << "Error:unable to join," << rc << std::endl;
// exit(-1);
// }
// std::cout << "Main: completed thread id :" << i ;
// std::cout << " exiting with status :" << status << std::endl;
// }
// std::cout << "Main: program exiting." << std::endl;
// pthread_exit(NULL);
}
else {
// Single thread execution (for easy debugging)
for (unsigned i = 0; i < nb_threads; ++i){
for (unsigned i = 0; i < nb_threads; ++i) {
int start = i * batch_size;
functor(start, start+batch_size);
}
@ -81,10 +46,11 @@ static void parallel_for(unsigned nb_elements,
// Deform the elements left
int start = nb_threads * batch_size;
// functor(start, start+batch_remainder);
my_threads[nb_threads] = std::thread(functor, start, start+batch_remainder);
functor(start, start+batch_remainder);
// Wait for the other thread to finish their task
if(use_threads)
if (use_threads)
std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
}
#endif

View File

@ -1,88 +1,64 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "Settings.h"
#include <vector>
namespace Settings
{
namespace Settings {
bool overwrite_files = false;
bool overwrite_dir = false;
bool create_dir = false;
bool verbose_output = true;
bool canOverwriteFiles(){ return overwrite_files; }
bool canOverwriteDir(){ return overwrite_dir; }
bool canCreateDir(){ return create_dir; }
void canOverwriteFiles(bool permission){ overwrite_files = permission; }
void canOverwriteDir(bool permission){ overwrite_dir = permission; }
void canCreateDir(bool permission){ create_dir = permission; }
bool canOverwriteFiles() { return overwrite_files; }
bool canOverwriteDir() { return overwrite_dir; }
bool canCreateDir() { return create_dir; }
void canOverwriteFiles(bool permission) { overwrite_files = permission; }
void canOverwriteDir(bool permission) { overwrite_dir = permission; }
void canCreateDir(bool permission) { create_dir = permission; }
bool bundleLibs_bool = false;
bool bundleLibs(){ return bundleLibs_bool; }
void bundleLibs(bool on){ bundleLibs_bool = on; }
bool bundleLibs() { return bundleLibs_bool; }
void bundleLibs(bool on) { bundleLibs_bool = on; }
std::string dest_folder_str = "./libs/";
std::string destFolder(){ return dest_folder_str; }
std::string destFolder() { return dest_folder_str; }
void destFolder(std::string path)
{
dest_folder_str = path;
// fix path if needed so it ends with '/'
if( dest_folder_str[ dest_folder_str.size()-1 ] != '/' ) dest_folder_str += "/";
if (dest_folder_str[dest_folder_str.size()-1] != '/')
dest_folder_str += "/";
}
std::vector<std::string> files;
void addFileToFix(std::string path){ files.push_back(path); }
int fileToFixAmount(){ return files.size(); }
std::string fileToFix(const int n){ return files[n]; }
void addFileToFix(std::string path) { files.push_back(path); }
int fileToFixAmount() { return files.size(); }
std::string fileToFix(const int n) { return files[n]; }
std::string inside_path_str = "@executable_path/../libs/";
std::string inside_lib_path(){ return inside_path_str; }
std::string inside_lib_path() { return inside_path_str; }
void inside_lib_path(std::string p)
{
inside_path_str = p;
// fix path if needed so it ends with '/'
if( inside_path_str[ inside_path_str.size()-1 ] != '/' ) inside_path_str += "/";
if (inside_path_str[inside_path_str.size()-1] != '/')
inside_path_str += "/";
}
std::vector<std::string> prefixes_to_ignore;
void ignore_prefix(std::string prefix)
{
if( prefix[ prefix.size()-1 ] != '/' ) prefix += "/";
if (prefix[prefix.size()-1] != '/')
prefix += "/";
prefixes_to_ignore.push_back(prefix);
}
bool isPrefixIgnored(std::string prefix)
{
const int prefix_amount = prefixes_to_ignore.size();
for(int n=0; n<prefix_amount; n++)
{
if(prefix.compare(prefixes_to_ignore[n]) == 0) return true;
for (int n=0; n<prefix_amount; n++) {
if (prefix.compare(prefixes_to_ignore[n]) == 0)
return true;
}
return false;
@ -90,20 +66,24 @@ bool isPrefixIgnored(std::string prefix)
bool isPrefixBundled(std::string prefix)
{
if(prefix.find(".framework") != std::string::npos) return false;
if(prefix.find("@executable_path") != std::string::npos) return false;
if(prefix.compare("/usr/lib/") == 0) return false;
if(isPrefixIgnored(prefix)) return false;
if (prefix.find(".framework") != std::string::npos)
return false;
if (prefix.find("@executable_path") != std::string::npos)
return false;
if (prefix.compare("/usr/lib/") == 0)
return false;
if (isPrefixIgnored(prefix))
return false;
return true;
}
std::vector<std::string> searchPaths;
void addSearchPath(std::string path){ searchPaths.push_back(path); }
int searchPathAmount(){ return searchPaths.size(); }
std::string searchPath(const int n){ return searchPaths[n]; }
void addSearchPath(std::string path) { searchPaths.push_back(path); }
int searchPathAmount() { return searchPaths.size(); }
std::string searchPath(const int n) { return searchPaths[n]; }
bool verboseOutput(){ return verbose_output; }
void verboseOutput(bool status){ verbose_output = status; }
bool verboseOutput() { return verbose_output; }
void verboseOutput(bool status) { verbose_output = status; }
}
} // namespace Settings

View File

@ -1,39 +1,14 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _settings_
#define _settings_
#include <string>
namespace Settings
{
namespace Settings {
bool isPrefixBundled(std::string prefix);
bool isPrefixIgnored(std::string prefix);
void ignore_prefix(std::string prefix);
bool canOverwriteFiles();
void canOverwriteFiles(bool permission);
@ -63,5 +38,6 @@ std::string searchPath(const int n);
bool verboseOutput();
void verboseOutput(bool status);
}
} // namespace Settings
#endif

View File

@ -1,28 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "Utils.h"
#include "Dependency.h"
#include "Settings.h"
@ -33,13 +8,8 @@ THE SOFTWARE.
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
/*
void setInstallPath(string loc)
{
path_to_libs_folder = loc;
}*/
using namespace std;
void tokenize(const string& str, const char* delim, vector<string>* vectorarg)
{
@ -48,13 +18,12 @@ void tokenize(const string& str, const char* delim, vector<string>* vectorarg)
string delimiters(delim);
// skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of( delimiters , 0);
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
while (string::npos != pos || string::npos != lastPos) {
// found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
@ -64,61 +33,48 @@ void tokenize(const string& str, const char* delim, vector<string>* vectorarg)
// find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
bool fileExists( std::string filename )
{
if (access( filename.c_str(), F_OK ) != -1)
{
if (access(filename.c_str(), F_OK) != -1) {
return true; // file exists
}
else
{
//std::cout << "access(filename) returned -1 on filename [" << filename << "] I will try trimming." << std::endl;
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
{
//std::cout << "Still failed. Cannot find the specified file." << std::endl;
return false;// file doesn't exist
}
return false; // file doesn't exist
}
}
void copyFile(string from, string to)
{
bool override = Settings::canOverwriteFiles();
if(!override)
{
if(fileExists( to ))
{
bool overwrite = Settings::canOverwriteFiles();
if (!overwrite) {
if (fileExists(to)) {
cerr << "\n\nError : File " << to.c_str() << " already exists. Remove it or enable overwriting." << endl;
exit(1);
}
}
string override_permission = string(override ? "-f " : "-n ");
string overwrite_permission = string(overwrite ? "-f " : "-n ");
// copy file to local directory
string command = string("cp ") + override_permission + from + string(" ") + to;
if( from != to && systemp( command ) != 0 )
{
string command = string("cp ") + overwrite_permission + from + string(" ") + to;
if (from != to && systemp(command) != 0) {
cerr << "\n\nError : An error occured while trying to copy file " << from << " to " << to << endl;
exit(1);
}
// give it write permission
string command2 = string("chmod +w ") + to;
if( systemp( command2 ) != 0 )
{
if (systemp(command2) != 0) {
cerr << "\n\nError : An error occured while trying to set write permissions on file " << to << endl;
exit(1);
}
@ -126,45 +82,44 @@ void copyFile(string from, string to)
std::string system_get_output(std::string cmd)
{
FILE * command_output;
FILE* command_output;
char output[128];
int amount_read = 1;
std::string full_output;
try
{
try {
command_output = popen(cmd.c_str(), "r");
if(command_output == NULL) throw;
if (command_output == NULL)
throw;
while(amount_read > 0)
{
while (amount_read > 0) {
amount_read = fread(output, 1, 127, command_output);
if(amount_read <= 0) break;
else
{
if (amount_read <= 0) {
break;
}
else {
output[amount_read] = '\0';
full_output += output;
}
}
}
catch(...)
{
catch (...) {
std::cerr << "An error occured while executing command " << cmd.c_str() << std::endl;
pclose(command_output);
return "";
}
int return_value = pclose(command_output);
if(return_value != 0) return "";
if (return_value != 0)
return "";
return full_output;
}
int systemp(std::string& cmd)
{
if(Settings::verboseOutput())
{
if (Settings::verboseOutput()) {
std::cout << " " << cmd.c_str() << std::endl;
}
return system(cmd.c_str());
@ -173,17 +128,17 @@ int systemp(std::string& cmd)
std::string getUserInputDirForFile(const std::string& filename)
{
const int searchPathAmount = Settings::searchPathAmount();
for(int n=0; n<searchPathAmount; n++)
{
for (int n=0; n<searchPathAmount; n++) {
auto searchPath = Settings::searchPath(n);
if( !searchPath.empty() && searchPath[ searchPath.size()-1 ] != '/' ) searchPath += "/";
if(!searchPath.empty() && searchPath[searchPath.size()-1] != '/')
searchPath += "/";
if( !fileExists( searchPath+filename ) ) {
if (!fileExists(searchPath+filename)) {
continue;
} else {
std::cerr << (searchPath+filename) << " was found.\n"
<< "/!\\ DylibBundler MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: "
<< "Manually check the executable with 'otool -L'" << std::endl;
<< "Check the executable with 'otool -L'" << std::endl;
return searchPath;
}
}
@ -196,20 +151,20 @@ std::string getUserInputDirForFile(const std::string& filename)
std::cin >> prefix;
std::cout << std::endl;
if(prefix.compare("quit")==0) exit(1);
if (prefix.compare("quit") == 0)
exit(1);
if( !prefix.empty() && prefix[ prefix.size()-1 ] != '/' ) prefix += "/";
if (!prefix.empty() && prefix[prefix.size()-1] != '/')
prefix += "/";
if( !fileExists( prefix+filename ) )
{
if (!fileExists( prefix+filename)) {
std::cerr << (prefix+filename) << " does not exist. Try again" << std::endl;
continue;
}
else
{
else {
std::cerr << (prefix+filename) << " was found.\n"
<< "/!\\ DylibBundler MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: "
<< "Manually check the executable with 'otool -L'" << std::endl;
<< "Check the executable with 'otool -L'" << std::endl;
return prefix;
}
}

View File

@ -1,28 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _utils_h_
#define _utils_h_
@ -32,7 +7,7 @@ THE SOFTWARE.
class Library;
void tokenize(const std::string& str, const char* delimiters, std::vector<std::string>*);
bool fileExists( std::string filename );
bool fileExists(std::string filename);
void copyFile(std::string from, std::string to);

View File

@ -1,27 +1,3 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Marianne Gagnon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <cstdlib>
#include <cstring>
#include <iostream>
@ -31,7 +7,6 @@ THE SOFTWARE.
#include "Utils.h"
#include "DylibBundler.h"
#include "ParallelFor.h"
/*
TODO
@ -44,12 +19,10 @@ THE SOFTWARE.
const std::string VERSION = "git";
// FIXME - no memory management is done at all (anyway the program closes immediately so who cares?)
std::string installPath = "";
void showHelp()
{
std::cout << "dylibbundler " << VERSION << std::endl;
@ -70,73 +43,59 @@ void showHelp()
int main (int argc, char * const argv[])
{
// parse arguments
for(int i=0; i<argc; i++)
{
if(strcmp(argv[i],"-x")==0 or strcmp(argv[i],"--fix-file")==0)
{
for (int i=0; i<argc; i++) {
if (strcmp(argv[i],"-x") == 0 || strcmp(argv[i],"--fix-file") == 0) {
i++;
Settings::addFileToFix(argv[i]);
continue;
}
else if(strcmp(argv[i],"-b")==0 or strcmp(argv[i],"--bundle-deps")==0)
{
else if (strcmp(argv[i],"-b") == 0 || strcmp(argv[i],"--bundle-deps") == 0) {
Settings::bundleLibs(true);
continue;
}
else if(strcmp(argv[i],"-p")==0 or strcmp(argv[i],"--install-path")==0)
{
else if (strcmp(argv[i],"-p") == 0 || strcmp(argv[i],"--install-path") == 0) {
i++;
Settings::inside_lib_path(argv[i]);
continue;
}
else if(strcmp(argv[i],"-i")==0 or strcmp(argv[i],"--ignore")==0)
{
else if (strcmp(argv[i],"-i") == 0 || strcmp(argv[i],"--ignore") == 0) {
i++;
Settings::ignore_prefix(argv[i]);
continue;
}
else if(strcmp(argv[i],"-d")==0 or strcmp(argv[i],"--dest-dir")==0)
{
else if (strcmp(argv[i],"-d") == 0 || strcmp(argv[i],"--dest-dir") == 0) {
i++;
Settings::destFolder(argv[i]);
continue;
}
else if(strcmp(argv[i],"-of")==0 or strcmp(argv[i],"--overwrite-files")==0)
{
else if (strcmp(argv[i],"-of") == 0 || strcmp(argv[i],"--overwrite-files") == 0) {
Settings::canOverwriteFiles(true);
continue;
}
else if(strcmp(argv[i],"-od")==0 or strcmp(argv[i],"--overwrite-dir")==0)
{
else if (strcmp(argv[i],"-od") == 0 || strcmp(argv[i],"--overwrite-dir") == 0) {
Settings::canOverwriteDir(true);
Settings::canCreateDir(true);
continue;
}
else if(strcmp(argv[i],"-cd")==0 or strcmp(argv[i],"--create-dir")==0)
{
else if (strcmp(argv[i],"-cd") == 0 || strcmp(argv[i],"--create-dir") == 0) {
Settings::canCreateDir(true);
continue;
}
else if(strcmp(argv[i],"-h")==0 or strcmp(argv[i],"--help")==0)
{
else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"--help") == 0) {
showHelp();
exit(0);
}
if(strcmp(argv[i],"-s")==0 or strcmp(argv[i],"--search-path")==0)
{
if (strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"--search-path") == 0) {
i++;
Settings::addSearchPath(argv[i]);
continue;
}
else if(strcmp(argv[i],"-q")==0 or strcmp(argv[i],"--quiet")==0)
{
else if (strcmp(argv[i],"-q") == 0 || strcmp(argv[i],"--quiet") == 0) {
Settings::verboseOutput(false);
continue;
}
else if(i>0)
{
else if (i > 0) {
// if we meet an unknown flag, abort
// ignore first one cause it's usually the path to the executable
std::cerr << "Unknown flag " << argv[i] << std::endl << std::endl;
@ -145,8 +104,7 @@ int main (int argc, char * const argv[])
}
}
if(not Settings::bundleLibs() and Settings::fileToFixAmount()<1)
{
if (!Settings::bundleLibs() && Settings::fileToFixAmount() < 1) {
showHelp();
exit(0);
}
@ -154,8 +112,7 @@ int main (int argc, char * const argv[])
std::cout << "* Collecting dependencies"; fflush(stdout);
const int amount = Settings::fileToFixAmount();
std::cout << "# of files to fix: " << amount << std::endl;
for(int n=0; n<amount; n++)
for (int n=0; n<amount; n++)
collectDependencies(Settings::fileToFix(n));
collectSubDependencies();