diff --git a/Crafter.Build-Bounce.cppm b/Crafter.Build-Bounce.cppm index c334f36..2a6e50c 100644 --- a/Crafter.Build-Bounce.cppm +++ b/Crafter.Build-Bounce.cppm @@ -25,36 +25,65 @@ module; #include #include #include +#include +#include export module Crafter.Build:Bounce; -export void BounceCommand(const std::string& cmd) { - // std::array buffer; - // std::string result; +namespace Crafter::Build { + export std::string RunCommand(const std::string_view cmd) { + std::array buffer; + std::string result; - // std::string with = cmd + " 2>&1"; - // // Open pipe to file - // FILE* pipe = popen(with.c_str(), "r"); - // if (!pipe) throw std::runtime_error("popen() failed!"); + std::string with = std::string(cmd) + " 2>&1"; + // Open pipe to file + FILE* pipe = popen(with.c_str(), "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); - // // Read till end of process: - // while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { - // result += buffer.data(); - // } + // Read till end of process: + while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { + result += buffer.data(); + } - // // Close pipe - // auto returnCode = pclose(pipe); - // if (returnCode != 0) { - // // Optional: handle non-zero exit status - // } + // Close pipe + pclose(pipe); + return result; + } + export void RunCommandIgnore(const std::string_view cmd) { + std::string with = std::string(cmd) + " > /dev/null 2>&1"; + FILE* pipe = popen(with.c_str(), "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); + pclose(pipe); + } - // std::cout << result; - system(cmd.c_str()); -} + export struct ClangError { + std::string filename; + uint32_t line_number; + std::string error_message; + std::string code; + }; -export void BounceCommandIgnore(const std::string& cmd) { - std::string with = cmd + " > /dev/null 2>&1"; - FILE* pipe = popen(with.c_str(), "r"); - if (!pipe) throw std::runtime_error("popen() failed!"); - pclose(pipe); + export std::vector RunClang(const std::string_view cmd) { + std::string result = RunCommand(cmd); + std::vector errors; + + std::regex error_regex(R"((/[^:]+\.cpp):(\d+):\d+: error: (.*)\n\s*[0-9| ]*\s*(.*))"); + std::smatch match; + + while (std::regex_search(result, match, error_regex)) { + ClangError error; + error.filename = match[1].str(); + error.line_number = std::stoi(match[2].str()); + error.error_message = match[3].str(); + error.code = match[4].str(); + errors.push_back(error); + result = match.suffix().str(); + } + + if(result != "" && errors.size() == 0) { + throw std::runtime_error(result); + } + + return errors; + } } \ No newline at end of file diff --git a/Crafter.Build-ModuleFile.cpp b/Crafter.Build-ModuleFile.cpp index 9bc8b76..127cc61 100644 --- a/Crafter.Build-ModuleFile.cpp +++ b/Crafter.Build-ModuleFile.cpp @@ -26,6 +26,7 @@ module; #include #include #include +#include module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; @@ -83,7 +84,8 @@ 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) { +std::vector ModulePartition::Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags) { + std::vector errors; if(needsRecompiling) { std::string defines; for(const Define& define : config.defines) { @@ -98,12 +100,13 @@ void ModulePartition::Compile(std::string clangDir, const Configuration& config, if(config.verbose) { std::cout << command << std::endl; } - BounceCommand(command.c_str()); + errors = RunClang(command); } *compiled = true; compiled->notify_all(); + return errors; } -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::vector 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 defines; for(const Define& define : config.defines) { defines+=define.ToString(); @@ -112,7 +115,7 @@ void ModulePartition::CompileSource(std::string clangDir, const Configuration& c if(config.verbose) { std::cout << command << std::endl; } - BounceCommand(command.c_str()); + return RunClang(command); } Module::Module(const std::string& name, const fs::path& path, const Configuration& config, const fs::path& pcmDir, std::string& files, const fs::path& buildDir) : name(name), path(path) { @@ -162,18 +165,25 @@ void Module::Check() { } } -void Module::Compile(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::vector Module::Compile(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 defines; for(const Define& define : config.defines) { defines+=define.ToString(); } + std::mutex errorMutex; + std::vector errors; std::vector threads; for(auto& [key, val] : partitions) {; if(val.needsRecompiling) { - threads.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags](){ - val.Compile(clangDir, config, pcmDir, target, march, flags); + threads.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &errors, &errorMutex](){ + std::vector newErrors = val.Compile(clangDir, config, pcmDir, target, march, flags); + if(newErrors.size() > 0) { + errorMutex.lock(); + errors.insert(errors.end(), newErrors.begin(), newErrors.end()); + errorMutex.unlock(); + } }); } } @@ -182,36 +192,56 @@ void Module::Compile(std::string clangDir, const Configuration& config, fs::path thread.join(); } + if(errors.size() > 0) { + return errors; + } + { 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; } - BounceCommand(command.c_str()); + errors = RunClang(command); + } + + if(errors.size() > 0) { + return errors; } std::vector threads2; for(auto& [key, val] : partitions) {; if(val.needsRecompiling) { - threads2.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir](){ - val.CompileSource(clangDir, config, pcmDir, target, march, flags, buildDir); + threads2.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir, &errors, &errorMutex](){ + std::vector newErrors = val.CompileSource(clangDir, config, pcmDir, target, march, flags, buildDir); + if(newErrors.size() > 0) { + errorMutex.lock(); + errors.insert(errors.end(), newErrors.begin(), newErrors.end()); + errorMutex.unlock(); + } }); } } - threads2.emplace_back([this, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir, &defines](){ + threads2.emplace_back([this, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir, &defines, &errors, &errorMutex](){ 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; } - BounceCommand(command.c_str()); + std::vector newErrors = RunClang(command); + if(newErrors.size() > 0) { + errorMutex.lock(); + errors.insert(errors.end(), newErrors.begin(), newErrors.end()); + errorMutex.unlock(); + } }); for(std::thread& thread : threads2){ thread.join(); } + + return errors; } -std::vector Module::GetModules(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, std::string& files, const fs::path& buildDir) { +std::tuple, std::vector> Module::GetModules(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, std::string& files, const fs::path& buildDir) { std::vector modules; for(const fs::path& file: config.moduleFiles) { std::ifstream t(file.generic_string()+".cppm"); @@ -225,9 +255,16 @@ std::vector Module::GetModules(std::string clangDir, const Configuration modules.emplace_back(match[1], file, config, pcmDir, files, buildDir); } } - std::for_each(std::execution::par, modules.begin(), modules.end(), [&clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir](Module& modulee) { + std::vector errors; + std::mutex errorMutex; + std::for_each(std::execution::par, modules.begin(), modules.end(), [&clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir, &errors, &errorMutex](Module& modulee) { modulee.Check(); - modulee.Compile(clangDir, config, pcmDir, target, march, flags, buildDir); + std::vector newErrors = modulee.Compile(clangDir, config, pcmDir, target, march, flags, buildDir); + if(newErrors.size() > 0) { + errorMutex.lock(); + errors.insert(errors.end(), newErrors.begin(), newErrors.end()); + errorMutex.unlock(); + } }); - return modules; + return {modules, errors}; } \ No newline at end of file diff --git a/Crafter.Build-ModuleFile.cppm b/Crafter.Build-ModuleFile.cppm index 1fd0837..3ad1a6e 100644 --- a/Crafter.Build-ModuleFile.cppm +++ b/Crafter.Build-ModuleFile.cppm @@ -26,9 +26,11 @@ module; #include #include #include -#include +#include +#include export module Crafter.Build:ModuleFile; import :Configuration; +import :Bounce; namespace fs = std::filesystem; export namespace Crafter::Build { @@ -48,8 +50,8 @@ export namespace Crafter::Build { ModulePartition(const std::string& name, const fs::path& path, Module* parent, const std::string& fileContent, const fs::path& pcmDir); void AddDependants(); void Check(); - void Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags); - void 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::vector Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags); + std::vector 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); }; class Module { @@ -60,7 +62,7 @@ export namespace Crafter::Build { const fs::path path; Module(const std::string& name, const fs::path& path, const Configuration& config, const fs::path& pcmDir, std::string& files, const fs::path& buildDir); void Check(); - void Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const fs::path& buildDir); - static std::vector GetModules(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, std::string& files, const fs::path& buildDir); + std::vector Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const fs::path& buildDir); + static std::tuple, std::vector> GetModules(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, std::string& files, const fs::path& buildDir); }; } diff --git a/Crafter.Build-Project.cpp b/Crafter.Build-Project.cpp index d298bac..47c036d 100644 --- a/Crafter.Build-Project.cpp +++ b/Crafter.Build-Project.cpp @@ -31,6 +31,7 @@ module; #include #include #include +#include module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; @@ -39,45 +40,42 @@ Project::Project(std::string name, fs::path path, std::vector con } -const Configuration& Project::Build(std::string configuration) { +std::tuple> Project::Build(std::string configuration) { for(Configuration& config : configurations) { if(config.name == configuration){ - Build(config); - return config; + return {config, Build(config)}; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -const Configuration& Project::Build(std::string configuration, fs::path outputDir) { +std::tuple> Project::Build(std::string configuration, fs::path outputDir) { for(Configuration& config : configurations) { if(config.name == configuration){ - Build(config, outputDir); - return config; + return {config, Build(config, outputDir)}; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -const Configuration& Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) { +std::tuple> Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) { for(Configuration& config : configurations) { if(config.name == configuration){ - Build(config, outputDir, binDir); - return config; + return {config, Build(config, outputDir, binDir)}; } } throw std::runtime_error("Configuration: " + configuration + " not found."); } -void Project::Build(Configuration& configuration) { - Build(configuration, configuration.outputDir); +std::vector Project::Build(Configuration& configuration) { + return Build(configuration, configuration.outputDir); } -void Project::Build(Configuration& config, fs::path outputDir) { - Build(config, outputDir, outputDir); +std::vector Project::Build(Configuration& config, fs::path outputDir) { + return Build(config, outputDir, outputDir); } -void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) { +std::vector Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) { if(config.standard.empty()) { config.standard = "c++26"; } @@ -161,13 +159,16 @@ void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) 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) { + std::tuple> depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir); + if(std::get<1>(depConfig).size() > 0) { + return std::get<1>(depConfig); + } + for(const std::string& lib2 : std::get<0>(depConfig).libs) { if (depLibSet.insert(lib2).second) { libs+=std::format(" -l{}", lib2); } } - for(const Dependency& dep2 : depConfig.dependencies) { + for(const Dependency& dep2 : std::get<0>(depConfig).dependencies) { if (depLibSet.insert(dep2.name).second) { libs+=std::format(" -l{}", dep2.name); } @@ -179,13 +180,16 @@ void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) 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) { + std::tuple> depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir); + if(std::get<1>(depConfig).size() > 0) { + return std::get<1>(depConfig); + } + for(const std::string& lib2 : std::get<0>(depConfig).libs) { + if (depLibSet.insert(lib2).second) { libs+=std::format(" -l{}", lib2); } } - for(const Dependency& dep2 : depConfig.dependencies) { + for(const Dependency& dep2 : std::get<0>(depConfig).dependencies) { if (depLibSet.insert(dep2.name).second) { libs+=std::format(" -l{}", dep2.name); } @@ -229,17 +233,24 @@ void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) } std::string files; - std::vector modules = Module::GetModules(clangDir, config, pcmDir, target, march, flags, files, buildDir); + std::tuple, std::vector> modules = Module::GetModules(clangDir, config, pcmDir, target, march, flags, files, buildDir); + + if(std::get<1>(modules).size() > 0) { + return std::get<1>(modules); + } + + std::vector errors = Source::GetSourceFiles(clangDir, config, pcmDir, target, march, flags, std::get<0>(modules), files, buildDir); + if(errors.size() > 0) { + return errors; + } std::vector threads; - Source::GetSourceFiles(clangDir, config, pcmDir, target, march, flags, threads, modules, files, buildDir); - for(std::uint_fast32_t i = 0; i < config.c_files.size(); i++) { files+=std::format("{}_source.o ",(buildDir/config.c_files[i].filename()).generic_string()); if(!fs::exists((buildDir/config.c_files[i].filename()).generic_string()+"_source.o") || fs::last_write_time(config.c_files[i].generic_string()+".c") > fs::last_write_time((buildDir/config.c_files[i].filename()).generic_string()+"_source.o")) { threads.emplace_back([i, &config, pcmDir, target, clangDir, flags, march, &buildDir](){ - BounceCommand(std::format("clang {}.c -c -O{} {} {} -o {}_source.o {}", config.c_files[i].generic_string(), config.optimizationLevel, march, flags, (buildDir/config.c_files[i].filename()).generic_string(), target).c_str()); + RunCommand(std::format("clang {}.c -c -O{} {} {} -o {}_source.o {}", config.c_files[i].generic_string(), config.optimizationLevel, march, flags, (buildDir/config.c_files[i].filename()).generic_string(), target).c_str()); }); } } @@ -249,19 +260,18 @@ void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) } if(config.type == "executable"){ - if(config.target == "x86_64-w64-mingw64" || config.target == "x86_64-w64-mingw32") { - flags += " -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread"; - name += ".exe"; - } std::string command = std::format("{} {} {}-O{} -o {} {} {} -fuse-ld=lld", clangDir, flags, files, config.optimizationLevel, (outputDir/name).generic_string(), target, libs); if(config.verbose) { std::cout << command << std::endl; } - BounceCommand(command.c_str()); + std::vector errors = RunClang(command); + if(errors.size() > 0) { + return errors; + } } else if(config.type == "library"){ - BounceCommandIgnore(std::format("ar r {}.a {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); + RunCommandIgnore(std::format("ar r {}.a {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); } else if(config.type == "shared-library"){ - BounceCommandIgnore(std::format("ar r {}.so {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); + RunCommandIgnore(std::format("ar r {}.so {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); } for(const fs::path& additionalFile : config.additionalFiles){ @@ -272,6 +282,7 @@ void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) fs::copy(additionalFile, binDir); } } + return {}; } Project Project::LoadFromJSON(fs::path path) { diff --git a/Crafter.Build-Project.cppm b/Crafter.Build-Project.cppm index b0251d1..8e33a30 100644 --- a/Crafter.Build-Project.cppm +++ b/Crafter.Build-Project.cppm @@ -22,8 +22,10 @@ module; #include #include #include +#include export module Crafter.Build:Project; import :Configuration; +import :Bounce; namespace fs = std::filesystem; export namespace Crafter::Build { @@ -33,12 +35,12 @@ export namespace Crafter::Build { fs::path path; std::vector configurations; Project(std::string name, fs::path path, std::vector configurations); - 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); + std::tuple> Build(std::string configuration); + std::tuple> Build(std::string configuration, fs::path outputDir); + std::tuple> Build(std::string configuration, fs::path outputDir, fs::path binDir); + std::vector Build(Configuration& configuration); + std::vector Build(Configuration& configuration, fs::path outputDir); + std::vector 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 a464c42..cf53674 100644 --- a/Crafter.Build-SourceFile.cpp +++ b/Crafter.Build-SourceFile.cpp @@ -25,28 +25,41 @@ module; #include #include #include +#include #include module Crafter.Build; 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::vector Source::GetSourceFiles(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const std::vector& modules, std::string& files, const fs::path& buildDir) { std::string defines; for(const Define& define : config.defines) { defines+=define.ToString(); } + std::vector threads; + std::mutex errorMutex; + std::vector errors; 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, defines](){ + threads.emplace_back([&config, sourceFile, pcmDir, target, clangDir, flags, march, buildDir, defines, &errors, &errorMutex]() { 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; } - BounceCommand(command.c_str()); + std::vector newErrors = RunClang(command); + if(newErrors.size() > 0) { + errorMutex.lock(); + errors.insert(errors.end(), newErrors.begin(), newErrors.end()); + errorMutex.unlock(); + } }); } } + for(std::thread& thread : threads){ + thread.join(); + } + return errors; } bool Source::Check(const fs::path& path, const std::vector& modules, const Configuration& config, const fs::path& buildDir) { diff --git a/Crafter.Build-SourceFile.cppm b/Crafter.Build-SourceFile.cppm index 36674e3..14e6326 100644 --- a/Crafter.Build-SourceFile.cppm +++ b/Crafter.Build-SourceFile.cppm @@ -35,7 +35,7 @@ namespace fs = std::filesystem; namespace Crafter::Build { class Source { public: - static void 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); + static std::vector GetSourceFiles(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const std::vector& modules, std::string& files, const fs::path& buildDir); private: static bool Check(const fs::path& path, const std::vector& modules, const Configuration& config, const fs::path& buildDir); }; diff --git a/build.sh b/build.sh index 8175cdf..c99a518 100755 --- a/build.sh +++ b/build.sh @@ -1,6 +1,7 @@ mkdir build mkdir bin +clang++ -std=c++26 Crafter.Build-Bounce.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-Bounce.pcm clang++ -std=c++26 Crafter.Build-Shader.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-Shader.pcm clang++ -std=c++26 Crafter.Build-Dependency.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-Dependency.pcm clang++ -std=c++26 Crafter.Build-Configuration.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-Configuration.pcm @@ -17,6 +18,7 @@ clang++ -std=c++26 Crafter.Build-Shader.cpp -fprebuilt-module-path=./build -c -O clang++ -std=c++26 Crafter.Build-Project.cpp -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Project_source.o clang++ -std=c++26 main.cpp -fprebuilt-module-path=./build -c -o ./build/main.o +clang++ -std=c++26 ./build/Crafter.Build-Bounce.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Bounce.o clang++ -std=c++26 ./build/Crafter.Build-Project.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Project.o clang++ -std=c++26 ./build/Crafter.Build-Configuration.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Configuration.o clang++ -std=c++26 ./build/Crafter.Build-ModuleFile.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-ModuleFile.o @@ -24,6 +26,6 @@ clang++ -std=c++26 ./build/Crafter.Build-SourceFile.pcm -fprebuilt-module-path=. clang++ -std=c++26 ./build/Crafter.Build-Shader.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Shader.o clang++ -std=c++26 ./build/Crafter.Build-Dependency.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Dependency.o clang++ -std=c++26 ./build/Crafter.Build.pcm -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build.o -clang++ ./build/main.o ./build/Crafter.Build-ModuleFile_source.o ./build/Crafter.Build-ModuleFile.o ./build/Crafter.Build-SourceFile_source.o ./build/Crafter.Build-SourceFile.o ./build/Crafter.Build-Shader_source.o ./build/Crafter.Build-Shader.o ./build/Crafter.Build.o ./build/Crafter.Build-Configuration.o ./build/Crafter.Build-Configuration_source.o ./build/Crafter.Build-Project.o ./build/Crafter.Build-Project_source.o ./build/Crafter.Build-Dependency.o ./build/Crafter.Build-Dependency_source.o -O3 -o ./bin/crafter-build -L/usr/local/lib -L/usr/lib/ -lvulkan -lMachineIndependent -lOSDependent -lGenericCodeGen -lglslang -lglslang-default-resource-limits -lSPIRV -lSPVRemapper -ltbb -fuse-ld=lld +clang++ ./build/main.o ./build/Crafter.Build-ModuleFile_source.o ./build/Crafter.Build-Bounce.o ./build/Crafter.Build-ModuleFile.o ./build/Crafter.Build-SourceFile_source.o ./build/Crafter.Build-SourceFile.o ./build/Crafter.Build-Shader_source.o ./build/Crafter.Build-Shader.o ./build/Crafter.Build.o ./build/Crafter.Build-Configuration.o ./build/Crafter.Build-Configuration_source.o ./build/Crafter.Build-Project.o ./build/Crafter.Build-Project_source.o ./build/Crafter.Build-Dependency.o ./build/Crafter.Build-Dependency_source.o -O3 -o ./bin/crafter-build -L/usr/local/lib -L/usr/lib/ -lvulkan -lMachineIndependent -lOSDependent -lGenericCodeGen -lglslang -lglslang-default-resource-limits -lSPIRV -lSPVRemapper -ltbb -fuse-ld=lld rm -rf build diff --git a/main.cpp b/main.cpp index 784ecaf..d0019ee 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include +#include #include "json.hpp" import Crafter.Build; using namespace Crafter::Build; @@ -58,11 +60,22 @@ int main(int argc, char* argv[]) { projectPath = filepath; } + std::vector errors; Project project = Project::LoadFromJSON(projectPath); if(outputDir.empty()){ - project.Build(configuration); + errors = std::get<1>(project.Build(configuration)); } else{ - project.Build(configuration, fs::path(outputDir)); + errors = std::get<1>(project.Build(configuration, fs::path(outputDir))); + } + + if(errors.size() > 0){ + for (const ClangError& error : errors) { + std::cout << "Filename: " << error.filename << std::endl; + std::cout << "Line: " << error.line_number << std::endl; + std::cout << "Error Message: " << error.error_message << std::endl; + std::cout << "Code: " << error.code << std::endl << std::endl; + } + return 0; } if(run){