|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fs::path compile_file(fs::path src_path, const build_params& params, const library_manifest& man) { |
|
|
|
|
|
|
|
|
fs::path object_file_path(fs::path source_path, const build_params& params) { |
|
|
auto obj_dir = params.out_root / "obj"; |
|
|
auto obj_dir = params.out_root / "obj"; |
|
|
auto obj_relpath = fs::relative(src_path, params.root); |
|
|
|
|
|
|
|
|
auto obj_relpath = fs::relative(source_path, params.root); |
|
|
obj_relpath.replace_filename(obj_relpath.filename().string() |
|
|
obj_relpath.replace_filename(obj_relpath.filename().string() |
|
|
+ params.toolchain.object_suffix()); |
|
|
+ params.toolchain.object_suffix()); |
|
|
auto obj_path = obj_dir / obj_relpath; |
|
|
auto obj_path = obj_dir / obj_relpath; |
|
|
|
|
|
return obj_path; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fs::path compile_file(fs::path src_path, const build_params& params, const library_manifest& man) { |
|
|
|
|
|
auto obj_path = object_file_path(src_path, params); |
|
|
fs::create_directories(obj_path.parent_path()); |
|
|
fs::create_directories(obj_path.parent_path()); |
|
|
|
|
|
|
|
|
spdlog::info("Compile file: {}", fs::relative(src_path, params.root).string()); |
|
|
spdlog::info("Compile file: {}", fs::relative(src_path, params.root).string()); |
|
|
|
|
|
|
|
|
lm_write_pairs(export_root / "lib.lml", lm_pairs); |
|
|
lm_write_pairs(export_root / "lib.lml", lm_pairs); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fs::path |
|
|
|
|
|
link_test(const fs::path& source_file, const build_params& params, const fs::path& lib_archive) { |
|
|
|
|
|
const auto obj_file = object_file_path(source_file, params); |
|
|
|
|
|
if (!fs::exists(obj_file)) { |
|
|
|
|
|
throw compile_failure( |
|
|
|
|
|
fmt::format("Unable to find a generated test object file where expected ({})", |
|
|
|
|
|
obj_file.string())); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const auto test_name = source_file.stem().stem().string(); |
|
|
|
|
|
link_exe_spec spec; |
|
|
|
|
|
extend(spec.inputs, {obj_file, lib_archive}); |
|
|
|
|
|
spec.output = params.out_root |
|
|
|
|
|
/ fs::relative(source_file, params.root) |
|
|
|
|
|
.replace_filename(test_name + params.toolchain.executable_suffix()); |
|
|
|
|
|
const auto link_command = params.toolchain.create_link_executable_command(spec); |
|
|
|
|
|
|
|
|
|
|
|
spdlog::info("Linking test executable: {}", spec.output.string()); |
|
|
|
|
|
fs::create_directories(spec.output.parent_path()); |
|
|
|
|
|
auto proc_res = run_proc(link_command); |
|
|
|
|
|
if (proc_res.retc != 0) { |
|
|
|
|
|
throw compile_failure( |
|
|
|
|
|
fmt::format("Failed to link executable '{}'. Link command exited {}:\n{}", |
|
|
|
|
|
spec.output.string(), |
|
|
|
|
|
proc_res.retc, |
|
|
|
|
|
proc_res.output)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return spec.output; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<fs::path> link_tests(const source_list& sources, |
|
|
|
|
|
const build_params& params, |
|
|
|
|
|
const library_manifest&, |
|
|
|
|
|
const fs::path& lib_archive) { |
|
|
|
|
|
std::vector<fs::path> exes; |
|
|
|
|
|
for (const auto& source_file : sources) { |
|
|
|
|
|
if (source_file.kind == source_kind::test) { |
|
|
|
|
|
exes.push_back(link_test(source_file.path, params, lib_archive)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return exes; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
std::vector<fs::path> |
|
|
std::vector<fs::path> |
|
|
compile_sources(source_list sources, const build_params& params, const library_manifest& man) { |
|
|
compile_sources(source_list sources, const build_params& params, const library_manifest& man) { |
|
|
// We don't bother with a nice thread pool, as the overhead of compiling |
|
|
// We don't bother with a nice thread pool, as the overhead of compiling |
|
|
|
|
|
|
|
|
arc.out_path = params.out_root |
|
|
arc.out_path = params.out_root |
|
|
/ (fmt::format("lib{}{}", params.export_name, params.toolchain.archive_suffix())); |
|
|
/ (fmt::format("lib{}{}", params.export_name, params.toolchain.archive_suffix())); |
|
|
|
|
|
|
|
|
|
|
|
// Create the static library archive |
|
|
spdlog::info("Create archive {}", arc.out_path.string()); |
|
|
spdlog::info("Create archive {}", arc.out_path.string()); |
|
|
auto ar_cmd = params.toolchain.create_archive_command(arc); |
|
|
auto ar_cmd = params.toolchain.create_archive_command(arc); |
|
|
if (fs::exists(arc.out_path)) { |
|
|
if (fs::exists(arc.out_path)) { |
|
|
|
|
|
|
|
|
throw archive_failure("Failed to create the library archive"); |
|
|
throw archive_failure("Failed to create the library archive"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Link any test executables |
|
|
|
|
|
std::vector<fs::path> test_exes; |
|
|
|
|
|
if (params.build_tests) { |
|
|
|
|
|
test_exes = link_tests(sources, params, man, arc.out_path); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (params.do_export) { |
|
|
if (params.do_export) { |
|
|
generate_export(params, arc.out_path, sources); |
|
|
generate_export(params, arc.out_path, sources); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (params.build_tests) { |
|
|
|
|
|
for (const auto& exe : test_exes) { |
|
|
|
|
|
spdlog::info("Running test: {}", fs::relative(exe, params.out_root).string()); |
|
|
|
|
|
const auto test_res = run_proc({exe.string()}); |
|
|
|
|
|
if (test_res.retc != 0) { |
|
|
|
|
|
spdlog::error("TEST FAILED:\n{}", test_res.output); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
spdlog::info("Test run finished"); |
|
|
|
|
|
} |
|
|
} |
|
|
} |