From 5af6d0080a336a3c21a6b52596eb8501799bdeb6 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Thu, 15 May 2025 15:25:06 +0200 Subject: [PATCH] defines --- Crafter.Build-Configuration.cpp | 11 +++- Crafter.Build-Configuration.cppm | 12 +++- Crafter.Build-Dependency.cppm | 1 + Crafter.Build-ModuleFile.cpp | 23 +++++--- Crafter.Build-ModuleFile.cppm | 1 - Crafter.Build-Project.cpp | 96 ++++++++++++++------------------ Crafter.Build-Project.cppm | 14 ++--- Crafter.Build-SourceFile.cpp | 8 ++- 8 files changed, 93 insertions(+), 73 deletions(-) diff --git a/Crafter.Build-Configuration.cpp b/Crafter.Build-Configuration.cpp index 781988e..c7bbf9d 100644 --- a/Crafter.Build-Configuration.cpp +++ b/Crafter.Build-Configuration.cpp @@ -25,7 +25,7 @@ module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; -Configuration::Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose): name(name), standard(standard), sourceFiles(sourceFiles), moduleFiles(moduleFiles), optimizationLevel(optimizationLevel), buildDir(buildDir), outputDir(outputDir), type(type), target(target), march(march), dependencies(dependencies), additionalFiles(additionalFiles), flags(flags), debug(debug), libs(libs), lib_paths(lib_paths), c_files(c_files), shaderFiles(shaderFiles), includeDirs(includeDirs), verbose(verbose) { +Configuration::Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose, std::vector defines): name(name), standard(standard), sourceFiles(sourceFiles), moduleFiles(moduleFiles), optimizationLevel(optimizationLevel), buildDir(buildDir), outputDir(outputDir), type(type), target(target), march(march), dependencies(dependencies), additionalFiles(additionalFiles), flags(flags), debug(debug), libs(libs), lib_paths(lib_paths), c_files(c_files), shaderFiles(shaderFiles), includeDirs(includeDirs), verbose(verbose), defines(defines) { } @@ -83,6 +83,12 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json const std::filesystem::path fullFilePath = workingDir / filePath; shaderFiles.emplace_back(fullFilePath, it["entrypoint"].get(), static_cast(it["type"].get())); } + } else if(key == "defines") { + for (auto it : val) { + std::string name = it["name"].get(); + std::string value = it["value"].get(); + defines.emplace_back(name, value); + } } else if(key == "additional_files") { const std::vector tempAdditionalFiles = val.get>(); additionalFiles = std::vector(tempAdditionalFiles.size()); @@ -182,6 +188,9 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json if(!extendData.includeDirs.empty()){ includeDirs.insert(includeDirs.end(), extendData.includeDirs.begin(), extendData.includeDirs.end()); } + if(!extendData.defines.empty()){ + defines.insert(defines.end(), extendData.defines.begin(), extendData.defines.end()); + } break; } } diff --git a/Crafter.Build-Configuration.cppm b/Crafter.Build-Configuration.cppm index 346876d..bee8d6c 100644 --- a/Crafter.Build-Configuration.cppm +++ b/Crafter.Build-Configuration.cppm @@ -23,6 +23,7 @@ module; #include #include "json.hpp" #include +#include export module Crafter.Build:Configuration; import :Dependency; import :Shader; @@ -30,6 +31,14 @@ import :Shader; namespace fs = std::filesystem; export namespace Crafter::Build { + struct Define { + std::string name; + std::string value; + std::string ToString() const { + return std::format(" -D {}={}", name, value); + } + }; + class Configuration { public: std::string name; @@ -40,6 +49,7 @@ export namespace Crafter::Build { std::vector shaderFiles; std::vector additionalFiles; std::vector includeDirs; + std::vector defines; std::string optimizationLevel; std::string buildDir; std::string outputDir; @@ -53,7 +63,7 @@ export namespace Crafter::Build { std::unordered_map additionalProperties; std::vector flags; bool verbose = false; - Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose); + Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose, std::vector defines); Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir); }; } diff --git a/Crafter.Build-Dependency.cppm b/Crafter.Build-Dependency.cppm index 506cdb8..835102c 100644 --- a/Crafter.Build-Dependency.cppm +++ b/Crafter.Build-Dependency.cppm @@ -29,6 +29,7 @@ export namespace Crafter::Build { std::string configuration; std::string commit; std::string branch; + std::string name; Dependency(std::string path, std::string configuration, std::string commit, std::string branch); }; } diff --git a/Crafter.Build-ModuleFile.cpp b/Crafter.Build-ModuleFile.cpp index bc0b4e6..0ba86bd 100644 --- a/Crafter.Build-ModuleFile.cpp +++ b/Crafter.Build-ModuleFile.cpp @@ -55,10 +55,8 @@ ModulePartition::ModulePartition(const std::string& name, const fs::path& path, } if(!fs::exists((pcmDir/path.filename()).generic_string()+".pcm")) { needsRecompiling = true; - needsRecompilingDependency = true; } else if(fs::last_write_time(path.generic_string()+".cppm") > fs::last_write_time((pcmDir/path.filename()).generic_string()+".pcm")) { needsRecompiling = true; - needsRecompilingDependency = true; } } @@ -77,7 +75,7 @@ void ModulePartition::AddDependants() { void ModulePartition::Check() { if(!needsRecompiling) { for(ModulePartition* dependency : partitionDependenciesP) { - if(dependency->needsRecompilingDependency) { + if(dependency->needsRecompiling) { needsRecompiling = true; break; } @@ -87,12 +85,16 @@ void ModulePartition::Check() { void ModulePartition::Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags) { if(needsRecompiling) { + std::string defines; + for(const Define& define : config.defines) { + defines+=define.ToString(); + } for(ModulePartition* dependency : partitionDependenciesP) { if(dependency->needsRecompiling) { dependency->compiled->wait(false); } } - std::string command = std::format("{} {} -std={} {}.cppm --precompile {} -fprebuilt-module-path={} -o {}.pcm {}", clangDir, flags, config.standard, path.generic_string(), march, pcmDir.generic_string(), (pcmDir/path.filename()).generic_string(), target); + std::string command = std::format("{} {} {} -std={} {}.cppm --precompile {} -fprebuilt-module-path={} -o {}.pcm {}", clangDir, defines, flags, config.standard, path.generic_string(), march, pcmDir.generic_string(), (pcmDir/path.filename()).generic_string(), target); if(config.verbose) { std::cout << command << std::endl; } @@ -102,7 +104,11 @@ void ModulePartition::Compile(std::string clangDir, const Configuration& config, compiled->notify_all(); } void ModulePartition::CompileSource(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const fs::path& buildDir) { - std::string command = std::format("{} -std={} {}.pcm -fprebuilt-module-path={} -c -O{} {} {} -o {}.o {}", clangDir, config.standard, (pcmDir/path.filename()).generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (buildDir/path.filename()).generic_string(), target); + std::string defines; + for(const Define& define : config.defines) { + defines+=define.ToString(); + } + std::string command = std::format("{} {} -std={} {}.pcm -fprebuilt-module-path={} -c -O{} {} {} -o {}.o {}", clangDir, defines, config.standard, (pcmDir/path.filename()).generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (buildDir/path.filename()).generic_string(), target); if(config.verbose) { std::cout << command << std::endl; } @@ -145,9 +151,12 @@ void Module::Check() { val.Check(); } - for(auto& [key, val] : partitions) {; - if(val.needsRecompilingDependency) { + for(auto& [key, val] : partitions) { + if(val.needsRecompiling) { needsRecompiling = true; + for(auto& [key, val] : partitions) { + val.needsRecompiling = true; + } break; } } diff --git a/Crafter.Build-ModuleFile.cppm b/Crafter.Build-ModuleFile.cppm index dfb0227..1fd0837 100644 --- a/Crafter.Build-ModuleFile.cppm +++ b/Crafter.Build-ModuleFile.cppm @@ -36,7 +36,6 @@ export namespace Crafter::Build { class ModulePartition { public: - bool needsRecompilingDependency = false; bool needsRecompiling = false; fs::path path; Module* parent; diff --git a/Crafter.Build-Project.cpp b/Crafter.Build-Project.cpp index 41ac7e9..a7902ef 100644 --- a/Crafter.Build-Project.cpp +++ b/Crafter.Build-Project.cpp @@ -30,73 +30,54 @@ module; #include #include #include +#include module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; - -std::vector mergeUnique(const std::vector& vec1, const std::vector& vec2) { - std::unordered_set uniqueElements; - std::vector result; - - for (const auto& str : vec1) { - if (uniqueElements.insert(str).second) { - result.push_back(str); - } - } - - for (const auto& str : vec2) { - if (uniqueElements.insert(str).second) { - result.push_back(str); - } - } - - return result; -} - Project::Project(std::string name, fs::path path, std::vector configurations) : name(name), path(path), configurations(configurations) { } -void Project::Build(std::string configuration) const { - for(const Configuration& config : configurations) { +const Configuration& Project::Build(std::string configuration) { + for(Configuration& config : configurations) { if(config.name == configuration){ Build(config); - return; + return config; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -void Project::Build(std::string configuration, fs::path outputDir) const { - for(const Configuration& config : configurations) { +const Configuration& Project::Build(std::string configuration, fs::path outputDir) { + for(Configuration& config : configurations) { if(config.name == configuration){ Build(config, outputDir); - return; + return config; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -void Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) const { - for(const Configuration& config : configurations) { +const Configuration& Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) { + for(Configuration& config : configurations) { if(config.name == configuration){ Build(config, outputDir, binDir); - return; + return config; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -void Project::Build(Configuration configuration) const { +void Project::Build(Configuration& configuration) { Build(configuration, configuration.outputDir); } -void Project::Build(Configuration config, fs::path outputDir) const { +void Project::Build(Configuration& config, fs::path outputDir) { Build(config, outputDir, outputDir); } -void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) const { +void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) { if(config.standard.empty()) { config.standard = "c++26"; } @@ -149,7 +130,7 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c } for(Shader& shader : config.shaderFiles) { - shader.Compile(outputDir); + shader.Compile(binDir); } std::vector depThreads = std::vector(config.dependencies.size()); @@ -157,7 +138,7 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c if(config.dependencies.size() > 0){ libs += std::format(" -L{}", pcmDir.generic_string()); } - + std::unordered_set depLibSet; for(std::int_fast32_t i = 0; i < depThreads.size(); i++) { if(config.dependencies[i].path.ends_with(".git")) { fs::path name = fs::path(config.dependencies[i].path).filename(); @@ -176,26 +157,37 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c } config.dependencies[i].path = fs::path(config.dependencies[i].path).filename().replace_extension(); Project project = Project::LoadFromJSON(fs::path(buildDir)/config.dependencies[i].path/"project.json"); - libs+=std::format(" -l{}", project.name); - depThreads[i] = std::thread([i, pcmDir, config, project, binDir]() { - project.Build(config.dependencies[i].configuration, pcmDir, binDir); - }); - for(const Configuration& config2 : project.configurations) { - if(config2.name == config.dependencies[i].configuration){ - config.libs = mergeUnique(config.libs, config2.libs); - break; + config.dependencies[i].name = project.name; + if (depLibSet.insert(project.name).second) { + libs+=std::format(" -l{}", project.name); + } + const Configuration& depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir); + for(const std::string& lib2 : depConfig.libs) { + if (depLibSet.insert(lib2).second) { + libs+=std::format(" -l{}", lib2); + } + } + for(const Dependency& dep2 : depConfig.dependencies) { + if (depLibSet.insert(dep2.name).second) { + libs+=std::format(" -l{}", dep2.name); } } } else{ Project project = Project::LoadFromJSON(config.dependencies[i].path); - libs+=std::format(" -l{}", project.name); - depThreads[i] = std::thread([i, pcmDir, config, project, binDir]() { - project.Build(config.dependencies[i].configuration, pcmDir, binDir); - }); - for(const Configuration& config2 : project.configurations) { - if(config2.name == config.dependencies[i].configuration){ - config.libs = mergeUnique(config.libs, config2.libs); - break; + config.dependencies[i].name = project.name; + + if (depLibSet.insert(project.name).second) { + libs+=std::format(" -l{}", project.name); + } + const Configuration& depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir); + for(const std::string& lib2 : depConfig.libs) { + if (depLibSet.insert(lib2).second) { + libs+=std::format(" -l{}", lib2); + } + } + for(const Dependency& dep2 : depConfig.dependencies) { + if (depLibSet.insert(dep2.name).second) { + libs+=std::format(" -l{}", dep2.name); } } } @@ -231,10 +223,6 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c libs+= std::format(" -l{}",lib); } - for(std::thread& thread : depThreads){ - thread.join(); - } - std::string march; if(config.target != "wasm32-unknown-wasi"){ march = std::format("-march={}", config.march); diff --git a/Crafter.Build-Project.cppm b/Crafter.Build-Project.cppm index 16ed230..b0251d1 100644 --- a/Crafter.Build-Project.cppm +++ b/Crafter.Build-Project.cppm @@ -33,13 +33,13 @@ export namespace Crafter::Build { fs::path path; std::vector configurations; Project(std::string name, fs::path path, std::vector configurations); - void Build(std::string configuration) const; - void Build(std::string configuration, fs::path outputDir) const; - void Build(std::string configuration, fs::path outputDir, fs::path binDir) const; - void Build(Configuration configuration) const; - void Build(Configuration configuration, fs::path outputDir) const; - void Build(Configuration configuration, fs::path outputDir, fs::path binDir) const; - void SaveToJSON(fs::path path) const; + const Configuration& Build(std::string configuration); + const Configuration& Build(std::string configuration, fs::path outputDir); + const Configuration& Build(std::string configuration, fs::path outputDir, fs::path binDir); + void Build(Configuration& configuration); + void Build(Configuration& configuration, fs::path outputDir); + void Build(Configuration& configuration, fs::path outputDir, fs::path binDir); + void SaveToJSON(fs::path path); static Project LoadFromJSON(fs::path path); }; } diff --git a/Crafter.Build-SourceFile.cpp b/Crafter.Build-SourceFile.cpp index fcc09c5..7f32cdf 100644 --- a/Crafter.Build-SourceFile.cpp +++ b/Crafter.Build-SourceFile.cpp @@ -31,11 +31,15 @@ using namespace Crafter::Build; namespace fs = std::filesystem; void Source::GetSourceFiles(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, std::vector& threads, const std::vector& modules, std::string& files, const fs::path& buildDir) { + std::string defines; + for(const Define& define : config.defines) { + defines+=define.ToString(); + } for(const fs::path& sourceFile : config.sourceFiles) { files+=std::format("{}_source.o ",(buildDir/sourceFile.filename()).generic_string()); if(Source::Check(sourceFile, modules, config, buildDir)) { - threads.emplace_back([&config, sourceFile, pcmDir, target, clangDir, flags, march, buildDir](){ - std::string command = std::format("{} -std={} {}.cpp -fprebuilt-module-path={} -c -O{} {} {} -o {}_source.o {}", clangDir, config.standard, sourceFile.generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (buildDir/sourceFile.filename()).generic_string(), target); + threads.emplace_back([&config, sourceFile, pcmDir, target, clangDir, flags, march, buildDir, defines](){ + std::string command = std::format("{} {} -std={} {}.cpp -fprebuilt-module-path={} -c -O{} {} {} -o {}_source.o {}", clangDir, defines, config.standard, sourceFile.generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (buildDir/sourceFile.filename()).generic_string(), target); if(config.verbose) { std::cout << command << std::endl; }