From f834093a8904a076f248d0f7034b66bbe0a5087f Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 23 Jun 2021 21:13:39 +0200 Subject: Add configure checks for programs and be more consistent with the use of the phrases build and host systems (inspired by autotools). --- configure.cc | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- libcppbuild.h | 18 +++---- rebuild.cc | 2 +- task.cc | 14 ++--- task.h | 2 +- task_ar.cc | 8 +-- 6 files changed, 174 insertions(+), 31 deletions(-) diff --git a/configure.cc b/configure.cc index 1979936..c19910e 100644 --- a/configure.cc +++ b/configure.cc @@ -38,6 +38,57 @@ const std::string& getConfiguration(const std::string& key, return defaultValue; } +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 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 {}; +} + int configure(int argc, char* argv[]) { Settings settings; @@ -58,7 +109,13 @@ int configure(int argc, char* argv[]) int key{128}; std::string build_arch; + std::string build_path; std::string host_arch; + std::string host_path; + std::string cc_prog = "gcc"; + std::string cxx_prog = "g++"; + std::string ar_prog = "ar"; + std::string ld_prog = "ld"; opt.add("build-dir", required_argument, 'b', "Set output directory for build files (default: '" + @@ -75,6 +132,34 @@ int configure(int argc, char* argv[]) return 0; }); + opt.add("cc", required_argument, key++, + "Use specified c-compiler instead of gcc.", + [&]() { + cc_prog = optarg; + return 0; + }); + + opt.add("cxx", required_argument, key++, + "Use specified c++-compiler instead of g++.", + [&]() { + cxx_prog = optarg; + return 0; + }); + + opt.add("ar", required_argument, key++, + "Use specified archiver instead of ar.", + [&]() { + ar_prog = optarg; + return 0; + }); + + opt.add("ld", required_argument, key++, + "Use specified linker instead of ld.", + [&]() { + ld_prog = optarg; + return 0; + }); + opt.add("build", required_argument, key++, "Configure for building on specified architecture.", [&]() { @@ -82,6 +167,13 @@ int configure(int argc, char* argv[]) return 0; }); + opt.add("build-path", required_argument, key++, + "Set path to build tool-chain.", + [&]() { + build_path = optarg; + return 0; + }); + opt.add("host", required_argument, key++, "Cross-compile to build programs to run on specified architecture.", [&]() { @@ -89,6 +181,13 @@ int configure(int argc, char* argv[]) return 0; }); + opt.add("host-path", required_argument, key++, + "Set path to cross-compile tool-chain.", + [&]() { + host_path = optarg; + return 0; + }); + opt.add("help", no_argument, 'h', "Print this help text.", [&]() { @@ -106,10 +205,11 @@ int configure(int argc, char* argv[]) } auto tasks = getTasks(settings); - +/* bool needs_cpp{false}; bool needs_c{false}; bool needs_ar{false}; + bool needs_asm{false}; for(const auto& task :tasks) { switch(task->sourceLanguage()) @@ -124,8 +224,44 @@ int configure(int argc, char* argv[]) case Language::Cpp: needs_c = true; break; + case Language::Asm: + needs_asm = true; + break; } } +*/ + auto cc_env = getenv("CC"); + if(cc_env) + { + cc_prog = cc_env; + } + + auto cxx_env = getenv("CXX"); + if(cxx_env) + { + cxx_prog = cxx_env; + } + + auto ar_env = getenv("AR"); + if(ar_env) + { + ar_prog = ar_env; + } + + auto ld_env = getenv("LD"); + if(ld_env) + { + ld_prog = ld_env; + } + + std::string host_cc = locate(host_arch, cc_prog); + std::string host_cxx = locate(host_arch, cxx_prog); + std::string host_ar = locate(host_arch, ar_prog); + std::string host_ld = locate(host_arch, ld_prog); + std::string build_cc = locate(build_arch, cc_prog); + std::string build_cxx = locate(build_arch, cxx_prog); + std::string build_ar = locate(build_arch, ar_prog); + std::string build_ld = locate(build_arch, ld_prog); { std::ofstream istr(configurationFile); @@ -136,18 +272,25 @@ int configure(int argc, char* argv[]) istr << " {\n"; istr << " { \"cmd\", \"" << cmd_str << "\" },\n"; istr << " { \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; - istr << " { \"" << cfg::target_cc << "\", \"/usr/bin/gcc\" },\n"; - istr << " { \"" << cfg::target_cpp << "\", \"/usr/bin/g++\" },\n"; - istr << " { \"" << cfg::target_ar << "\", \"/usr/bin/ar\" },\n"; - istr << " { \"" << cfg::target_ld << "\", \"/usr/bin/ld\" },\n"; - istr << " { \"" << cfg::host_cc << "\", \"/usr/bin/gcc\" },\n"; - istr << " { \"" << cfg::host_cpp << "\", \"/usr/bin/g++\" },\n"; - istr << " { \"" << cfg::host_ar << "\", \"/usr/bin/ar\" },\n"; - istr << " { \"" << cfg::host_ld << "\", \"/usr/bin/ld\" },\n"; + istr << " { \"" << cfg::host_cc << "\", \"" << host_cc << "\" },\n"; + istr << " { \"" << cfg::host_cxx << "\", \"" << host_cxx << "\" },\n"; + istr << " { \"" << cfg::host_ar << "\", \"" << host_ar << "\" },\n"; + istr << " { \"" << cfg::host_ld << "\", \"" << host_ld << "\" },\n"; + istr << " { \"" << cfg::build_cc << "\", \"" << build_cc << "\" },\n"; + istr << " { \"" << cfg::build_cxx << "\", \"" << build_cxx << "\" },\n"; + istr << " { \"" << cfg::build_ar << "\", \"" << build_ar << "\" },\n"; + istr << " { \"" << cfg::build_ld << "\", \"" << build_ld << "\" },\n"; istr << " };\n"; istr << " return c;\n"; istr << "}\n"; } + { + std::ofstream istr(configHeaderFile); + istr << "#pragma once\n\n"; + istr << "#define HAS_FOO 1\n"; + istr << "//#define HAS_BAR 1\n"; + } + return 0; } diff --git a/libcppbuild.h b/libcppbuild.h index 9ea3fb1..d0a0080 100644 --- a/libcppbuild.h +++ b/libcppbuild.h @@ -26,15 +26,15 @@ enum class Language enum class OutputSystem { - Target, // Output for the target system - BuildHost, // Internal tool during cross-compilation + Host, // Output for the target system + Build, // Internal tool during cross-compilation }; struct BuildConfiguration { TargetType type{TargetType::Auto}; Language language{Language::Auto}; - OutputSystem system{OutputSystem::Target}; + OutputSystem system{OutputSystem::Host}; std::string target; std::vector sources; // source list std::vector depends; // internal dependencies @@ -59,15 +59,15 @@ namespace cfg { constexpr auto builddir = "builddir"; -constexpr auto target_cc = "target-cc"; -constexpr auto target_cpp = "target-cpp"; -constexpr auto target_ar = "target-ar"; -constexpr auto target_ld = "target-ld"; - constexpr auto host_cc = "host-cc"; -constexpr auto host_cpp = "host-cpp"; +constexpr auto host_cxx = "host-cpp"; constexpr auto host_ar = "host-ar"; constexpr auto host_ld = "host-ld"; + +constexpr auto build_cc = "build-cc"; +constexpr auto build_cxx = "build-cpp"; +constexpr auto build_ar = "build-ar"; +constexpr auto build_ld = "build-ld"; } const std::map& configuration(); diff --git a/rebuild.cc b/rebuild.cc index 0978eb1..b4564de 100644 --- a/rebuild.cc +++ b/rebuild.cc @@ -116,7 +116,7 @@ void recompileCheck(const Settings& settings, int argc, char* argv[], bool force if(dirty) { std::cout << "Rebuilding config\n"; - auto tool = getConfiguration(cfg::host_cpp, "/usr/bin/g++"); + auto tool = getConfiguration(cfg::build_cxx, "/usr/bin/g++"); auto ret = execute(tool, args, settings.verbose > 0); if(ret != 0) { diff --git a/task.cc b/task.cc index 70d0b76..5a08a47 100644 --- a/task.cc +++ b/task.cc @@ -115,18 +115,18 @@ std::string Task::compiler() const case Language::C: switch(outputSystem()) { - case OutputSystem::Target: - return getConfiguration(cfg::target_cc, "/usr/bin/gcc"); - case OutputSystem::BuildHost: + case OutputSystem::Host: return getConfiguration(cfg::host_cc, "/usr/bin/gcc"); + case OutputSystem::Build: + return getConfiguration(cfg::build_cc, "/usr/bin/gcc"); } case Language::Cpp: switch(outputSystem()) { - case OutputSystem::Target: - return getConfiguration(cfg::target_cpp, "/usr/bin/g++"); - case OutputSystem::BuildHost: - return getConfiguration(cfg::host_cpp, "/usr/bin/g++"); + case OutputSystem::Host: + return getConfiguration(cfg::host_cxx, "/usr/bin/g++"); + case OutputSystem::Build: + return getConfiguration(cfg::build_cxx, "/usr/bin/g++"); } default: std::cerr << "Unknown CC target type\n"; diff --git a/task.h b/task.h index 09bfd7d..8ad11c3 100644 --- a/task.h +++ b/task.h @@ -53,5 +53,5 @@ protected: const BuildConfiguration& config; TargetType target_type{TargetType::Auto}; Language source_language{Language::Auto}; - OutputSystem output_system{OutputSystem::Target}; + OutputSystem output_system{OutputSystem::Host}; }; diff --git a/task_ar.cc b/task_ar.cc index a183102..bcaa010 100644 --- a/task_ar.cc +++ b/task_ar.cc @@ -146,12 +146,12 @@ int TaskAR::runInner() std::string tool; switch(outputSystem()) { - case OutputSystem::Target: - tool = getConfiguration(cfg::target_ar, "/usr/bin/ar"); - break; - case OutputSystem::BuildHost: + case OutputSystem::Host: tool = getConfiguration(cfg::host_ar, "/usr/bin/ar"); break; + case OutputSystem::Build: + tool = getConfiguration(cfg::build_ar, "/usr/bin/ar"); + break; } return execute(tool, args, settings.verbose > 0); -- cgit v1.2.3