spec.enable_warnings = _rules.enable_warnings(); | spec.enable_warnings = _rules.enable_warnings(); | ||||
extend(spec.include_dirs, _rules.include_dirs()); | extend(spec.include_dirs, _rules.include_dirs()); | ||||
for (const auto& use : _rules.uses()) { | for (const auto& use : _rules.uses()) { | ||||
extend(spec.include_dirs, env.ureqs.include_paths(use)); | |||||
extend(spec.external_include_dirs, env.ureqs.include_paths(use)); | |||||
} | } | ||||
extend(spec.definitions, _rules.defs()); | extend(spec.definitions, _rules.defs()); | ||||
return env.toolchain.create_compile_command(spec); | return env.toolchain.create_compile_command(spec); |
optional<bool> do_debug; | optional<bool> do_debug; | ||||
optional<bool> do_optimize; | optional<bool> do_optimize; | ||||
opt_str_seq include_template; | opt_str_seq include_template; | ||||
opt_str_seq external_include_template; | |||||
opt_str_seq define_template; | opt_str_seq define_template; | ||||
opt_str_seq warning_flags; | opt_str_seq warning_flags; | ||||
opt_str_seq flags; | opt_str_seq flags; | ||||
lm::read_opt("C++-Version", cxx_version), | lm::read_opt("C++-Version", cxx_version), | ||||
// Flag templates | // Flag templates | ||||
read_argv{"Include-Template", include_template}, | read_argv{"Include-Template", include_template}, | ||||
read_argv{"External-Include-Template", include_template}, | |||||
read_argv{"Define-Template", define_template}, | read_argv{"Define-Template", define_template}, | ||||
// Flags | // Flags | ||||
read_argv_acc{"Warning-Flags", warning_flags}, | read_argv_acc{"Warning-Flags", warning_flags}, | ||||
std::terminate(); | std::terminate(); | ||||
}); | }); | ||||
tc.external_include_template = read_opt(external_include_template, [&]() -> string_seq { | |||||
if (!compiler_id) { | |||||
// Just reuse the include template for regular files | |||||
return tc.include_template; | |||||
} | |||||
if (is_gnu_like) { | |||||
return {"-isystem", "<PATH>"}; | |||||
} else if (is_msvc) { | |||||
// MSVC has external-header support inbound, but it is not fully ready yet | |||||
return {"/I", "<PATH>"}; | |||||
} | |||||
assert(false && "External-Include-Template deduction failed"); | |||||
std::terminate(); | |||||
}); | |||||
tc.define_template = read_opt(define_template, [&]() -> string_seq { | tc.define_template = read_opt(define_template, [&]() -> string_seq { | ||||
if (!compiler_id) { | if (!compiler_id) { | ||||
fail(context, "Cannot deduce 'Define-Template' without 'Compiler-ID'"); | fail(context, "Cannot deduce 'Define-Template' without 'Compiler-ID'"); |
string_seq c_compile; | string_seq c_compile; | ||||
string_seq cxx_compile; | string_seq cxx_compile; | ||||
string_seq include_template; | string_seq include_template; | ||||
string_seq external_include_template; | |||||
string_seq define_template; | string_seq define_template; | ||||
string_seq link_archive; | string_seq link_archive; | ||||
string_seq link_exe; | string_seq link_exe; |
toolchain toolchain::realize(const toolchain_prep& prep) { | toolchain toolchain::realize(const toolchain_prep& prep) { | ||||
toolchain ret; | toolchain ret; | ||||
ret._c_compile = prep.c_compile; | |||||
ret._cxx_compile = prep.cxx_compile; | |||||
ret._inc_template = prep.include_template; | |||||
ret._def_template = prep.define_template; | |||||
ret._link_archive = prep.link_archive; | |||||
ret._link_exe = prep.link_exe; | |||||
ret._warning_flags = prep.warning_flags; | |||||
ret._archive_prefix = prep.archive_prefix; | |||||
ret._archive_suffix = prep.archive_suffix; | |||||
ret._object_prefix = prep.object_prefix; | |||||
ret._object_suffix = prep.object_suffix; | |||||
ret._exe_prefix = prep.exe_prefix; | |||||
ret._exe_suffix = prep.exe_suffix; | |||||
ret._deps_mode = prep.deps_mode; | |||||
ret._c_compile = prep.c_compile; | |||||
ret._cxx_compile = prep.cxx_compile; | |||||
ret._inc_template = prep.include_template; | |||||
ret._extern_inc_template = prep.external_include_template; | |||||
ret._def_template = prep.define_template; | |||||
ret._link_archive = prep.link_archive; | |||||
ret._link_exe = prep.link_exe; | |||||
ret._warning_flags = prep.warning_flags; | |||||
ret._archive_prefix = prep.archive_prefix; | |||||
ret._archive_suffix = prep.archive_suffix; | |||||
ret._object_prefix = prep.object_prefix; | |||||
ret._object_suffix = prep.object_suffix; | |||||
ret._exe_prefix = prep.exe_prefix; | |||||
ret._exe_suffix = prep.exe_suffix; | |||||
ret._deps_mode = prep.deps_mode; | |||||
return ret; | return ret; | ||||
} | } | ||||
return replace(_inc_template, "<PATH>", p.string()); | return replace(_inc_template, "<PATH>", p.string()); | ||||
} | } | ||||
vector<string> toolchain::external_include_args(const fs::path& p) const noexcept { | |||||
return replace(_extern_inc_template, "<PATH>", p.string()); | |||||
} | |||||
vector<string> toolchain::definition_args(std::string_view s) const noexcept { | vector<string> toolchain::definition_args(std::string_view s) const noexcept { | ||||
return replace(_def_template, "<DEF>", s); | return replace(_def_template, "<DEF>", s); | ||||
} | } | ||||
extend(flags, inc_args); | extend(flags, inc_args); | ||||
} | } | ||||
for (auto&& ext_inc_dir : spec.external_include_dirs) { | |||||
auto inc_args = external_include_args(ext_inc_dir); | |||||
extend(flags, inc_args); | |||||
} | |||||
for (auto&& def : spec.definitions) { | for (auto&& def : spec.definitions) { | ||||
auto def_args = definition_args(def); | auto def_args = definition_args(def); | ||||
extend(flags, def_args); | extend(flags, def_args); |
fs::path out_path; | fs::path out_path; | ||||
std::vector<std::string> definitions = {}; | std::vector<std::string> definitions = {}; | ||||
std::vector<fs::path> include_dirs = {}; | std::vector<fs::path> include_dirs = {}; | ||||
language lang = language::automatic; | |||||
std::vector<fs::path> external_include_dirs = {}; | |||||
language lang = language::automatic; | |||||
bool enable_warnings = false; | bool enable_warnings = false; | ||||
}; | }; | ||||
string_seq _c_compile; | string_seq _c_compile; | ||||
string_seq _cxx_compile; | string_seq _cxx_compile; | ||||
string_seq _inc_template; | string_seq _inc_template; | ||||
string_seq _extern_inc_template; | |||||
string_seq _def_template; | string_seq _def_template; | ||||
string_seq _link_archive; | string_seq _link_archive; | ||||
string_seq _link_exe; | string_seq _link_exe; | ||||
std::vector<std::string> definition_args(std::string_view s) const noexcept; | std::vector<std::string> definition_args(std::string_view s) const noexcept; | ||||
std::vector<std::string> include_args(const fs::path& p) const noexcept; | std::vector<std::string> include_args(const fs::path& p) const noexcept; | ||||
std::vector<std::string> external_include_args(const fs::path& p) const noexcept; | |||||
compile_command_info create_compile_command(const compile_file_spec&) const noexcept; | compile_command_info create_compile_command(const compile_file_spec&) const noexcept; | ||||
std::vector<std::string> create_archive_command(const archive_spec&) const noexcept; | std::vector<std::string> create_archive_command(const archive_spec&) const noexcept; | ||||
std::vector<std::string> create_link_executable_command(const link_exe_spec&) const noexcept; | std::vector<std::string> create_link_executable_command(const link_exe_spec&) const noexcept; |