| return parse_toolchain_dds(kvs, context); | return parse_toolchain_dds(kvs, context); | ||||
| } | } | ||||
| namespace { | |||||
| struct read_argv_acc { | struct read_argv_acc { | ||||
| strv my_key; | strv my_key; | ||||
| opt_str_seq& out; | opt_str_seq& out; | ||||
| return *what; | return *what; | ||||
| } | } | ||||
| template <typename... Args> | |||||
| [[noreturn]] void fail(strv context, strv message, Args&&... args) { | |||||
| throw std::runtime_error( | |||||
| format("{} - Failed to read toolchain file: {}", context, message, args...)); | |||||
| } | |||||
| } // namespace | |||||
| toolchain dds::parse_toolchain_dds(const lm::pair_list& pairs, strv context) { | toolchain dds::parse_toolchain_dds(const lm::pair_list& pairs, strv context) { | ||||
| opt_string compiler_id; | opt_string compiler_id; | ||||
| opt_string c_compiler_fpath; | opt_string c_compiler_fpath; | ||||
| toolchain_prep tc; | toolchain_prep tc; | ||||
| auto fail = [&](auto msg, auto... args)[[noreturn]]->void { | |||||
| throw std::runtime_error( | |||||
| format("{}: Failed to generate toolchain: {}", context, msg, args...)); | |||||
| }; | |||||
| enum compiler_id_e_t { | enum compiler_id_e_t { | ||||
| no_comp_id, | no_comp_id, | ||||
| msvc, | msvc, | ||||
| } else if (compiler_id == "Clang") { | } else if (compiler_id == "Clang") { | ||||
| return clang; | return clang; | ||||
| } else { | } else { | ||||
| fail("Unknown Compiler-ID '{}'", *compiler_id); | |||||
| fail(context, "Unknown Compiler-ID '{}'", *compiler_id); | |||||
| } | } | ||||
| }(); | }(); | ||||
| return *c_compiler_fpath; | return *c_compiler_fpath; | ||||
| } | } | ||||
| if (!compiler_id.has_value()) { | if (!compiler_id.has_value()) { | ||||
| fail("Unable to determine what compiler to use."); | |||||
| fail(context, "Unable to determine what compiler to use."); | |||||
| } | } | ||||
| if (is_gnu) { | if (is_gnu) { | ||||
| return is_cxx ? "g++" : "gcc"; | return is_cxx ? "g++" : "gcc"; | ||||
| } else if (c_version == "c18") { | } else if (c_version == "c18") { | ||||
| return c18; | return c18; | ||||
| } else { | } else { | ||||
| fail("Unknown C-Version '{}'", *c_version); | |||||
| fail(context, "Unknown C-Version '{}'", *c_version); | |||||
| } | } | ||||
| }(); | }(); | ||||
| } else if (cxx_version == "c++20") { | } else if (cxx_version == "c++20") { | ||||
| return cxx20; | return cxx20; | ||||
| } else { | } else { | ||||
| fail("Unknown C++-Version '{}'", *cxx_version); | |||||
| fail(context, "Unknown C++-Version '{}'", *cxx_version); | |||||
| } | } | ||||
| }(); | }(); | ||||
| auto get_c_version_flags = [&]() -> string_seq { | auto get_c_version_flags = [&]() -> string_seq { | ||||
| if (!compiler_id.has_value()) { | if (!compiler_id.has_value()) { | ||||
| fail("Unable to deduce flags for 'C-Version' without setting 'Compiler-ID'"); | |||||
| fail(context, "Unable to deduce flags for 'C-Version' without setting 'Compiler-ID'"); | |||||
| } | } | ||||
| auto c_ver_iter = c_version_flag_table.find({compiler_id_e, c_version_e}); | auto c_ver_iter = c_version_flag_table.find({compiler_id_e, c_version_e}); | ||||
| assert(c_ver_iter != c_version_flag_table.end()); | assert(c_ver_iter != c_version_flag_table.end()); | ||||
| auto get_cxx_version_flags = [&]() -> string_seq { | auto get_cxx_version_flags = [&]() -> string_seq { | ||||
| if (!compiler_id.has_value()) { | if (!compiler_id.has_value()) { | ||||
| fail("Unable to deduce flags for 'C++-Version' without setting 'Compiler-ID'"); | |||||
| fail(context, "Unable to deduce flags for 'C++-Version' without setting 'Compiler-ID'"); | |||||
| } | } | ||||
| auto cxx_ver_iter = cxx_version_flag_table.find({compiler_id_e, cxx_version_e}); | auto cxx_ver_iter = cxx_version_flag_table.find({compiler_id_e, cxx_version_e}); | ||||
| assert(cxx_ver_iter != cxx_version_flag_table.end()); | assert(cxx_ver_iter != cxx_version_flag_table.end()); | ||||
| tc.include_template = read_opt(include_template, [&]() -> string_seq { | tc.include_template = read_opt(include_template, [&]() -> string_seq { | ||||
| if (!compiler_id) { | if (!compiler_id) { | ||||
| fail("Cannot deduce 'Include-Template' without 'Compiler-ID'"); | |||||
| fail(context, "Cannot deduce 'Include-Template' without 'Compiler-ID'"); | |||||
| } | } | ||||
| if (is_gnu_like) { | if (is_gnu_like) { | ||||
| return {"-I", "<PATH>"}; | return {"-I", "<PATH>"}; | ||||
| 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("Cannot deduce 'Define-Template' without 'Compiler-ID'"); | |||||
| fail(context, "Cannot deduce 'Define-Template' without 'Compiler-ID'"); | |||||
| } | } | ||||
| if (is_gnu_like) { | if (is_gnu_like) { | ||||
| return {"-D", "<DEF>"}; | return {"-D", "<DEF>"}; | ||||
| tc.archive_prefix = archive_prefix.value_or("lib"); | tc.archive_prefix = archive_prefix.value_or("lib"); | ||||
| tc.archive_suffix = read_opt(archive_suffix, [&] { | tc.archive_suffix = read_opt(archive_suffix, [&] { | ||||
| if (!compiler_id) { | if (!compiler_id) { | ||||
| fail("Cannot deduce library file extension without Compiler-ID"); | |||||
| fail(context, "Cannot deduce library file extension without Compiler-ID"); | |||||
| } | } | ||||
| if (is_gnu) { | if (is_gnu) { | ||||
| return ".a"; | return ".a"; | ||||
| tc.object_prefix = obj_prefix.value_or(""); | tc.object_prefix = obj_prefix.value_or(""); | ||||
| tc.object_suffix = read_opt(obj_suffix, [&] { | tc.object_suffix = read_opt(obj_suffix, [&] { | ||||
| if (!compiler_id) { | if (!compiler_id) { | ||||
| fail("Cannot deduce object file extension without Compiler-ID"); | |||||
| fail(context, "Cannot deduce object file extension without Compiler-ID"); | |||||
| } | } | ||||
| if (is_gnu) { | if (is_gnu) { | ||||
| return ".o"; | return ".o"; | ||||
| tc.link_archive = read_opt(create_archive, [&]() -> string_seq { | tc.link_archive = read_opt(create_archive, [&]() -> string_seq { | ||||
| if (!compiler_id) { | if (!compiler_id) { | ||||
| fail("Unable to deduce archive creation rules without a Compiler-ID"); | |||||
| fail(context, "Unable to deduce archive creation rules without a Compiler-ID"); | |||||
| } | } | ||||
| if (is_msvc) { | if (is_msvc) { | ||||
| return {"lib", "/nologo", "/OUT:<OUT>", "<IN>"}; | return {"lib", "/nologo", "/OUT:<OUT>", "<IN>"}; | ||||
| tc.link_exe = read_opt(link_executable, [&]() -> string_seq { | tc.link_exe = read_opt(link_executable, [&]() -> string_seq { | ||||
| if (!compiler_id) { | if (!compiler_id) { | ||||
| fail("Unable to deduce how to link executables without a Compiler-ID"); | |||||
| fail(context, "Unable to deduce how to link executables without a Compiler-ID"); | |||||
| } | } | ||||
| if (is_msvc) { | if (is_msvc) { | ||||
| return {get_compiler(true), "/nologo", "/EHsc", "<IN>", "/Fe<OUT>"}; | return {get_compiler(true), "/nologo", "/EHsc", "<IN>", "/Fe<OUT>"}; |