Browse Source

Run archive creation in a subdir for shorter command lines

default_compile_flags
vector-of-bool 4 years ago
parent
commit
2c900b6dd5
4 changed files with 21 additions and 10 deletions
  1. +5
    -2
      src/dds/build/plan/archive.cpp
  2. +5
    -2
      src/dds/proc.hpp
  3. +9
    -5
      src/dds/proc.nix.cpp
  4. +2
    -1
      src/dds/proc.win.cpp

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

; ;
// Build up the archive command // Build up the archive command
archive_spec ar; archive_spec ar;

auto ar_cwd = env.output_root;
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, fs::current_path(), env.knobs);
auto ar_cmd = env.toolchain.create_archive_command(ar, ar_cwd, 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


// Do it! // Do it!
dds_log(info, "[{}] Archive: {}", _qual_name, out_relpath); dds_log(info, "[{}] Archive: {}", _qual_name, out_relpath);
auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>([&] { return run_proc(ar_cmd); });
auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>(
[&] { return run_proc(proc_options{.command = ar_cmd, .cwd = ar_cwd}); });
dds_log(info, "[{}] Archive: {} - {:L}ms", _qual_name, out_relpath, dur_ms.count()); dds_log(info, "[{}] Archive: {} - {:L}ms", _qual_name, out_relpath, dur_ms.count());


// Check, log, and throw // Check, log, and throw

+ 5
- 2
src/dds/proc.hpp View File

#pragma once #pragma once


#include <chrono> #include <chrono>
#include <filesystem>
#include <optional> #include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
} }


struct proc_result { struct proc_result {
int signal = 0;
int retc = 0;
int signal = 0;
int retc = 0;
bool timed_out = false; bool timed_out = false;
std::string output; std::string output;


struct proc_options { struct proc_options {
std::vector<std::string> command; std::vector<std::string> command;


std::optional<std::filesystem::path> cwd = std::nullopt;

/** /**
* Timeout for the subprocess, in milliseconds. If zero, will wait forever * Timeout for the subprocess, in milliseconds. If zero, will wait forever
*/ */

+ 9
- 5
src/dds/proc.nix.cpp View File

#ifndef _WIN32 #ifndef _WIN32
#include "./proc.hpp" #include "./proc.hpp"


#include <dds/util/fs.hpp>
#include <dds/util/log.hpp> #include <dds/util/log.hpp>
#include <dds/util/signal.hpp> #include <dds/util/signal.hpp>


} }
} }


::pid_t
spawn_child(const std::vector<std::string>& command, int stdout_pipe, int close_me) noexcept {
::pid_t spawn_child(const proc_options& opts, int stdout_pipe, int close_me) noexcept {
// We must allocate BEFORE fork(), since the CRT might stumble with malloc()-related locks that // We must allocate BEFORE fork(), since the CRT might stumble with malloc()-related locks that
// are held during the fork(). // are held during the fork().
std::vector<const char*> strings; std::vector<const char*> strings;
strings.reserve(command.size() + 1);
for (auto& s : command) {
strings.reserve(opts.command.size() + 1);
for (auto& s : opts.command) {
strings.push_back(s.data()); strings.push_back(s.data());
} }
strings.push_back(nullptr); strings.push_back(nullptr);


std::string workdir = opts.cwd.value_or(fs::current_path()).string();

auto child_pid = ::fork(); auto child_pid = ::fork();
if (child_pid != 0) { if (child_pid != 0) {
return child_pid; return child_pid;
check_rc(rc != -1, "Failed to dup2 stdout"); check_rc(rc != -1, "Failed to dup2 stdout");
rc = dup2(stdout_pipe, STDERR_FILENO); rc = dup2(stdout_pipe, STDERR_FILENO);
check_rc(rc != -1, "Failed to dup2 stderr"); check_rc(rc != -1, "Failed to dup2 stderr");
rc = ::chdir(workdir.data());
check_rc(rc != -1, "Failed to chdir() for subprocess");


::execvp(strings[0], (char* const*)strings.data()); ::execvp(strings[0], (char* const*)strings.data());


int read_pipe = stdio_pipe[0]; int read_pipe = stdio_pipe[0];
int write_pipe = stdio_pipe[1]; int write_pipe = stdio_pipe[1];


auto child = spawn_child(opts.command, write_pipe, read_pipe);
auto child = spawn_child(opts, write_pipe, read_pipe);


::close(write_pipe); ::close(write_pipe);



+ 2
- 1
src/dds/proc.win.cpp View File

#ifdef _WIN32 #ifdef _WIN32
#include "./proc.hpp" #include "./proc.hpp"


#include <dds/util/fs.hpp>
#include <dds/util/log.hpp> #include <dds/util/log.hpp>


#include <fmt/core.h> #include <fmt/core.h>
true, true,
CREATE_NEW_PROCESS_GROUP, CREATE_NEW_PROCESS_GROUP,
nullptr, nullptr,
nullptr,
opts.cwd.value_or(fs::current_path()).c_str(),
&startup_info, &startup_info,
&proc_info); &proc_info);
if (!okay) { if (!okay) {

Loading…
Cancel
Save