Skip to content

Commit

Permalink
Implement stderr redirection for Command (#1006)
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui authored Oct 5, 2024
1 parent 7b5f3ca commit 5e76668
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 74 deletions.
11 changes: 6 additions & 5 deletions src/Algos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ getCmdOutput(const Command& cmd, const usize retry) {
int exitCode = EXIT_SUCCESS;
int waitTime = 1;
for (usize i = 0; i < retry; ++i) {
const auto [output, status] = cmd.output();
if (status == EXIT_SUCCESS) {
return output;
const auto [curExitCode, stdout, stderr] = cmd.output();
static_cast<void>(stderr);
if (curExitCode == EXIT_SUCCESS) {
return stdout;
}
exitCode = status;
exitCode = curExitCode;

// Sleep for an exponential backoff.
std::this_thread::sleep_for(std::chrono::seconds(waitTime));
Expand All @@ -86,7 +87,7 @@ bool
commandExists(const std::string_view cmd) noexcept {
const int exitCode = Command("which")
.addArg(cmd)
.setStdoutConfig(Command::StdioConfig::Null)
.setStdoutConfig(Command::IOConfig::Null)
.spawn()
.wait();
return exitCode == EXIT_SUCCESS;
Expand Down
59 changes: 29 additions & 30 deletions src/BuildConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,10 @@
#include <utility>
#include <vector>

static constinit const std::string_view TEST_OUT_DIR = "tests";
static constinit const std::string_view PATH_FROM_OUT_DIR = "../../";
namespace {

static std::vector<fs::path>
listSourceFilePaths(const std::string_view directory) {
std::vector<fs::path> sourceFilePaths;
for (const auto& entry : fs::recursive_directory_iterator(directory)) {
if (!SOURCE_FILE_EXTS.contains(entry.path().extension())) {
continue;
}
sourceFilePaths.emplace_back(entry.path());
}
return sourceFilePaths;
}
constinit const std::string_view TEST_OUT_DIR = "tests";
constinit const std::string_view PATH_FROM_OUT_DIR = "../../";

enum class VarType : std::uint8_t {
Recursive, // =
Expand Down Expand Up @@ -87,12 +77,6 @@ struct Variable {
VarType type = VarType::Simple;
};

std::ostream&
operator<<(std::ostream& os, const Variable& var) {
os << var.type << ' ' << var.value;
return os;
}

struct Target {
std::vector<std::string> commands;
std::optional<std::string> sourceFile;
Expand All @@ -110,9 +94,9 @@ struct BuildConfig {
std::optional<std::unordered_set<std::string>> phony;
std::optional<std::unordered_set<std::string>> all;

// NOLINTBEGIN(readability-identifier-naming)
std::string outDir;
std::string CXX;
std::string cxx;
// NOLINTBEGIN(readability-identifier-naming)
std::vector<std::string> CXXFLAGS;
std::vector<std::string> DEFINES;
std::vector<std::string> INCLUDES = { "-I../../include" };
Expand All @@ -122,22 +106,23 @@ struct BuildConfig {
explicit BuildConfig(const std::string& packageName)
: packageName{ packageName }, buildOutDir{ packageName + ".d" } {
if (const char* cxx = std::getenv("CXX")) {
CXX = cxx;
this->cxx = cxx;
} else {
const std::string output = Command("make")
.addArg("--print-data-base")
.addArg("--question")
.addArg("-f")
.addArg("/dev/null")
.setStderrConfig(Command::IOConfig::Null)
.output()
.output;
.stdout;
std::istringstream iss(output);
std::string line;

while (std::getline(iss, line)) {
if (line.starts_with("CXX = ")) {
constexpr usize offset = 6;
CXX = line.substr(offset);
this->cxx = line.substr(offset);
return;
}
}
Expand Down Expand Up @@ -229,7 +214,7 @@ struct BuildConfig {
) const;
};

static void
void
emitDep(std::ostream& os, usize& offset, const std::string_view dep) {
constexpr usize maxLineLen = 80;
if (offset + dep.size() + 2 > maxLineLen) { // 2 for space and \.
Expand All @@ -241,7 +226,7 @@ emitDep(std::ostream& os, usize& offset, const std::string_view dep) {
offset += dep.size() + 1; // space
}

static void
void
emitTarget(
std::ostream& os, const std::string_view target,
const std::unordered_set<std::string>& dependsOn,
Expand Down Expand Up @@ -302,6 +287,8 @@ BuildConfig::emitVariable(std::ostream& os, const std::string& varName) const {
os << '\n';
}

} // namespace

void
BuildConfig::emitMakefile(std::ostream& os) const {
const std::vector<std::string> sortedVars = topoSort(variables, varDeps);
Expand Down Expand Up @@ -370,7 +357,7 @@ BuildConfig::emitCompdb(const std::string_view baseDir, std::ostream& os)
const std::string file = targetInfo.sourceFile.value();
// The output is the target.
const std::string output = target;
const Command cmd = Command(CXX)
const Command cmd = Command(cxx)
.addArgs(CXXFLAGS)
.addArgs(DEFINES)
.addArgs(INCLUDES)
Expand Down Expand Up @@ -402,7 +389,7 @@ BuildConfig::emitCompdb(const std::string_view baseDir, std::ostream& os)
std::string
BuildConfig::runMM(const std::string& sourceFile, const bool isTest) const {
Command command =
Command(CXX).addArgs(CXXFLAGS).addArgs(DEFINES).addArgs(INCLUDES);
Command(cxx).addArgs(CXXFLAGS).addArgs(DEFINES).addArgs(INCLUDES);
if (isTest) {
command.addArg("-DPOAC_TEST");
}
Expand Down Expand Up @@ -461,7 +448,7 @@ BuildConfig::containsTestCode(const std::string& sourceFile) const {
while (std::getline(ifs, line)) {
if (line.find("POAC_TEST") != std::string::npos) {
// TODO: Can't we somehow elegantly make the compiler command sharable?
Command command(CXX);
Command command(cxx);
command.addArg("-E");
command.addArgs(CXXFLAGS);
command.addArgs(DEFINES);
Expand Down Expand Up @@ -623,7 +610,7 @@ BuildConfig::addDefine(

void
BuildConfig::setVariables(const bool isDebug) {
this->defineSimpleVar("CXX", CXX);
this->defineSimpleVar("CXX", cxx);

CXXFLAGS.push_back("-std=c++" + getPackageEdition().getString());
if (shouldColor()) {
Expand Down Expand Up @@ -812,6 +799,18 @@ processTestSrc(
}
}

static std::vector<fs::path>
listSourceFilePaths(const std::string_view directory) {
std::vector<fs::path> sourceFilePaths;
for (const auto& entry : fs::recursive_directory_iterator(directory)) {
if (!SOURCE_FILE_EXTS.contains(entry.path().extension())) {
continue;
}
sourceFilePaths.emplace_back(entry.path());
}
return sourceFilePaths;
}

static void
configureBuild(BuildConfig& config, const bool isDebug) {
if (!fs::exists("src")) {
Expand Down
Loading

0 comments on commit 5e76668

Please sign in to comment.