浏览代码

Support for building applications

default_compile_flags
vector-of-bool 5 年前
父节点
当前提交
579f82d07e
共有 4 个文件被更改,包括 61 次插入16 次删除
  1. +2
    -1
      manifest.dds
  2. +55
    -14
      src/dds/build.cpp
  3. +1
    -0
      src/dds/build.hpp
  4. +3
    -1
      src/dds/ddslim.main.cpp

+ 2
- 1
manifest.dds 查看文件

@@ -1,3 +1,4 @@
Private-Include: external/spdlog/include
Private-Include: external/wil/include
Private-Define: FMT_HEADER_ONLY=1
Private-Include: external/taywee-args/include
Private-Define: FMT_HEADER_ONLY=1

+ 55
- 14
src/dds/build.cpp 查看文件

@@ -132,11 +132,7 @@ fs::path compile_file(fs::path src_path, const build_params& params, const libra
auto compile_res = run_proc(cmd);
if (!compile_res.okay()) {
spdlog::error("Compilation failed: {}", spec.source_path.string());
std::stringstream strm;
for (auto& arg : cmd) {
strm << std::quoted(arg) << ' ';
}
spdlog::error("Subcommand FAILED: {}\n{}", strm.str(), compile_res.output);
spdlog::error("Subcommand FAILED: {}\n{}", quote_command(cmd), compile_res.output);
throw compile_failure("Compilation failed.");
}

@@ -221,8 +217,9 @@ link_test(const fs::path& source_file, const build_params& params, const fs::pat
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{}",
fmt::format("Failed to link test executable '{}'. Link command [{}] returned {}:\n{}",
spec.output.string(),
quote_command(link_command),
proc_res.retc,
proc_res.output));
}
@@ -230,6 +227,35 @@ link_test(const fs::path& source_file, const build_params& params, const fs::pat
return spec.output;
}

void link_app(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 app object file where expected ({})",
obj_file.string()));
}

const auto app_name = source_file.stem().stem().string();
link_exe_spec spec;
extend(spec.inputs, {obj_file, lib_archive});
spec.output = params.out_root / (app_name + params.toolchain.executable_suffix() + ".tmp");
const auto link_command = params.toolchain.create_link_executable_command(spec);

spdlog::info("Linking application executable: {}", spec.output.string());
auto proc_res = run_proc(link_command);
if (proc_res.retc != 0) {
throw compile_failure(fmt::format(
"Failed to link application executable '{}'. Link command [{}] returned {}:\n{}",
spec.output.string(),
quote_command(link_command),
proc_res.retc,
proc_res.output));
}
fs::rename(spec.output, spec.output.parent_path() / spec.output.stem());
}

std::vector<fs::path> link_tests(const source_list& sources,
const build_params& params,
const library_manifest&,
@@ -243,6 +269,16 @@ std::vector<fs::path> link_tests(const source_list& sources,
return exes;
}

void link_apps(const source_list& sources,
const build_params& params,
const fs::path& lib_archive) {
for (const auto& source_file : sources) {
if (source_file.kind == source_kind::app) {
link_app(source_file.path, params, lib_archive);
}
}
}

std::vector<fs::path>
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
@@ -263,7 +299,10 @@ compile_sources(source_list sources, const build_params& params, const library_m
}
auto source = sources.back();
sources.pop_back();
if (source.kind == source_kind::header || source.kind == source_kind::app) {
if (source.kind == source_kind::header) {
continue;
}
if (source.kind == source_kind::app && !params.build_apps) {
continue;
}
if (source.kind == source_kind::test && !params.build_tests) {
@@ -272,8 +311,10 @@ compile_sources(source_list sources, const build_params& params, const library_m
lk.unlock();
try {
auto obj_path = compile_file(source.path, params, man);
lk.lock();
objects.emplace_back(std::move(obj_path));
if (source.kind == source_kind::source) {
lk.lock();
objects.emplace_back(std::move(obj_path));
}
} catch (...) {
lk.lock();
exceptions.push_back(std::current_exception());
@@ -358,11 +399,7 @@ void dds::build(const build_params& params, const library_manifest& man) {
auto ar_res = run_proc(ar_cmd);
if (!ar_res.okay()) {
spdlog::error("Failure creating archive library {}", arc.out_path);
std::stringstream strm;
for (auto& arg : ar_cmd) {
strm << std::quoted(arg) << ' ';
}
spdlog::error("Subcommand failed: {}", strm.str());
spdlog::error("Subcommand failed: {}", quote_command(ar_cmd));
spdlog::error("Subcommand produced output:\n{}", ar_res.output);
throw archive_failure("Failed to create the library archive");
}
@@ -373,6 +410,10 @@ void dds::build(const build_params& params, const library_manifest& man) {
test_exes = link_tests(sources, params, man, arc.out_path);
}

if (params.build_apps) {
link_apps(sources, params, arc.out_path);
}

if (params.do_export) {
generate_export(params, arc.out_path, sources);
}

+ 1
- 0
src/dds/build.hpp 查看文件

@@ -17,6 +17,7 @@ struct build_params {
bool do_export = false;
bool build_tests = false;
bool enable_warnings = false;
bool build_apps = false;
int parallel_jobs = 0;
};


+ 3
- 1
src/dds/ddslim.main.cpp 查看文件

@@ -50,7 +50,8 @@ struct cli_build {
(dds::fs::current_path() / "toolchain.dds").string()};

args::Flag build_tests{cmd, "build_tests", "Build the tests", {"tests", 't'}};
args::Flag export_{cmd, "export_dir", "Generate a library export", {"export", 'E'}};
args::Flag build_apps{cmd, "build_apps", "Build applications", {"apps", 'A'}};
args::Flag export_{cmd, "export", "Generate a library export", {"export", 'E'}};

args::Flag enable_warnings{cmd,
"enable_warnings",
@@ -86,6 +87,7 @@ struct cli_build {
params.toolchain = _get_toolchain();
params.do_export = export_.Get();
params.build_tests = build_tests.Get();
params.build_apps = build_apps.Get();
params.enable_warnings = enable_warnings.Get();
params.parallel_jobs = num_jobs.Get();
dds::library_manifest man;

正在加载...
取消
保存