Browse Source

Generate cmdlines using the shortest input paths relative to the cwd

default_compile_flags
vector-of-bool 4 years ago
parent
commit
2c6cd6df24
6 changed files with 56 additions and 28 deletions
  1. +1
    -1
      src/dds/build/plan/archive.cpp
  2. +1
    -1
      src/dds/build/plan/compile_file.cpp
  3. +2
    -1
      src/dds/build/plan/exe.cpp
  4. +16
    -11
      src/dds/toolchain/from_json.test.cpp
  5. +28
    -10
      src/dds/toolchain/toolchain.cpp
  6. +8
    -4
      src/dds/toolchain/toolchain.hpp

+ 1
- 1
src/dds/build/plan/archive.cpp View File

archive_spec ar; archive_spec ar;
ar.input_files = std::move(objects); ar.input_files = std::move(objects);
ar.out_path = env.output_root / calc_archive_file_path(env.toolchain); 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 // `out_relpath` is purely for the benefit of the user to have a short name
// in the logs // in the logs

+ 1
- 1
src/dds/build/plan/compile_file.cpp View File

extend(spec.external_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, 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 { fs::path compile_file_plan::calc_object_file_path(const build_env& env) const noexcept {

+ 2
- 1
src/dds/build/plan/exe.cpp View File

std::reverse(spec.inputs.begin(), spec.inputs.end()); std::reverse(spec.inputs.begin(), spec.inputs.end());


// Do it! // 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()); fs::create_directories(spec.output.parent_path());
auto msg = fmt::format("[{}] Link: {:30}", auto msg = fmt::format("[{}] Link: {:30}",
lib.qualified_name(), lib.qualified_name(),

+ 16
- 11
src/dds/toolchain/from_json.test.cpp View File

auto tc = dds::parse_toolchain_json5(tc_content); auto tc = dds::parse_toolchain_json5(tc_content);


dds::compile_file_spec cf; 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); auto cf_cmd_str = dds::quote_command(cf_cmd.command);
CHECK(cf_cmd_str == expected_compile); CHECK(cf_cmd_str == expected_compile);


cf.enable_warnings = true; 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); CHECK(cf_cmd_str == expected_compile_warnings);


dds::archive_spec ar_spec; dds::archive_spec ar_spec;
ar_spec.input_files.push_back("foo.o"); ar_spec.input_files.push_back("foo.o");
ar_spec.input_files.push_back("bar.o"); ar_spec.input_files.push_back("bar.o");
ar_spec.out_path = "stuff.a"; 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); CHECK(ar_cmd_str == expected_ar);


dds::link_exe_spec exe_spec; dds::link_exe_spec exe_spec;
exe_spec.inputs.push_back("foo.o"); exe_spec.inputs.push_back("foo.o");
exe_spec.inputs.push_back("bar.a"); exe_spec.inputs.push_back("bar.a");
exe_spec.output = "meow.exe"; 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); auto exe_cmd_str = dds::quote_command(exe_cmd);
CHECK(exe_cmd_str == expected_exe); CHECK(exe_cmd_str == expected_exe);
} }
dds::compile_file_spec cfs; dds::compile_file_spec cfs;
cfs.source_path = "foo.cpp"; cfs.source_path = "foo.cpp";
cfs.out_path = "foo.o"; 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 CHECK(cmd.command
== std::vector<std::string>{"g++", == std::vector<std::string>{"g++",
"-fPIC", "-fPIC",
"-ofoo.o"}); "-ofoo.o"});


cfs.definitions.push_back("FOO=BAR"); 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 CHECK(cmd.command
== std::vector<std::string>{"g++", == std::vector<std::string>{"g++",
"-fPIC", "-fPIC",
"-ofoo.o"}); "-ofoo.o"});


cfs.include_dirs.push_back("fake-dir"); 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 CHECK(cmd.command
== std::vector<std::string>{"g++", == std::vector<std::string>{"g++",
"-fPIC", "-fPIC",

+ 28
- 10
src/dds/toolchain/toolchain.cpp View File

#include <dds/util/paths.hpp> #include <dds/util/paths.hpp>
#include <dds/util/string.hpp> #include <dds/util/string.hpp>


#include <range/v3/view/transform.hpp>

#include <cassert> #include <cassert>
#include <optional> #include <optional>
#include <string> #include <string>
return replace(_def_template, "[def]", s); 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, compile_command_info toolchain::create_compile_command(const compile_file_spec& spec,
path_ref,
toolchain_knobs knobs) const noexcept { toolchain_knobs knobs) const noexcept {
using namespace std::literals; using namespace std::literals;


} }


vector<string> toolchain::create_archive_command(const archive_spec& spec, vector<string> toolchain::create_archive_command(const archive_spec& spec,
path_ref cwd,
toolchain_knobs) const noexcept { toolchain_knobs) const noexcept {
vector<string> cmd; vector<string> cmd;

auto out_arg = shortest_path_from(spec.out_path, cwd).string();
for (auto& arg : _link_archive) { for (auto& arg : _link_archive) {
if (arg == "[in]") { 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 { } else {
cmd.push_back(replace(arg, "[out]", spec.out_path.string()));
cmd.push_back(replace(arg, "[out]", out_arg));
} }
} }
return cmd; return cmd;
} }


vector<string> toolchain::create_link_executable_command(const link_exe_spec& spec, vector<string> toolchain::create_link_executable_command(const link_exe_spec& spec,
path_ref cwd,
toolchain_knobs) const noexcept { toolchain_knobs) const noexcept {
vector<string> cmd; vector<string> cmd;
for (auto& arg : _link_exe) { for (auto& arg : _link_exe) {
if (arg == "[in]") { 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 { } 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; return cmd;

+ 8
- 4
src/dds/toolchain/toolchain.hpp View File

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; 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&, std::vector<std::string> create_link_executable_command(const link_exe_spec&,
path_ref cwd,
toolchain_knobs) const noexcept; toolchain_knobs) const noexcept;


static std::optional<toolchain> get_builtin(std::string_view key) noexcept; static std::optional<toolchain> get_builtin(std::string_view key) noexcept;

Loading…
Cancel
Save