summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2023-01-20 08:37:29 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2023-01-20 09:02:45 +0100
commita5585150f0ff8d27ddd22792f521f1374a3eedd8 (patch)
tree3bb442e835502d452ebe5137ad7fca5f5156bb5f /src
parent3cbadb8f5c55020ece96fab0fc8f4f51da01888e (diff)
Add env to execute function.
Diffstat (limited to 'src')
-rw-r--r--src/configure.cc127
-rw-r--r--src/execute.cc82
-rw-r--r--src/execute.h4
-rw-r--r--src/task_ar.cc2
-rw-r--r--src/task_cc.cc2
-rw-r--r--src/task_ld.cc2
-rw-r--r--src/task_so.cc2
-rw-r--r--src/unittest.cc2
-rw-r--r--src/util.cc79
-rw-r--r--src/util.h6
10 files changed, 224 insertions, 84 deletions
diff --git a/src/configure.cc b/src/configure.cc
index 10f3056..b2639cb 100644
--- a/src/configure.cc
+++ b/src/configure.cc
@@ -98,57 +98,6 @@ const std::string& ctor::configuration::get(const std::string& key, const std::s
return default_value;
}
-std::string locate(const std::string& arch, const std::string& app)
-{
- std::string path_env = std::getenv("PATH");
- //std::cout << path_env << "\n";
-
- std::string program = app;
- if(!arch.empty())
- {
- program = arch + "-" + app;
- }
- std::cout << "Looking for: " << program << "\n";
- std::vector<std::string> paths;
-
- {
- std::stringstream ss(path_env);
- std::string path;
- while (std::getline(ss, path, ':'))
- {
- paths.push_back(path);
- }
- }
- for(const auto& path_str : paths)
- {
- std::filesystem::path path(path_str);
- auto prog_path = path / program;
- if(std::filesystem::exists(prog_path))
- {
- std::cout << "Found file " << app << " in path: " << path << "\n";
- auto perms = std::filesystem::status(prog_path).permissions();
- if((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none)
- {
- //std::cout << " - executable by owner\n";
- }
- if((perms & std::filesystem::perms::group_exec) != std::filesystem::perms::none)
- {
- //std::cout << " - executable by group\n";
- }
- if((perms & std::filesystem::perms::others_exec) != std::filesystem::perms::none)
- {
- //std::cout << " - executable by others\n";
- }
-
- return prog_path.string();
- }
- }
-
- std::cerr << "Could not locate " << app << " for the " << arch << " architecture\n";
- exit(1);
- return {};
-}
-
class Args
: public std::vector<char*>
{
@@ -475,11 +424,36 @@ int regenerateCache(ctor::settings& settings,
ld_prog = ld_env->second;
}
+ auto paths = get_paths();
+
// Host detection
- auto host_cc = locate(host_arch_prefix, cc_prog);
- auto host_cxx = locate(host_arch_prefix, cxx_prog);
- auto host_ar = locate(host_arch_prefix, ar_prog);
- auto host_ld = locate(host_arch_prefix, ld_prog);
+ auto host_cc = locate(cc_prog, paths, host_arch_prefix);
+ if(host_cc.empty())
+ {
+ std::cerr << "Could not locate host_cc prog" << std::endl;
+ return 1;
+ }
+
+ auto host_cxx = locate(cxx_prog, paths, host_arch_prefix);
+ if(host_cxx.empty())
+ {
+ std::cerr << "Could not locate host_cxx prog" << std::endl;
+ return 1;
+ }
+
+ auto host_ar = locate(ar_prog, paths, host_arch_prefix);
+ if(host_ar.empty())
+ {
+ std::cerr << "Could not locate host_ar prog" << std::endl;
+ return 1;
+ }
+
+ auto host_ld = locate(ld_prog, paths, host_arch_prefix);
+ if(host_ld.empty())
+ {
+ std::cerr << "Could not locate host_ld prog" << std::endl;
+ return 1;
+ }
auto host_toolchain = getToolChain(host_cxx);
auto host_arch_str = get_arch(ctor::output_system::host);
@@ -487,11 +461,40 @@ int regenerateCache(ctor::settings& settings,
std::cout << "** Host architecture '" << host_arch_str << "': " << host_arch << std::endl;
+ if(host_arch == ctor::arch::unknown)
+ {
+ std::cerr << "Could not detect host architecture" << std::endl;
+ return 1;
+ }
+
// Build detection
- auto build_cc = locate(build_arch_prefix, cc_prog);
- auto build_cxx = locate(build_arch_prefix, cxx_prog);
- auto build_ar = locate(build_arch_prefix, ar_prog);
- auto build_ld = locate(build_arch_prefix, ld_prog);
+ auto build_cc = locate(cc_prog, paths, build_arch_prefix);
+ if(build_cc.empty())
+ {
+ std::cerr << "Could not locate build_cc prog" << std::endl;
+ return 1;
+ }
+
+ auto build_cxx = locate(cxx_prog, paths, build_arch_prefix);
+ if(build_cxx.empty())
+ {
+ std::cerr << "Could not locate build_cxx prog" << std::endl;
+ return 1;
+ }
+
+ auto build_ar = locate(ar_prog, paths, build_arch_prefix);
+ if(build_ar.empty())
+ {
+ std::cerr << "Could not locate build_ar prog" << std::endl;
+ return 1;
+ }
+
+ auto build_ld = locate(ld_prog, paths, build_arch_prefix);
+ if(build_ld.empty())
+ {
+ std::cerr << "Could not locate build_ld prog" << std::endl;
+ return 1;
+ }
auto build_toolchain = getToolChain(build_cxx);
auto build_arch_str = get_arch(ctor::output_system::build);
@@ -499,6 +502,12 @@ int regenerateCache(ctor::settings& settings,
std::cout << "** Build architecture '" << build_arch_str << "': " << build_arch << std::endl;
+ if(build_arch == ctor::arch::unknown)
+ {
+ std::cerr << "Could not detect build architecture" << std::endl;
+ return 1;
+ }
+
if(!host_cxx.empty())
{
// This is needed for bootstrapping (when running configure for the first time)
diff --git a/src/execute.cc b/src/execute.cc
index 20a4a02..b4013d0 100644
--- a/src/execute.cc
+++ b/src/execute.cc
@@ -20,6 +20,28 @@ https://stackoverflow.com/questions/4259629/what-is-the-difference-between-fork-
namespace
{
+class Env
+ : public std::vector<char*>
+{
+public:
+ Env(const std::vector<std::string>& args)
+ {
+ for(const auto& arg : args)
+ {
+ push_back(strdup(arg.data()));
+ }
+ push_back(nullptr);
+ }
+
+ ~Env()
+ {
+ for(auto ptr : *this)
+ {
+ free(ptr);
+ }
+ }
+};
+
int parent_waitpid(pid_t pid)
{
int status;
@@ -33,8 +55,11 @@ int parent_waitpid(pid_t pid)
}
} // namespace ::
+extern char **environ; // see 'man environ'
+
int execute(const std::string& command,
const std::vector<std::string>& args,
+ const std::map<std::string, std::string>& env,
bool verbose)
{
std::vector<const char*> argv;
@@ -45,22 +70,22 @@ int execute(const std::string& command,
}
argv.push_back(nullptr);
- if(verbose)
+ std::string cmd;
+ for(const auto& arg : argv)
{
- std::string cmd;
- for(const auto& arg : argv)
+ if(arg == nullptr)
{
- if(arg == nullptr)
- {
- break;
- }
- if(!cmd.empty())
- {
- cmd += " ";
- }
- cmd += arg;
+ break;
}
+ if(!cmd.empty())
+ {
+ cmd += " ";
+ }
+ cmd += arg;
+ }
+ if(verbose)
+ {
std::cout << cmd << std::endl;
}
@@ -68,23 +93,42 @@ int execute(const std::string& command,
auto pid = vfork();
if(pid == 0)
{
- execv(command.data(), (char**)argv.data());
+ std::vector<std::string> venv;
+ for(const auto& [key, value] : env)
+ {
+ venv.push_back(key + "=" + value);
+ }
+
+ for(auto current = environ; *current; ++current)
+ {
+ venv.push_back(*current);
+ }
+
+ Env penv(venv);
+ execve(command.data(), (char**)argv.data(), penv.data());
std::cout << "Could not execute " << command << ": " <<
strerror(errno) << "\n";
- _exit(1); // execv only returns if an error occurred
+ _exit(1); // execve only returns if an error occurred
}
- auto ret = parent_waitpid(pid);
+ return parent_waitpid(pid);
#elif 0
pid_t pid;
+ std::vector<std::string> venv;
+ for(const auto& [key, value] : env)
+ {
+ venv.push_back(key + "=" + value);
+ }
+ Env penv(venv);
if(posix_spawn(&pid, command.data(), nullptr, nullptr,
- (char**)argv.data(), nullptr))
+ (char**)argv.data(), penv.data()))
{
return 1;
}
- auto ret = parent_waitpid(pid);
+ return parent_waitpid(pid);
#else
- auto ret = system(cmd.data());
+ (void)parent_waitpid;
+ return system(cmd.data());
#endif
- return ret;
+ return 1;
}
diff --git a/src/execute.h b/src/execute.h
index c750a83..336c3ef 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -5,7 +5,9 @@
#include <string>
#include <vector>
+#include <map>
int execute(const std::string& command,
- const std::vector<std::string>& args,
+ const std::vector<std::string>& args = {},
+ const std::map<std::string, std::string>& env = {},
bool verbose = true);
diff --git a/src/task_ar.cc b/src/task_ar.cc
index 605ab17..9cd78d0 100644
--- a/src/task_ar.cc
+++ b/src/task_ar.cc
@@ -118,7 +118,7 @@ int TaskAR::runInner()
break;
}
- return execute(tool, args, settings.verbose > 0);
+ return execute(tool, args, {}, settings.verbose > 0);
}
int TaskAR::clean()
diff --git a/src/task_cc.cc b/src/task_cc.cc
index 46662ad..2238b67 100644
--- a/src/task_cc.cc
+++ b/src/task_cc.cc
@@ -187,7 +187,7 @@ int TaskCC::runInner()
targetFile().lexically_normal().string() << std::endl;
}
- return execute(compiler(), args, settings.verbose > 0);
+ return execute(compiler(), args, {}, settings.verbose > 0);
}
int TaskCC::clean()
diff --git a/src/task_ld.cc b/src/task_ld.cc
index 908b641..a98ef44 100644
--- a/src/task_ld.cc
+++ b/src/task_ld.cc
@@ -123,7 +123,7 @@ int TaskLD::runInner()
}
auto tool = compiler();
- return execute(tool, args, settings.verbose > 0);
+ return execute(tool, args, {}, settings.verbose > 0);
}
int TaskLD::clean()
diff --git a/src/task_so.cc b/src/task_so.cc
index 522f6f2..e99205d 100644
--- a/src/task_so.cc
+++ b/src/task_so.cc
@@ -111,7 +111,7 @@ int TaskSO::runInner()
}
auto tool = compiler();
- return execute(tool, args, settings.verbose > 0);
+ return execute(tool, args, {}, settings.verbose > 0);
}
int TaskSO::clean()
diff --git a/src/unittest.cc b/src/unittest.cc
index 237b2e3..1e32878 100644
--- a/src/unittest.cc
+++ b/src/unittest.cc
@@ -24,7 +24,7 @@ int runUnitTests(std::set<std::shared_ptr<Task>>& tasks,
name = task->target();
}
std::cout << name << ": " << std::flush;
- auto ret = execute(task->targetFile(), {}, settings.verbose > 0);
+ auto ret = execute(task->targetFile(), {}, {}, settings.verbose > 0);
ok &= ret == 0;
if(ret == 0)
{
diff --git a/src/util.cc b/src/util.cc
index fe16471..db5a5f6 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -167,3 +167,82 @@ std::string esc(const std::string& in)
}
return out;
}
+
+std::vector<std::string> get_paths()
+{
+ std::vector<std::string> paths;
+
+ std::string path_env = std::getenv("PATH");
+
+#ifdef _WIN32
+ const char sep{';'};
+#else
+ const char sep{':'};
+#endif
+
+ std::stringstream ss(path_env);
+ std::string path;
+ while (std::getline(ss, path, sep))
+ {
+ paths.push_back(path);
+ }
+
+ return paths;
+}
+
+bool check_executable(const std::filesystem::path& prog)
+{
+ auto perms = std::filesystem::status(prog).permissions();
+
+ if((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none)
+ {
+ return true;
+ }
+
+ if((perms & std::filesystem::perms::group_exec) != std::filesystem::perms::none)
+ {
+ return true;
+ }
+
+ if((perms & std::filesystem::perms::others_exec) != std::filesystem::perms::none)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+std::string locate(const std::string& prog,
+ const std::vector<std::string>& paths,
+ const std::string& arch)
+{
+ std::string program = prog;
+ if(!arch.empty())
+ {
+ program = arch + "-" + prog;
+ }
+
+ // first check if arch contains an absolute path to prog
+ if(std::filesystem::exists(program))
+ {
+ if(check_executable(program))
+ {
+ return program;
+ }
+ }
+
+ for(const auto& path_str : paths)
+ {
+ std::filesystem::path path(path_str);
+ auto prog_path = path / program;
+ if(std::filesystem::exists(prog_path))
+ {
+ if(check_executable(prog_path))
+ {
+ return prog_path.string();
+ }
+ }
+ }
+
+ return {};
+}
diff --git a/src/util.h b/src/util.h
index 9fa6be2..eeb3206 100644
--- a/src/util.h
+++ b/src/util.h
@@ -22,3 +22,9 @@ void append(T& a, const T& b)
}
std::string esc(const std::string& in);
+
+std::vector<std::string> get_paths();
+
+std::string locate(const std::string& app,
+ const std::vector<std::string>& paths,
+ const std::string& arch = {});