// -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. #pragma once #include #include #include #include enum class TargetType { Auto, // Default - deduce from target name and sources extensions Executable, StaticLibrary, DynamicLibrary, Object, UnitTest, }; enum class Language { Auto, // Default - deduce language from source extensions C, Cpp, Asm, }; enum class OutputSystem { Host, // Output for the target system Build, // Internal tool during cross-compilation }; struct Source { Source(const char* file) : file(file) {} Source(const std::string& file) : file(file) {} Source(const char* file, Language lang) : file(file), language(lang) {} Source(const std::string& file, Language lang) : file(file), language(lang) {} std::string file; Language language{Language::Auto}; }; struct Flags { std::vector cxxflags; // flags for c++ compiler std::vector cflags; // flags for c compiler std::vector ldflags; // flags for linker std::vector asmflags; // flags for asm translator }; struct BuildConfiguration { std::string name; // Name - used for referring in other configurations. TargetType type{TargetType::Auto}; OutputSystem system{OutputSystem::Host}; std::string target; // Output target file for this configuration std::vector sources; // source list std::vector depends; // internal target dependencies Flags flags; std::vector externals; // externals used by this configuration }; using BuildConfigurations = std::vector; int reg(BuildConfigurations (*cb)(), const std::source_location location = std::source_location::current()); struct ExternalConfiguration { std::string name; // Name for configuration Flags flags; std::vector libs; // libraries }; using ExternalConfigurations = std::vector; int reg(ExternalConfigurations (*cb)(), const std::source_location location = std::source_location::current()); // Convenience macro - ugly but keeps things simple(r) #define CONCAT(a, b) CONCAT_INNER(a, b) #define CONCAT_INNER(a, b) a ## b #define UNIQUE_NAME(base) CONCAT(base, __LINE__) #define REG(cb) namespace { int UNIQUE_NAME(unique) = reg(cb); } // Predefined configuration keys namespace cfg { constexpr auto builddir = "builddir"; constexpr auto host_cc = "host-cc"; 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"; constexpr auto ctor_includedir = "ctor-includedir"; constexpr auto ctor_libdir = "ctor-libdir"; } struct Configuration { std::vector args; // vector of arguments used when last calling configure std::map env; // env used when last calling configure std::map tools; // tools std::map externals; }; const Configuration& configuration(); bool hasConfiguration(const std::string& key); const std::string& getConfiguration(const std::string& key, const std::string& defaultValue = {});