@@ -1,6 +1,7 @@ | |||
#include "./archive.hpp" | |||
#include <dds/proc.hpp> | |||
#include <dds/util/time.hpp> | |||
#include <range/v3/view/transform.hpp> | |||
#include <spdlog/spdlog.h> | |||
@@ -27,10 +28,7 @@ void create_archive_plan::archive(const build_env& env) const { | |||
} | |||
spdlog::info("[{}] Archive: {}", _name, out_relpath); | |||
auto start_time = std::chrono::steady_clock::now(); | |||
auto ar_res = run_proc(ar_cmd); | |||
auto end_time = std::chrono::steady_clock::now(); | |||
auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time); | |||
auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>([&] { return run_proc(ar_cmd); }); | |||
spdlog::info("[{}] Archive: {} - {:n}ms", _name, out_relpath, dur_ms.count()); | |||
if (!ar_res.okay()) { |
@@ -3,6 +3,7 @@ | |||
#include <dds/proc.hpp> | |||
#include <dds/util/algo.hpp> | |||
#include <dds/util/signal.hpp> | |||
#include <dds/util/time.hpp> | |||
#include <spdlog/spdlog.h> | |||
@@ -29,14 +30,8 @@ void compile_file_plan::compile(const build_env& env) const { | |||
fs::relative(_source.path, _source.basis_path).string()); | |||
spdlog::info(msg); | |||
auto start_time = std::chrono::steady_clock::now(); | |||
auto cmd = generate_compile_command(env); | |||
auto compile_res = run_proc(cmd); | |||
auto end_time = std::chrono::steady_clock::now(); | |||
auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time); | |||
auto cmd = generate_compile_command(env); | |||
auto&& [dur_ms, compile_res] = timed<std::chrono::milliseconds>([&] { return run_proc(cmd); }); | |||
spdlog::info("{} - {:>7n}ms", msg, dur_ms.count()); | |||
if (!compile_res.okay()) { |
@@ -2,6 +2,7 @@ | |||
#include <dds/build/plan/library.hpp> | |||
#include <dds/proc.hpp> | |||
#include <dds/util/time.hpp> | |||
#include <spdlog/spdlog.h> | |||
@@ -29,9 +30,14 @@ void link_executable_plan::link(build_env_ref env, const library_plan& lib) cons | |||
std::reverse(spec.inputs.begin(), spec.inputs.end()); | |||
const auto link_command = env.toolchain.create_link_executable_command(spec); | |||
spdlog::info("Linking executable: {}", fs::relative(spec.output, env.output_root).string()); | |||
fs::create_directories(out_path.parent_path()); | |||
auto proc_res = run_proc(link_command); | |||
auto msg = fmt::format("[{}] Link: {:30}", | |||
lib.name(), | |||
fs::relative(spec.output, env.output_root).string()); | |||
spdlog::info(msg); | |||
auto [dur_ms, proc_res] | |||
= timed<std::chrono::milliseconds>([&] { return run_proc(link_command); }); | |||
spdlog::info("{} - {:>6n}ms", msg, dur_ms.count()); | |||
if (!proc_res.okay()) { | |||
throw compile_failure( | |||
fmt::format("Failed to link test executable '{}'. Link command [{}] returned {}:\n{}", | |||
@@ -54,10 +60,8 @@ std::optional<test_failure> link_executable_plan::run_test(build_env_ref env) co | |||
auto exe_path = calc_executable_path(env); | |||
auto msg = fmt::format("Run test: {:30}", fs::relative(exe_path, env.output_root).string()); | |||
spdlog::info(msg); | |||
auto start = std::chrono::high_resolution_clock::now(); | |||
auto res = run_proc({exe_path.string()}); | |||
auto end = std::chrono::high_resolution_clock::now(); | |||
auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - start); | |||
auto&& [dur, res] | |||
= timed<std::chrono::microseconds>([&] { return run_proc({exe_path.string()}); }); | |||
if (res.okay()) { | |||
spdlog::info("{} - PASSED - {:>9n}μs", msg, dur.count()); | |||
return std::nullopt; | |||
@@ -69,4 +73,4 @@ std::optional<test_failure> link_executable_plan::run_test(build_env_ref env) co | |||
f.retc = res.retc; | |||
return f; | |||
} | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
#pragma once | |||
#include <chrono> | |||
#include <utility> | |||
namespace dds { | |||
class stopwatch { | |||
public: | |||
using clock = std::chrono::high_resolution_clock; | |||
using time_point = clock::time_point; | |||
using duration = time_point::duration; | |||
private: | |||
time_point _start_time = clock::now(); | |||
public: | |||
void reset() noexcept { _start_time = clock::now(); } | |||
duration elapsed() const noexcept { return clock::now() - _start_time; } | |||
template <typename Dur> | |||
Dur elapsed_as() const noexcept { | |||
return std::chrono::duration_cast<Dur>(elapsed()); | |||
} | |||
auto elapsed_ms() const noexcept { return elapsed_as<std::chrono::milliseconds>(); } | |||
auto elapsed_us() const noexcept { return elapsed_as<std::chrono::microseconds>(); } | |||
}; | |||
template <typename Duration = stopwatch::duration, typename Func> | |||
auto timed(Func&& fn) noexcept(noexcept(((Func &&)(fn))())) { | |||
stopwatch sw; | |||
using result_type = decltype(((Func &&)(fn))()); | |||
if constexpr (std::is_void_v<result_type>) { | |||
((Func &&)(fn))(); | |||
auto elapsed = sw.elapsed_as<Duration>(); | |||
return std::pair(elapsed, nullptr); | |||
} else { | |||
decltype(auto) value = ((Func &&)(fn))(); | |||
auto elapsed = sw.elapsed_as<Duration>(); | |||
return std::pair<Duration, decltype(value)>(elapsed, ((decltype(value)&&)value)); | |||
} | |||
} | |||
} // namespace dds |