@@ -24,7 +24,7 @@ void create_archive_plan::archive(const build_env& env) const { | |||
archive_spec ar; | |||
ar.input_files = std::move(objects); | |||
ar.out_path = env.output_root / calc_archive_file_path(env.toolchain); | |||
auto ar_cmd = env.toolchain.create_archive_command(ar, env.knobs); | |||
auto ar_cmd = env.toolchain.create_archive_command(ar, fs::current_path(), env.knobs); | |||
// `out_relpath` is purely for the benefit of the user to have a short name | |||
// in the logs |
@@ -26,7 +26,7 @@ compile_command_info compile_file_plan::generate_compile_command(build_env_ref e | |||
extend(spec.external_include_dirs, env.ureqs.include_paths(use)); | |||
} | |||
extend(spec.definitions, _rules.defs()); | |||
return env.toolchain.create_compile_command(spec, env.knobs); | |||
return env.toolchain.create_compile_command(spec, dds::fs::current_path(), env.knobs); | |||
} | |||
fs::path compile_file_plan::calc_object_file_path(const build_env& env) const noexcept { |
@@ -43,7 +43,8 @@ void link_executable_plan::link(build_env_ref env, const library_plan& lib) cons | |||
std::reverse(spec.inputs.begin(), spec.inputs.end()); | |||
// Do it! | |||
const auto link_command = env.toolchain.create_link_executable_command(spec, env.knobs); | |||
const auto link_command | |||
= env.toolchain.create_link_executable_command(spec, dds::fs::current_path(), env.knobs); | |||
fs::create_directories(spec.output.parent_path()); | |||
auto msg = fmt::format("[{}] Link: {:30}", | |||
lib.qualified_name(), |
@@ -13,30 +13,33 @@ void check_tc_compile(std::string_view tc_content, | |||
auto tc = dds::parse_toolchain_json5(tc_content); | |||
dds::compile_file_spec cf; | |||
cf.source_path = "foo.cpp"; | |||
cf.out_path = "foo.o"; | |||
auto cf_cmd = tc.create_compile_command(cf, dds::toolchain_knobs{}); | |||
cf.source_path = "foo.cpp"; | |||
cf.out_path = "foo.o"; | |||
auto cf_cmd = tc.create_compile_command(cf, dds::fs::current_path(), dds::toolchain_knobs{}); | |||
auto cf_cmd_str = dds::quote_command(cf_cmd.command); | |||
CHECK(cf_cmd_str == expected_compile); | |||
cf.enable_warnings = true; | |||
cf_cmd = tc.create_compile_command(cf, dds::toolchain_knobs{}); | |||
cf_cmd_str = dds::quote_command(cf_cmd.command); | |||
cf_cmd = tc.create_compile_command(cf, dds::fs::current_path(), dds::toolchain_knobs{}); | |||
cf_cmd_str = dds::quote_command(cf_cmd.command); | |||
CHECK(cf_cmd_str == expected_compile_warnings); | |||
dds::archive_spec ar_spec; | |||
ar_spec.input_files.push_back("foo.o"); | |||
ar_spec.input_files.push_back("bar.o"); | |||
ar_spec.out_path = "stuff.a"; | |||
auto ar_cmd = tc.create_archive_command(ar_spec, dds::toolchain_knobs{}); | |||
auto ar_cmd_str = dds::quote_command(ar_cmd); | |||
auto ar_cmd | |||
= tc.create_archive_command(ar_spec, dds::fs::current_path(), dds::toolchain_knobs{}); | |||
auto ar_cmd_str = dds::quote_command(ar_cmd); | |||
CHECK(ar_cmd_str == expected_ar); | |||
dds::link_exe_spec exe_spec; | |||
exe_spec.inputs.push_back("foo.o"); | |||
exe_spec.inputs.push_back("bar.a"); | |||
exe_spec.output = "meow.exe"; | |||
auto exe_cmd = tc.create_link_executable_command(exe_spec, dds::toolchain_knobs{}); | |||
auto exe_cmd = tc.create_link_executable_command(exe_spec, | |||
dds::fs::current_path(), | |||
dds::toolchain_knobs{}); | |||
auto exe_cmd_str = dds::quote_command(exe_cmd); | |||
CHECK(exe_cmd_str == expected_exe); | |||
} | |||
@@ -93,7 +96,7 @@ TEST_CASE("Manipulate a toolchain and file compilation") { | |||
dds::compile_file_spec cfs; | |||
cfs.source_path = "foo.cpp"; | |||
cfs.out_path = "foo.o"; | |||
auto cmd = tc.create_compile_command(cfs, dds::toolchain_knobs{}); | |||
auto cmd = tc.create_compile_command(cfs, dds::fs::current_path(), dds::toolchain_knobs{}); | |||
CHECK(cmd.command | |||
== std::vector<std::string>{"g++", | |||
"-fPIC", | |||
@@ -108,7 +111,9 @@ TEST_CASE("Manipulate a toolchain and file compilation") { | |||
"-ofoo.o"}); | |||
cfs.definitions.push_back("FOO=BAR"); | |||
cmd = tc.create_compile_command(cfs, dds::toolchain_knobs{.is_tty = true}); | |||
cmd = tc.create_compile_command(cfs, | |||
dds::fs::current_path(), | |||
dds::toolchain_knobs{.is_tty = true}); | |||
CHECK(cmd.command | |||
== std::vector<std::string>{"g++", | |||
"-fPIC", | |||
@@ -126,7 +131,7 @@ TEST_CASE("Manipulate a toolchain and file compilation") { | |||
"-ofoo.o"}); | |||
cfs.include_dirs.push_back("fake-dir"); | |||
cmd = tc.create_compile_command(cfs, dds::toolchain_knobs{}); | |||
cmd = tc.create_compile_command(cfs, dds::fs::current_path(), dds::toolchain_knobs{}); | |||
CHECK(cmd.command | |||
== std::vector<std::string>{"g++", | |||
"-fPIC", |
@@ -6,6 +6,8 @@ | |||
#include <dds/util/paths.hpp> | |||
#include <dds/util/string.hpp> | |||
#include <range/v3/view/transform.hpp> | |||
#include <cassert> | |||
#include <optional> | |||
#include <string> | |||
@@ -52,7 +54,25 @@ vector<string> toolchain::definition_args(std::string_view s) const noexcept { | |||
return replace(_def_template, "[def]", s); | |||
} | |||
static fs::path shortest_path_from(path_ref file, path_ref base) { | |||
auto relative = file.lexically_normal().lexically_proximate(base); | |||
auto abs = file.lexically_normal(); | |||
if (relative.string().size() > abs.string().size()) { | |||
return abs; | |||
} else { | |||
return relative; | |||
} | |||
} | |||
template <typename R> | |||
static auto shortest_path_args(path_ref base, R&& r) { | |||
return ranges::views::all(r) // | |||
| ranges::views::transform( | |||
[base](auto&& path) { return shortest_path_from(path, base).string(); }); // | |||
} | |||
compile_command_info toolchain::create_compile_command(const compile_file_spec& spec, | |||
path_ref, | |||
toolchain_knobs knobs) const noexcept { | |||
using namespace std::literals; | |||
@@ -119,32 +139,30 @@ compile_command_info toolchain::create_compile_command(const compile_file_spec& | |||
} | |||
vector<string> toolchain::create_archive_command(const archive_spec& spec, | |||
path_ref cwd, | |||
toolchain_knobs) const noexcept { | |||
vector<string> cmd; | |||
auto out_arg = shortest_path_from(spec.out_path, cwd).string(); | |||
for (auto& arg : _link_archive) { | |||
if (arg == "[in]") { | |||
std::transform(spec.input_files.begin(), | |||
spec.input_files.end(), | |||
std::back_inserter(cmd), | |||
[](auto&& p) { return p.string(); }); | |||
extend(cmd, shortest_path_args(cwd, spec.input_files)); | |||
} else { | |||
cmd.push_back(replace(arg, "[out]", spec.out_path.string())); | |||
cmd.push_back(replace(arg, "[out]", out_arg)); | |||
} | |||
} | |||
return cmd; | |||
} | |||
vector<string> toolchain::create_link_executable_command(const link_exe_spec& spec, | |||
path_ref cwd, | |||
toolchain_knobs) const noexcept { | |||
vector<string> cmd; | |||
for (auto& arg : _link_exe) { | |||
if (arg == "[in]") { | |||
std::transform(spec.inputs.begin(), | |||
spec.inputs.end(), | |||
std::back_inserter(cmd), | |||
[](auto&& p) { return p.string(); }); | |||
extend(cmd, shortest_path_args(cwd, spec.inputs)); | |||
} else { | |||
cmd.push_back(replace(arg, "[out]", spec.output.string())); | |||
cmd.push_back(replace(arg, "[out]", shortest_path_from(spec.output, cwd).string())); | |||
} | |||
} | |||
return cmd; |
@@ -82,11 +82,15 @@ public: | |||
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> external_include_args(const fs::path& p) const noexcept; | |||
compile_command_info create_compile_command(const compile_file_spec&, | |||
toolchain_knobs) const noexcept; | |||
std::vector<std::string> create_archive_command(const archive_spec&, | |||
toolchain_knobs) const noexcept; | |||
compile_command_info | |||
create_compile_command(const compile_file_spec&, path_ref cwd, toolchain_knobs) const noexcept; | |||
std::vector<std::string> | |||
create_archive_command(const archive_spec&, path_ref cwd, toolchain_knobs) const noexcept; | |||
std::vector<std::string> create_link_executable_command(const link_exe_spec&, | |||
path_ref cwd, | |||
toolchain_knobs) const noexcept; | |||
static std::optional<toolchain> get_builtin(std::string_view key) noexcept; |