Refactor just a little

This commit is contained in:
2026-06-28 07:43:05 -04:00
parent 866b049566
commit 6fef2493ac
14 changed files with 595 additions and 444 deletions

80
src/actions.cpp Normal file
View File

@@ -0,0 +1,80 @@
#include "actions.h"
int runCmd(std::string cmd, bool dryrun) {
if (dryrun) {
spdlog::get("cmd")->warn("[DRYRUN] Running '{}'", cmd);
return 0;
}
spdlog::get("cmd")->debug("Running '{}'", cmd);
spdlog::get("cmd")->debug("Opening pipe");
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) {
spdlog::get("cmd")->warn("Failed to start the process");
return 1;
}
spdlog::get("cmd")->debug("Buffering and offloading pipe");
std::array<char, 256> buffer;
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
std::cout << buffer.data() << std::flush;
}
spdlog::get("filesystem")->debug("Closing pipe");
int exitCode = pclose(pipe);
spdlog::get("cmd")->info("Process ended with exit code: {}", exitCode);
return exitCode;
}
void buildDir(const std::filesystem::path& path, bool dryrun) {
if (dryrun) {
spdlog::get("build")->warn("[DRYRUN] Building '{}'", path.string());
return;
}
spdlog::get("build")->info("Building '{}'", path.string());
if (int exitCode =
runCmd(std::format("cd {} && ninja", path.string()), dryrun);
exitCode != 0) {
spdlog::get("build")->critical("Command exited with exit code: {}",
exitCode);
exit(EXIT_FAILURE);
}
}
void configureDir(const std::filesystem::path& path, std::string buildStr,
bool dryrun) {
if (dryrun) {
spdlog::get("configure")
->warn("[DRYRUN] Configuring '{}'", path.string());
return;
}
spdlog::get("configure")->info("Configuring '{}'", path.string());
if (int exitCode = runCmd(
std::format("cd {} && cmake ../../ -G Ninja -DCMAKE_BUILD_TYPE={}",
path.string(), buildStr),
dryrun);
exitCode != 0) {
spdlog::get("configure")
->critical("Command exited with exit code: {}", exitCode);
exit(EXIT_FAILURE);
}
}
void cleanDir(const std::filesystem::path& path, bool dryrun) {
if (dryrun) {
spdlog::get("clean")->warn("[DRYRUN] Cleaning '{}'", path.string());
return;
}
spdlog::get("clean")->info("Cleaning '{}'", path.string());
if (int exitCode =
runCmd(std::format("cd {} && ninja clean", path.string()), dryrun);
exitCode != 0) {
spdlog::get("clean")->critical("Command exited with exit code: {}",
exitCode);
exit(EXIT_FAILURE);
}
}

15
src/actions.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef BUILD_SCRIPT_ACTIONS
#define BUILD_SCRIPT_ACTIONS
#include <iostream>
#include "filesystem.h"
#include "logging.h"
int runCmd(std::string cmd, bool dryrun);
void buildDir(const std::filesystem::path& path, bool dryrun);
void configureDir(const std::filesystem::path& path, std::string buildStr,
bool dryrun);
void cleanDir(const std::filesystem::path& path, bool dryrun);
#endif // !BUILD_SCRIPT_ACTIONS

14
src/args.cpp Normal file
View File

@@ -0,0 +1,14 @@
#include "args.h"
Options parse(int argc, char** argv) {
Options options;
try {
options = structopt::app(argv[0], "1.0.0").parse<Options>(argc, argv);
} catch (structopt::exception& e) {
std::cout << e.what() << std::endl;
std::cout << e.help();
exit(EXIT_FAILURE);
}
return options;
}

19
src/args.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef BUILD_SCRIPT_ARGS
#define BUILD_SCRIPT_ARGS
#include <structopt/app.hpp>
#include "types.h"
struct Options {
Command command;
std::optional<BuildType> buildType = BuildType::none;
std::optional<bool> verbose = false;
std::optional<bool> dryrun = false;
};
STRUCTOPT(Options, command, buildType, verbose, dryrun);
Options parse(int argc, char** argv);
#endif // !BUILD_SCRIPT_ARGS

109
src/commands.cpp Normal file
View File

@@ -0,0 +1,109 @@
#include "commands.h"
void buildProject(const BuildType buildType, bool dryrun) {
checkBuildDirs(buildType, dryrun);
switch (buildType) {
case none:
configureDir("build/debug", "Debug", dryrun);
buildDir("build/debug", dryrun);
configureDir("build/release", "Release", dryrun);
buildDir("build/release", dryrun);
configureDir("build/relwithdeb", "RelWithDeb", dryrun);
buildDir("build/relwithdeb", dryrun);
configureDir("build/minsizerel", "MinSizeRel", dryrun);
buildDir("build/minsizerel", dryrun);
break;
case debug:
configureDir("build/debug", "Debug", dryrun);
buildDir("build/debug", dryrun);
break;
case release:
configureDir("build/release", "Release", dryrun);
buildDir("build/release", dryrun);
break;
case relwithdeb:
configureDir("build/relwithdeb", "RelWithDeb", dryrun);
buildDir("build/relwithdeb", dryrun);
break;
case minsizerel:
configureDir("build/minsizerel", "MinSizeRel", dryrun);
buildDir("build/minsizerel", dryrun);
break;
}
}
void configureProject(const BuildType buildType, bool dryrun) {
checkBuildDirs(buildType, dryrun);
switch (buildType) {
case none:
configureDir("build/debug", "Debug", dryrun);
configureDir("build/release", "Release", dryrun);
configureDir("build/relwithdeb", "RelWithDeb", dryrun);
configureDir("build/minsizerel", "MinSizeRel", dryrun);
break;
case debug:
configureDir("build/debug", "Debug", dryrun);
break;
case release:
configureDir("build/release", "Release", dryrun);
break;
case relwithdeb:
configureDir("build/RelWithDeb", "RelWithDeb", dryrun);
break;
case minsizerel:
configureDir("build/minsizerel", "MinSizeRel", dryrun);
break;
}
}
void cleanProject(const BuildType buildType, bool dryrun) {
checkBuildDirs(buildType, dryrun);
switch (buildType) {
case none:
cleanDir("build/debug", dryrun);
cleanDir("build/release", dryrun);
cleanDir("build/relwithdeb", dryrun);
cleanDir("build/minsizerel", dryrun);
break;
case debug:
cleanDir("build/debug", dryrun);
break;
case release:
cleanDir("build/release", dryrun);
break;
case relwithdeb:
cleanDir("build/RelWithDeb", dryrun);
break;
case minsizerel:
cleanDir("build/minsizerel", dryrun);
break;
}
}
void deleteProject(const BuildType buildType, bool dryrun) {
switch (buildType) {
case none:
deleteDir("build", dryrun);
break;
case debug:
deleteDir("build/debug", dryrun);
break;
case release:
deleteDir("build/release", dryrun);
break;
case relwithdeb:
deleteDir("build/relwithdeb", dryrun);
break;
case minsizerel:
deleteDir("build/minsizerel", dryrun);
break;
}
}
void rebuildProject(const BuildType buildType, bool dryrun) {
deleteProject(buildType, dryrun);
checkBuildDirs(buildType, dryrun);
configureProject(buildType, dryrun);
buildProject(buildType, dryrun);
}

13
src/commands.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef BUILD_SCRIPT_COMMANDS
#define BUILD_SCRIPT_COMMANDS
#include "actions.h"
#include "types.h"
void buildProject(const BuildType buildType, bool dryrun);
void configureProject(const BuildType buildType, bool dryrun);
void cleanProject(const BuildType buildType, bool dryrun);
void deleteProject(const BuildType buildType, bool dryrun);
void rebuildProject(const BuildType buildType, bool dryrun);
#endif // !BUILD_SCRIPT_COMMANDS

170
src/filesystem.cpp Normal file
View File

@@ -0,0 +1,170 @@
#include "filesystem.h"
#include <iostream>
#include "logging.h"
void deleteDir(const std::filesystem::path& path, bool dryrun) {
if (dryrun) {
spdlog::get("filesystem")
->warn("[DRYRUN] Deleting '{}'", path.string());
return;
}
spdlog::get("filesystem")->warn("DELETING '{}' directory.", path.string());
spdlog::get("filesystem")->debug("Checking '{}'", path.string());
if (!std::filesystem::exists(path) ||
!std::filesystem::is_directory(path)) {
spdlog::get("filesystem")
->info(
"The {} directory either doesn't exist or its a file. "
"Continuing...",
path.string());
return;
}
spdlog::get("filesystem")->debug("Deleting '{}'", path.string());
std::filesystem::remove_all(path);
}
void createDir(const std::filesystem::path& path, bool dryrun) {
if (dryrun) {
spdlog::get("filesystem")
->warn("[DRYRUN] Creating '{}'", path.string());
return;
}
spdlog::get("filesystem")->debug("Creating '{}'", path.string());
if (const bool res = std::filesystem::create_directories(path); !res) {
spdlog::get("filesystem")
->warn("Failed to create directory: '{}'", path.string());
}
}
void checkBuildDirs(const BuildType buildType, bool dryrun) {
spdlog::get("filesystem")->debug("Checking 'build' directory.");
if (!std::filesystem::is_directory("build")) {
spdlog::get("filesystem")
->warn("'build' is not a directory. Deleting.");
deleteDir("build", dryrun);
}
if (!std::filesystem::exists("build")) {
spdlog::get("filesystem")->info("Creating 'build' directory");
createDir("build", dryrun);
}
switch (buildType) {
case none:
spdlog::get("filesystem")
->debug("Checking 'build/debug' directory.");
if (!std::filesystem::is_directory("build/debug")) {
spdlog::get("filesystem")
->warn("'build/debug' is not a directory. Deleting.");
deleteDir("build/debug", dryrun);
}
if (!std::filesystem::exists("build/debug")) {
spdlog::get("filesystem")
->info("Creating 'build/debug' directory.");
createDir("build/debug", dryrun);
}
spdlog::get("filesystem")
->debug("Checking 'build/release' directory.");
if (!std::filesystem::is_directory("build/release")) {
spdlog::get("filesystem")
->warn("'build/release' is not a directory. Deleting.");
deleteDir("build/release", dryrun);
}
if (!std::filesystem::exists("build/release")) {
spdlog::get("filesystem")
->info("Creating 'build/release' directory.");
createDir("build/release", dryrun);
}
spdlog::get("filesystem")
->debug("Checking 'build/relwithdeb' directory.");
if (!std::filesystem::is_directory("build/relwithdeb")) {
spdlog::get("filesystem")
->warn("'build/relwithdeb' is not a directory. Deleting.");
deleteDir("build/relwithdeb", dryrun);
}
if (!std::filesystem::exists("build/relwithdeb")) {
spdlog::get("filesystem")
->info("Creating 'build/relwithdeb' directory.");
createDir("build/relwithdeb", dryrun);
}
spdlog::get("filesystem")
->debug("Checking 'build/minsizerel' directory.");
if (!std::filesystem::is_directory("build/minsizerel")) {
spdlog::get("filesystem")
->warn("'build/minsizerel' is not a directory. Deleting.");
deleteDir("build/minsizerel", dryrun);
}
if (!std::filesystem::exists("build/minsizerel")) {
spdlog::get("filesystem")
->info("Creating 'build/minsizerel' directory.");
createDir("build/minsizerel", dryrun);
};
break;
case debug:
spdlog::get("filesystem")
->debug("Checking 'build/debug' directory.");
if (!std::filesystem::is_directory("build/debug")) {
spdlog::get("filsystem")
->warn("'build/debug' is not a directory. Deleting.");
deleteDir("build/debug", dryrun);
}
if (!std::filesystem::exists("build/debug")) {
spdlog::get("filesystem")
->info("Creating 'build/debug' directory.");
createDir("build/debug", dryrun);
}
break;
case release:
spdlog::get("filesystem")
->debug("Checking 'build/release' directory.");
if (!std::filesystem::is_directory("build/release")) {
spdlog::get("filesystem")
->warn("'build/release' is not a directory. Deleting.");
deleteDir("build/release", dryrun);
}
if (!std::filesystem::exists("build/release")) {
spdlog::get("filesystem")
->info("Creating 'build/release' directory.");
createDir("build/release", dryrun);
}
break;
case relwithdeb:
spdlog::get("filesystem")
->debug("Checking 'build/relwithdeb' directory.");
if (!std::filesystem::is_directory("build/relwithdeb")) {
spdlog::get("filesystem")
->warn("'build/relwithdeb' is not a directory. Deleting.");
deleteDir("build/relwithdeb", dryrun);
}
if (!std::filesystem::exists("build/relwithdeb")) {
spdlog::get("filesystem")
->info("Creating 'build/relwithdeb' directory.");
createDir("build/relwithdeb", dryrun);
};
break;
case minsizerel:
spdlog::get("filesystem")
->debug("Checking 'build/minsizerel' directory.");
if (!std::filesystem::is_directory("build/minsizerel")) {
spdlog::get("filesystem")
->warn("'build/minsizerel' is not a directory. Deleting.");
deleteDir("build/minsizerel", dryrun);
}
if (!std::filesystem::exists("build/minsizerel")) {
spdlog::get("filesystem")
->info("Creating 'build/minsizerel' directory.");
createDir("build/minsizerel", dryrun);
};
break;
}
spdlog::get("filesystem")->info("All directories checked.");
}

12
src/filesystem.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef BUILD_SCRIPT_FILESYSTEM
#define BUILD_SCRIPT_FILESYSTEM
#include <filesystem>
#include "types.h"
void deleteDir(const std::filesystem::path& path, bool dryrun);
void createDir(const std::filesystem::path& path, bool dryrun);
void checkBuildDirs(const BuildType buildType, bool dryrun);
#endif // !BUILD_SCRIPT_FILESYSTEM

40
src/logging.cpp Normal file
View File

@@ -0,0 +1,40 @@
#include "logging.h"
void initLogging() {
spdlog::init_thread_pool(8192, 1);
spdlog::flush_every(std::chrono::seconds(1));
}
void createLogger(const char* name, const char* filename, const bool verbose) {
std::vector<spdlog::sink_ptr> sinks;
const auto stdout_sink =
std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
stdout_sink->set_level(spdlog::level::debug);
stdout_sink->set_pattern("%^[%D %r %z] [%n] [%l] %v%$");
sinks.push_back(stdout_sink);
if (filename != nullptr) {
const auto file_sink =
std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename);
file_sink->set_level(spdlog::level::debug);
file_sink->set_pattern("[%D %r %z] [%n] [%l] %v");
sinks.push_back(file_sink);
}
const auto logger = std::make_shared<spdlog::async_logger>(
name, sinks.begin(), sinks.end(), spdlog::thread_pool(),
spdlog::async_overflow_policy::block);
logger->flush_on(spdlog::level::warn);
#ifdef DEBUG
logger->set_level(spdlog::level::debug);
#else
if (verbose)
logger->set_level(spdlog::level::debug);
else
logger->set_level(spdlog::level::info);
#endif
spdlog::register_logger(logger);
}

12
src/logging.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef BUILD_SCRIPT_LOGGING
#define BUILD_SCRIPT_LOGGING
#include <spdlog/async.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
void initLogging();
void createLogger(const char* name, const char* filename, const bool verbose);
#endif // !BUILD_SCRIPT_LOGGING

View File

@@ -1,449 +1,15 @@
#include <spdlog/async.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
#include <filesystem>
#include <iostream>
#include <string>
#include <structopt/app.hpp>
#include "args.h"
#include "commands.h"
#include "logging.h"
#include "types.h"
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
enum Command {
build,
configure,
clean,
del,
rebuild,
};
enum BuildType {
none,
debug,
release,
relwithdeb,
minsizerel,
};
struct Options {
Command command;
std::optional<BuildType> buildType = BuildType::none;
std::optional<bool> verbose = false;
std::optional<bool> dryrun = false;
};
STRUCTOPT(Options, command, buildType, verbose, dryrun);
bool g_DryRun = false;
void initLogging() {
spdlog::init_thread_pool(8192, 1);
spdlog::flush_every(std::chrono::seconds(1));
}
void createLogger(const char* name, const char* filename, const bool verbose) {
std::vector<spdlog::sink_ptr> sinks;
const auto stdout_sink =
std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
stdout_sink->set_level(spdlog::level::debug);
stdout_sink->set_pattern("%^[%D %r %z] [%n] [%l] %v%$");
sinks.push_back(stdout_sink);
if (filename != nullptr) {
const auto file_sink =
std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename);
file_sink->set_level(spdlog::level::debug);
file_sink->set_pattern("[%D %r %z] [%n] [%l] %v");
sinks.push_back(file_sink);
}
const auto logger = std::make_shared<spdlog::async_logger>(
name, sinks.begin(), sinks.end(), spdlog::thread_pool(),
spdlog::async_overflow_policy::block);
logger->flush_on(spdlog::level::warn);
#ifdef DEBUG
logger->set_level(spdlog::level::debug);
#else
if (verbose)
logger->set_level(spdlog::level::debug);
else
logger->set_level(spdlog::level::info);
#endif
spdlog::register_logger(logger);
}
void deleteDir(const std::filesystem::path& path) {
if (g_DryRun) {
spdlog::get("filesystem")
->warn("[DRYRUN] Deleting '{}'", path.string());
return;
}
spdlog::get("filesystem")->warn("DELETING '{}' directory.", path.string());
spdlog::get("filesystem")->debug("Checking '{}'", path.string());
if (!std::filesystem::exists(path) ||
!std::filesystem::is_directory(path)) {
spdlog::get("filesystem")
->info(
"The {} directory either doesn't exist or its a file. "
"Continuing...",
path.string());
return;
}
spdlog::get("filesystem")->debug("Deleting '{}'", path.string());
std::filesystem::remove_all(path);
}
void createDir(const std::filesystem::path& path) {
if (g_DryRun) {
spdlog::get("filesystem")
->warn("[DRYRUN] Creating '{}'", path.string());
return;
}
spdlog::get("filesystem")->debug("Creating '{}'", path.string());
if (const bool res = std::filesystem::create_directories(path); !res) {
spdlog::get("filesystem")
->warn("Failed to create directory: '{}'", path.string());
}
}
void checkBuildDirs(const BuildType buildType) {
spdlog::get("filesystem")->debug("Checking 'build' directory.");
if (!std::filesystem::is_directory("build")) {
spdlog::get("filesystem")
->warn("'build' is not a directory. Deleting.");
deleteDir("build");
}
if (!std::filesystem::exists("build")) {
spdlog::get("filesystem")->info("Creating 'build' directory");
createDir("build");
}
switch (buildType) {
case none:
spdlog::get("filesystem")
->debug("Checking 'build/debug' directory.");
if (!std::filesystem::is_directory("build/debug")) {
spdlog::get("filesystem")
->warn("'build/debug' is not a directory. Deleting.");
deleteDir("build/debug");
}
if (!std::filesystem::exists("build/debug")) {
spdlog::get("filesystem")
->info("Creating 'build/debug' directory.");
createDir("build/debug");
}
spdlog::get("filesystem")
->debug("Checking 'build/release' directory.");
if (!std::filesystem::is_directory("build/release")) {
spdlog::get("filesystem")
->warn("'build/release' is not a directory. Deleting.");
deleteDir("build/release");
}
if (!std::filesystem::exists("build/release")) {
spdlog::get("filesystem")
->info("Creating 'build/release' directory.");
createDir("build/release");
}
spdlog::get("filesystem")
->debug("Checking 'build/relwithdeb' directory.");
if (!std::filesystem::is_directory("build/relwithdeb")) {
spdlog::get("filesystem")
->warn("'build/relwithdeb' is not a directory. Deleting.");
deleteDir("build/relwithdeb");
}
if (!std::filesystem::exists("build/relwithdeb")) {
spdlog::get("filesystem")
->info("Creating 'build/relwithdeb' directory.");
createDir("build/relwithdeb");
}
spdlog::get("filesystem")
->debug("Checking 'build/minsizerel' directory.");
if (!std::filesystem::is_directory("build/minsizerel")) {
spdlog::get("filesystem")
->warn("'build/minsizerel' is not a directory. Deleting.");
deleteDir("build/minsizerel");
}
if (!std::filesystem::exists("build/minsizerel")) {
spdlog::get("filesystem")
->info("Creating 'build/minsizerel' directory.");
createDir("build/minsizerel");
};
break;
case debug:
spdlog::get("filesystem")
->debug("Checking 'build/debug' directory.");
if (!std::filesystem::is_directory("build/debug")) {
spdlog::get("filsystem")
->warn("'build/debug' is not a directory. Deleting.");
deleteDir("build/debug");
}
if (!std::filesystem::exists("build/debug")) {
spdlog::get("filesystem")
->info("Creating 'build/debug' directory.");
createDir("build/debug");
}
break;
case release:
spdlog::get("filesystem")
->debug("Checking 'build/release' directory.");
if (!std::filesystem::is_directory("build/release")) {
spdlog::get("filesystem")
->warn("'build/release' is not a directory. Deleting.");
deleteDir("build/release");
}
if (!std::filesystem::exists("build/release")) {
spdlog::get("filesystem")
->info("Creating 'build/release' directory.");
createDir("build/release");
}
break;
case relwithdeb:
spdlog::get("filesystem")
->debug("Checking 'build/relwithdeb' directory.");
if (!std::filesystem::is_directory("build/relwithdeb")) {
spdlog::get("filesystem")
->warn("'build/relwithdeb' is not a directory. Deleting.");
deleteDir("build/relwithdeb");
}
if (!std::filesystem::exists("build/relwithdeb")) {
spdlog::get("filesystem")
->info("Creating 'build/relwithdeb' directory.");
createDir("build/relwithdeb");
};
break;
case minsizerel:
spdlog::get("filesystem")
->debug("Checking 'build/minsizerel' directory.");
if (!std::filesystem::is_directory("build/minsizerel")) {
spdlog::get("filesystem")
->warn("'build/minsizerel' is not a directory. Deleting.");
deleteDir("build/minsizerel");
}
if (!std::filesystem::exists("build/minsizerel")) {
spdlog::get("filesystem")
->info("Creating 'build/minsizerel' directory.");
createDir("build/minsizerel");
};
break;
}
spdlog::get("filesystem")->info("All directories checked.");
}
int runCmd(std::string cmd) {
if (g_DryRun) {
spdlog::get("cmd")->warn("[DRYRUN] Running '{}'", cmd);
return 0;
}
spdlog::get("cmd")->debug("Running '{}'", cmd);
spdlog::get("cmd")->debug("Opening pipe");
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) {
spdlog::get("cmd")->warn("Failed to start the process");
return 1;
}
spdlog::get("cmd")->debug("Buffering and offloading pipe");
std::array<char, 256> buffer;
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
std::cout << buffer.data() << std::flush;
}
spdlog::get("filesystem")->debug("Closing pipe");
int exitCode = pclose(pipe);
spdlog::get("cmd")->info("Process ended with exit code: {}", exitCode);
return exitCode;
}
void buildDir(const std::filesystem::path& path) {
if (g_DryRun) {
spdlog::get("build")->warn("[DRYRUN] Building '{}'", path.string());
return;
}
spdlog::get("build")->info("Building '{}'", path.string());
if (int exitCode = runCmd(std::format("cd {} && ninja", path.string()));
exitCode != 0) {
spdlog::get("build")->critical("Command exited with exit code: {}",
exitCode);
exit(EXIT_FAILURE);
}
}
void configureDir(const std::filesystem::path& path, std::string buildStr) {
if (g_DryRun) {
spdlog::get("configure")
->warn("[DRYRUN] Configuring '{}'", path.string());
return;
}
spdlog::get("configure")->info("Configuring '{}'", path.string());
if (int exitCode = runCmd(
std::format("cd {} && cmake ../../ -G Ninja -DCMAKE_BUILD_TYPE={}",
path.string(), buildStr));
exitCode != 0) {
spdlog::get("configure")
->critical("Command exited with exit code: {}", exitCode);
exit(EXIT_FAILURE);
}
}
void cleanDir(const std::filesystem::path& path) {
if (g_DryRun) {
spdlog::get("clean")->warn("[DRYRUN] Cleaning '{}'", path.string());
return;
}
spdlog::get("clean")->info("Cleaning '{}'", path.string());
if (int exitCode =
runCmd(std::format("cd {} && cmake clean", path.string()));
exitCode != 0) {
spdlog::get("clean")->critical("Command exited with exit code: {}",
exitCode);
exit(EXIT_FAILURE);
}
}
void buildProject(const BuildType buildType) {
checkBuildDirs(buildType);
switch (buildType) {
case none:
configureDir("build/debug", "Debug");
buildDir("build/debug");
configureDir("build/release", "Release");
buildDir("build/release");
configureDir("build/relwithdeb", "RelWithDeb");
buildDir("build/relwithdeb");
configureDir("build/minsizerel", "MinSizeRel");
buildDir("build/minsizerel");
break;
case debug:
configureDir("build/debug", "Debug");
buildDir("build/debug");
break;
case release:
configureDir("build/release", "Release");
buildDir("build/release");
break;
case relwithdeb:
configureDir("build/relwithdeb", "RelWithDeb");
buildDir("build/relwithdeb");
break;
case minsizerel:
configureDir("build/minsizerel", "MinSizeRel");
buildDir("build/minsizerel");
break;
}
}
void configureProject(const BuildType buildType) {
checkBuildDirs(buildType);
switch (buildType) {
case none:
configureDir("build/debug", "Debug");
configureDir("build/release", "Release");
configureDir("build/relwithdeb", "RelWithDeb");
configureDir("build/minsizerel", "MinSizeRel");
break;
case debug:
configureDir("build/debug", "Debug");
break;
case release:
configureDir("build/release", "Release");
break;
case relwithdeb:
configureDir("build/RelWithDeb", "RelWithDeb");
break;
case minsizerel:
configureDir("build/minsizerel", "MinSizeRel");
break;
}
}
void cleanProject(const BuildType buildType) {
checkBuildDirs(buildType);
switch (buildType) {
case none:
cleanDir("build/debug");
cleanDir("build/release");
cleanDir("build/relwithdeb");
cleanDir("build/minsizerel");
break;
case debug:
cleanDir("build/debug");
break;
case release:
cleanDir("build/release");
break;
case relwithdeb:
cleanDir("build/RelWithDeb");
break;
case minsizerel:
cleanDir("build/minsizerel");
break;
}
}
void deleteProject(const BuildType buildType) {
switch (buildType) {
case none:
deleteDir("build");
break;
case debug:
deleteDir("build/debug");
break;
case release:
deleteDir("build/release");
break;
case relwithdeb:
deleteDir("build/relwithdeb");
break;
case minsizerel:
deleteDir("build/minsizerel");
break;
}
}
void rebuildProject(const BuildType buildType) {
deleteProject(buildType);
checkBuildDirs(buildType);
configureProject(buildType);
buildProject(buildType);
}
int main(const int argc, char** argv) {
Options options;
try {
options = structopt::app(argv[0], "1.0.0").parse<Options>(argc, argv);
} catch (structopt::exception& e) {
std::cout << e.what() << std::endl;
std::cout << e.help();
exit(EXIT_FAILURE);
}
assert(options.verbose.has_value());
assert(options.dryrun.has_value());
assert(options.buildType.has_value());
g_DryRun = options.dryrun.value();
Options options = parse(argc, argv);
initLogging();
createLogger("app", nullptr, options.verbose.value());
@@ -462,19 +28,19 @@ int main(const int argc, char** argv) {
spdlog::get("app")->debug("Running command");
switch (options.command) {
case build:
buildProject(options.buildType.value());
buildProject(options.buildType.value(), options.dryrun.value());
break;
case configure:
configureProject(options.buildType.value());
configureProject(options.buildType.value(), options.dryrun.value());
break;
case clean:
cleanProject(options.buildType.value());
cleanProject(options.buildType.value(), options.dryrun.value());
break;
case del:
deleteProject(options.buildType.value());
deleteProject(options.buildType.value(), options.dryrun.value());
break;
case rebuild:
rebuildProject(options.buildType.value());
rebuildProject(options.buildType.value(), options.dryrun.value());
break;
}

20
src/types.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef BUILD_SCRIPT_TYPES
#define BUILD_SCRIPT_TYPES
enum Command {
build,
configure,
clean,
del,
rebuild,
};
enum BuildType {
none,
debug,
release,
relwithdeb,
minsizerel,
};
#endif // !BUILD_SCRIPT_TYPES