Smart parellalization
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
build/
|
||||
.idea
|
||||
*.dot
|
||||
|
||||
@@ -4,6 +4,9 @@ project(build_script)
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
|
||||
|
||||
# Taskflow has a deprecated declaration issue in its small_vector.hpp file
|
||||
add_compile_options(-Wno-deprecated-declarations)
|
||||
|
||||
file(GLOB REQUIRED_CMAKE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/*.required.cmake")
|
||||
foreach (cmake_file ${REQUIRED_CMAKE_FILES})
|
||||
include(${cmake_file})
|
||||
@@ -23,13 +26,16 @@ add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEADER_FILES})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
"${structops_SOURCE_DIR}/include"
|
||||
"${spdlog_SOURCE_DIR}/include"
|
||||
"${taskflow_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
structopt
|
||||
spdlog
|
||||
Taskflow
|
||||
)
|
||||
|
||||
# Structopt includes an outdated version of magic_enum that breaks some default defines
|
||||
# This is needed to bypass it. Im not happy about it, but it is what it is
|
||||
target_link_options(build_script PRIVATE -Wl,--allow-multiple-definition)
|
||||
|
||||
|
||||
5
cmake/taskflow.cmake
Normal file
5
cmake/taskflow.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
CPMAddPackage (
|
||||
URI "gh:taskflow/taskflow@4.1.0"
|
||||
OPTIONS "TF_BUILD_EXAMPLES off"
|
||||
OPTIONS "TF_BUILD_TESTS off"
|
||||
)
|
||||
19
src/app.cpp
19
src/app.cpp
@@ -1,6 +1,10 @@
|
||||
#include "app.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "args.h"
|
||||
#include "logging.h"
|
||||
#include "taskflow/core/executor.hpp"
|
||||
|
||||
Application::Application(Options options)
|
||||
: m_DryRun(options.dryrun.value()),
|
||||
@@ -10,7 +14,7 @@ Application::Application(Options options)
|
||||
createAllLoggers();
|
||||
}
|
||||
|
||||
void Application::run() {
|
||||
void Application::assemble() {
|
||||
spdlog::get("app")->debug("Running command");
|
||||
switch (m_Command) {
|
||||
case build:
|
||||
@@ -29,7 +33,20 @@ void Application::run() {
|
||||
rebuildProject();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::save_graph(std::string filename) {
|
||||
spdlog::get("app")->info("Saving task flow graph to '{}'", filename);
|
||||
spdlog::get("app")->info(
|
||||
"You can use a website like "
|
||||
"'https://dreampuf.github.io/GraphvizOnline/?engine=dot' to view it.");
|
||||
std::ofstream os(filename);
|
||||
m_Taskflow.dump(os);
|
||||
}
|
||||
|
||||
void Application::run() {
|
||||
tf::Executor executor;
|
||||
executor.run(m_Taskflow).wait();
|
||||
spdlog::get("app")->info("All work done!");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,19 @@
|
||||
#define BUILD_SCRIPT_APP
|
||||
|
||||
#include <filesystem>
|
||||
#include <taskflow/taskflow.hpp>
|
||||
|
||||
#include "args.h"
|
||||
#include "logging.h"
|
||||
#include "taskflow/core/executor.hpp"
|
||||
#include "taskflow/core/taskflow.hpp"
|
||||
#include "types.h"
|
||||
|
||||
class Application {
|
||||
public:
|
||||
Application(Options options);
|
||||
void assemble();
|
||||
void save_graph(std::string filename);
|
||||
void run();
|
||||
|
||||
private:
|
||||
@@ -18,6 +23,8 @@ class Application {
|
||||
BuildType m_BuildType;
|
||||
Command m_Command;
|
||||
|
||||
tf::Taskflow m_Taskflow;
|
||||
|
||||
void createAllLoggers();
|
||||
|
||||
void buildProject();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef BUILD_SCRIPT_ARGS
|
||||
#define BUILD_SCRIPT_ARGS
|
||||
|
||||
#include <optional>
|
||||
#include <structopt/app.hpp>
|
||||
|
||||
#include "types.h"
|
||||
@@ -11,8 +12,9 @@ struct Options {
|
||||
|
||||
std::optional<bool> verbose = false;
|
||||
std::optional<bool> dryrun = false;
|
||||
std::optional<std::string> graphFilename;
|
||||
};
|
||||
STRUCTOPT(Options, command, buildType, verbose, dryrun);
|
||||
STRUCTOPT(Options, command, buildType, verbose, dryrun, graphFilename);
|
||||
|
||||
Options parse(int argc, char** argv);
|
||||
|
||||
|
||||
298
src/commands.cpp
298
src/commands.cpp
@@ -1,87 +1,247 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "app.h"
|
||||
#include "types.h"
|
||||
|
||||
void Application::buildProject() {
|
||||
checkBuildDirs();
|
||||
switch (m_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;
|
||||
auto checkBuildDirsTask =
|
||||
m_Taskflow.emplace([this]() { this->checkBuildDirs(); })
|
||||
.name("checkBuildDirs");
|
||||
if (m_BuildType == BuildType::none) {
|
||||
auto configureDirDebugTask =
|
||||
m_Taskflow
|
||||
.emplace(
|
||||
[this]() { this->configureDir("build/debug", "debug"); })
|
||||
.name("configureDir(build/debug)");
|
||||
auto buildDirDebugTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/debug"); })
|
||||
.name("buildDir(build/debug)");
|
||||
|
||||
configureDirDebugTask.precede(buildDirDebugTask);
|
||||
checkBuildDirsTask.precede(configureDirDebugTask);
|
||||
|
||||
auto configureDirReleaseTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/release", "Release");
|
||||
})
|
||||
.name("configureDir(build/release)");
|
||||
auto buildDirReleaseTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/release"); })
|
||||
.name("buildDir(build/release)");
|
||||
|
||||
configureDirReleaseTask.precede(buildDirReleaseTask);
|
||||
checkBuildDirsTask.precede(configureDirReleaseTask);
|
||||
|
||||
auto configureDirRelWithDebTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/relwithdeb", "RelWithDeb");
|
||||
})
|
||||
.name("configureDir(build/relwithdeb)");
|
||||
auto buildDirRelWithDebTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/relwithdeb"); })
|
||||
.name("buildDir(build/relwithdeb)");
|
||||
|
||||
configureDirRelWithDebTask.precede(buildDirRelWithDebTask);
|
||||
checkBuildDirsTask.precede(configureDirRelWithDebTask);
|
||||
|
||||
auto configureDirMinSizeRelTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/minsizerel", "MinSizeRel");
|
||||
})
|
||||
.name("configureDir(build/minsizerel)");
|
||||
auto buildDirMinSizeRelTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/minsizerel"); })
|
||||
.name("buildDir(build/minsizerel)");
|
||||
|
||||
configureDirMinSizeRelTask.precede(buildDirMinSizeRelTask);
|
||||
checkBuildDirsTask.precede(configureDirMinSizeRelTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::debug) {
|
||||
auto configureDirTask =
|
||||
m_Taskflow
|
||||
.emplace(
|
||||
[this]() { this->configureDir("build/debug", "debug"); })
|
||||
.name("configureDir(build/debug)");
|
||||
auto buildDirTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/debug"); })
|
||||
.name("buildDir(build/debug)");
|
||||
|
||||
configureDirTask.precede(buildDirTask);
|
||||
checkBuildDirsTask.precede(configureDirTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::release) {
|
||||
auto configureDirTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/release", "Release");
|
||||
})
|
||||
.name("configureDir(build/release)");
|
||||
auto buildDirTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/release"); })
|
||||
.name("buildDir(build/release)");
|
||||
|
||||
configureDirTask.precede(buildDirTask);
|
||||
checkBuildDirsTask.precede(configureDirTask);
|
||||
} else if (m_BuildType == BuildType::relwithdeb) {
|
||||
auto configureDirTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/relwithdeb", "RelWithDeb");
|
||||
})
|
||||
.name("configureDir(build/relwithdeb)");
|
||||
auto buildDirTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/relwithdeb"); })
|
||||
.name("buildDir(build/relwithdeb)");
|
||||
|
||||
configureDirTask.precede(buildDirTask);
|
||||
checkBuildDirsTask.precede(configureDirTask);
|
||||
} else if (m_BuildType == BuildType::minsizerel) {
|
||||
auto configureDirTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/minsizerel", "MinSizeRel");
|
||||
})
|
||||
.name("configureDir(build/minsizerel)");
|
||||
auto buildDirTask =
|
||||
m_Taskflow.emplace([this]() { this->buildDir("build/minsizerel"); })
|
||||
.name("buildDir(build/minsizerel)");
|
||||
|
||||
configureDirTask.precede(buildDirTask);
|
||||
checkBuildDirsTask.precede(configureDirTask);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::configureProject() {
|
||||
checkBuildDirs();
|
||||
switch (m_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/relwithbeb", "RelWithDeb");
|
||||
break;
|
||||
case minsizerel:
|
||||
configureDir("build/minsizerel", "MinSizeRel");
|
||||
break;
|
||||
auto checkBuildDirsTask =
|
||||
m_Taskflow.emplace([this]() { this->checkBuildDirs(); })
|
||||
.name("checkBuildDirs");
|
||||
if (m_BuildType == BuildType::none) {
|
||||
auto configureDirDebugTask =
|
||||
m_Taskflow
|
||||
.emplace(
|
||||
[this]() { this->configureDir("build/debug", "debug"); })
|
||||
.name("configureDir(build/debug)");
|
||||
checkBuildDirsTask.precede(configureDirDebugTask);
|
||||
|
||||
auto configureDirReleaseTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/release", "Release");
|
||||
})
|
||||
.name("configureDir(build/release)");
|
||||
checkBuildDirsTask.precede(configureDirReleaseTask);
|
||||
|
||||
auto configureDirRelWithDebTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/relwithdeb", "RelWithDeb");
|
||||
})
|
||||
.name("configureDir(build/relwithdeb)");
|
||||
checkBuildDirsTask.precede(configureDirRelWithDebTask);
|
||||
|
||||
auto configureDirMinSizeRelTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/minsizerel", "MinSizeRel");
|
||||
})
|
||||
.name("configureDir(build/minsizerel)");
|
||||
checkBuildDirsTask.precede(configureDirMinSizeRelTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::debug) {
|
||||
auto configureDirDebugTask =
|
||||
m_Taskflow
|
||||
.emplace(
|
||||
[this]() { this->configureDir("build/debug", "debug"); })
|
||||
.name("configureDir(build/debug)");
|
||||
checkBuildDirsTask.precede(configureDirDebugTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::release) {
|
||||
auto configureDirReleaseTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/release", "Release");
|
||||
})
|
||||
.name("configureDir(build/release)");
|
||||
checkBuildDirsTask.precede(configureDirReleaseTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::relwithdeb) {
|
||||
auto configureDirRelWithDebTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/relwithdeb", "RelWithDeb");
|
||||
})
|
||||
.name("configureDir(build/relwithdeb)");
|
||||
checkBuildDirsTask.precede(configureDirRelWithDebTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::minsizerel) {
|
||||
auto configureDirMinSizeRelTask =
|
||||
m_Taskflow
|
||||
.emplace([this]() {
|
||||
this->configureDir("build/minsizerel", "MinSizeRel");
|
||||
})
|
||||
.name("configureDir(build/minsizerel)");
|
||||
checkBuildDirsTask.precede(configureDirMinSizeRelTask);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::cleanProject() {
|
||||
checkBuildDirs();
|
||||
auto checkBuildDirsTask =
|
||||
m_Taskflow.emplace([this]() { this->checkBuildDirs(); })
|
||||
.name("checkBuildDirs");
|
||||
|
||||
switch (m_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;
|
||||
if (m_BuildType == BuildType::none) {
|
||||
auto cleanDirDebugTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/debug"); })
|
||||
.name("cleanDir(build/debug)");
|
||||
checkBuildDirsTask.precede(cleanDirDebugTask);
|
||||
|
||||
auto cleanDirReleaseTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/release"); })
|
||||
.name("cleanDir(build/release)");
|
||||
checkBuildDirsTask.precede(cleanDirReleaseTask);
|
||||
|
||||
auto cleanDirRelWithDebTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/relwithdeb"); })
|
||||
.name("cleanDir(build/relwithdeb)");
|
||||
checkBuildDirsTask.precede(cleanDirRelWithDebTask);
|
||||
auto cleanDirMinSizeRelTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/minsizerel"); })
|
||||
.name("cleanDir(build/minsizerel)");
|
||||
checkBuildDirsTask.precede(cleanDirMinSizeRelTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::debug) {
|
||||
auto cleanDirDebugTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/debug"); })
|
||||
.name("cleanDir(build/debug)");
|
||||
checkBuildDirsTask.precede(cleanDirDebugTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::release) {
|
||||
auto cleanDirReleaseTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/release"); })
|
||||
.name("cleanDir(build/release)");
|
||||
checkBuildDirsTask.precede(cleanDirReleaseTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::relwithdeb) {
|
||||
auto cleanDirRelWithDebTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/relwithdeb"); })
|
||||
.name("cleanDir(build/relwithdeb)");
|
||||
checkBuildDirsTask.precede(cleanDirRelWithDebTask);
|
||||
|
||||
} else if (m_BuildType == BuildType::minsizerel) {
|
||||
auto cleanDirMinSizeRelTask =
|
||||
m_Taskflow.emplace([this]() { this->cleanDir("build/minsizerel"); })
|
||||
.name("cleanDir(build/minsizerel)");
|
||||
checkBuildDirsTask.precede(cleanDirMinSizeRelTask);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::deleteProject() {
|
||||
// No point in using taskflow for this...
|
||||
// In all cases its just deleting a single directory...
|
||||
// Bit overkill for that
|
||||
switch (m_BuildType) {
|
||||
case none:
|
||||
deleteDir("build");
|
||||
@@ -103,7 +263,5 @@ void Application::deleteProject() {
|
||||
|
||||
void Application::rebuildProject() {
|
||||
deleteProject();
|
||||
checkBuildDirs();
|
||||
configureProject();
|
||||
buildProject();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ void createLogger(const char* name, const char* filename, const bool verbose) {
|
||||
if (verbose)
|
||||
logger->set_level(spdlog::level::debug);
|
||||
else
|
||||
logger->set_level(spdlog::level::warn);
|
||||
logger->set_level(spdlog::level::info);
|
||||
#endif
|
||||
|
||||
spdlog::register_logger(logger);
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
int main(const int argc, char** argv) {
|
||||
Options options = parse(argc, argv);
|
||||
Application app(options);
|
||||
app.assemble();
|
||||
if (options.graphFilename.has_value()) {
|
||||
app.save_graph(options.graphFilename.value());
|
||||
spdlog::get("app")->info("Exiting..");
|
||||
return 0;
|
||||
}
|
||||
|
||||
app.run();
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user