From e9023132d506a9223d6c7c315a3cdf118effd30e Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 23 May 2022 18:46:13 +0200 Subject: Added support for manual externals (inherit flags and set include/lib paths from configure). --- ctor.cc | 1 + src/configure.cc | 97 +++++++++++++++++++++++++++++++++++++++---------- src/externals.h | 6 +++ src/externals_manual.cc | 33 +++++++++++++++++ src/externals_manual.h | 13 +++++++ src/libctor.h | 10 ++++- 6 files changed, 138 insertions(+), 22 deletions(-) create mode 100644 src/externals.h create mode 100644 src/externals_manual.cc create mode 100644 src/externals_manual.h diff --git a/ctor.cc b/ctor.cc index c8c7cff..cecf4d1 100644 --- a/ctor.cc +++ b/ctor.cc @@ -16,6 +16,7 @@ BuildConfigurations ctorConfigs() "src/build.cc", "src/configure.cc", "src/execute.cc", + "src/externals_manual.cc", "src/libctor.cc", "src/rebuild.cc", "src/task.cc", diff --git a/src/configure.cc b/src/configure.cc index 4df6026..02e8224 100644 --- a/src/configure.cc +++ b/src/configure.cc @@ -15,10 +15,14 @@ #include "libctor.h" #include "tasks.h" #include "rebuild.h" +#include "externals.h" std::filesystem::path configurationFile("configuration.cc"); std::filesystem::path configHeaderFile("config.h"); +std::map external_includedir; +std::map external_libdir; + const Configuration default_configuration{}; const Configuration& __attribute__((weak)) configuration() { @@ -143,6 +147,9 @@ public: } }; +// helper constant for the visitor +template inline constexpr bool always_false_v = false; + int regenerateCache(const Settings& default_settings, const std::vector& args, const std::map& env) @@ -249,6 +256,51 @@ int regenerateCache(const Settings& default_settings, return 0; }); + // Resolv externals + ExternalConfigurations externalConfigs; + for(std::size_t i = 0; i < numExternalConfigFiles; ++i) + { + auto newExternalConfigs = externalConfigFiles[i].cb(); + externalConfigs.insert(externalConfigs.end(), + newExternalConfigs.begin(), + newExternalConfigs.end()); + } + + auto add_path_args = + [&](const std::string& name) + { + opt.add(name + "-includedir", required_argument, key++, + "Set path to " + name + " header file.", + [&]() { + external_includedir[name] = optarg; + return 0; + }); + + opt.add(name + "-libdir", required_argument, key++, + "Set path to " + name + " libraries.", + [&]() { + external_libdir[name] = optarg; + return 0; + }); + }; + + for(const auto& ext : externalConfigs) + { + std::visit([&](auto&& arg) + { + using T = std::decay_t; + if constexpr (std::is_same_v) + { + add_path_args(ext.name); + } + else + { + static_assert(always_false_v, "non-exhaustive visitor!"); + } + }, ext.external); + + } + opt.add("help", no_argument, 'h', "Print this help text.", [&]() { @@ -325,16 +377,6 @@ int regenerateCache(const Settings& default_settings, std::string build_ar = locate(build_arch, ar_prog); std::string build_ld = locate(build_arch, ld_prog); - // Resolv externals - ExternalConfigurations externalConfigs; - for(std::size_t i = 0; i < numExternalConfigFiles; ++i) - { - auto newExternalConfigs = externalConfigFiles[i].cb(); - externalConfigs.insert(externalConfigs.end(), - newExternalConfigs.begin(), - newExternalConfigs.end()); - } - std::cout << "Writing results to: " << configurationFile.string() << "\n"; { std::ofstream istr(configurationFile); @@ -380,44 +422,59 @@ int regenerateCache(const Settings& default_settings, istr << " },\n"; istr << " .externals = {\n"; - for(const auto& externalConfig : externalConfigs) + for(const auto& ext : externalConfigs) { - istr << " { \"" << externalConfig.name << "\", {\n"; + istr << " { \"" << ext.name << "\", {\n"; + Flags resolved_flags; + if(std::holds_alternative(ext.external)) + { + if(auto ret = resolv(settings, ext.name, + std::get(ext.external), + resolved_flags)) + { + return ret; + } + } + else + { + std::cout << "Unknown external type\n"; + return 1; + } - if(!externalConfig.flags.cxxflags.empty()) + if(!resolved_flags.cxxflags.empty()) { istr << " .cxxflags = {"; - for(const auto& flag : externalConfig.flags.cxxflags) + for(const auto& flag : resolved_flags.cxxflags) { istr << "\"" << flag << "\","; } istr << "},\n"; } - if(!externalConfig.flags.cflags.empty()) + if(!resolved_flags.cflags.empty()) { istr << " .cflags = {"; - for(const auto& flag : externalConfig.flags.cflags) + for(const auto& flag : resolved_flags.cflags) { istr << "\"" << flag << "\","; } istr << "},\n"; } - if(!externalConfig.flags.ldflags.empty()) + if(!resolved_flags.ldflags.empty()) { istr << " .ldflags = {"; - for(const auto& flag : externalConfig.flags.ldflags) + for(const auto& flag : resolved_flags.ldflags) { istr << "\"" << flag << "\","; } istr << "},\n"; } - if(!externalConfig.flags.asmflags.empty()) + if(!resolved_flags.asmflags.empty()) { istr << " .asmflags = {"; - for(const auto& flag : externalConfig.flags.asmflags) + for(const auto& flag : resolved_flags.asmflags) { istr << "\"" << flag << "\","; } diff --git a/src/externals.h b/src/externals.h new file mode 100644 index 0000000..7b4aa23 --- /dev/null +++ b/src/externals.h @@ -0,0 +1,6 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#pragma once + +#include "externals_manual.h" diff --git a/src/externals_manual.cc b/src/externals_manual.cc new file mode 100644 index 0000000..afea257 --- /dev/null +++ b/src/externals_manual.cc @@ -0,0 +1,33 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include "externals_manual.h" + +#include + +#include "libctor.h" +#include "settings.h" + +extern std::map external_includedir; +extern std::map external_libdir; + +int resolv(const Settings& settings, const std::string& name, + const ExternalManual& ext, Flags& flags) +{ + flags = ext.flags; + + auto inc = external_includedir.find(name); + if(inc != external_includedir.end()) + { + flags.cflags.push_back("-I" + inc->second); + flags.cxxflags.push_back("-I" + inc->second); + } + + auto lib = external_libdir.find(name); + if(lib != external_libdir.end()) + { + flags.ldflags.push_back("-L" + lib->second); + } + + return 0; +} diff --git a/src/externals_manual.h b/src/externals_manual.h new file mode 100644 index 0000000..c7e3b9a --- /dev/null +++ b/src/externals_manual.h @@ -0,0 +1,13 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#pragma once + +#include + +struct Settings; +struct ExternalManual; +struct Flags; + +int resolv(const Settings& settings, const std::string& name, + const ExternalManual& ext, Flags& flags); diff --git a/src/libctor.h b/src/libctor.h index 0af33cb..721ac6a 100644 --- a/src/libctor.h +++ b/src/libctor.h @@ -7,6 +7,7 @@ #include #include #include +#include enum class TargetType { @@ -70,12 +71,17 @@ using BuildConfigurations = std::vector; int reg(BuildConfigurations (*cb)(), const std::source_location location = std::source_location::current()); +// This type will use flags verbatim +struct ExternalManual +{ + Flags flags; +}; + struct ExternalConfiguration { std::string name; // Name for configuration - Flags flags; - std::vector libs; // libraries + std::variant external; }; using ExternalConfigurations = std::vector; -- cgit v1.2.3