error messages
This commit is contained in:
parent
a36beab2ac
commit
23fa8b98b0
9 changed files with 199 additions and 90 deletions
|
|
@ -25,36 +25,65 @@ module;
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <string_view>
|
||||||
|
#include <regex>
|
||||||
export module Crafter.Build:Bounce;
|
export module Crafter.Build:Bounce;
|
||||||
|
|
||||||
export void BounceCommand(const std::string& cmd) {
|
namespace Crafter::Build {
|
||||||
// std::array<char, 128> buffer;
|
export std::string RunCommand(const std::string_view cmd) {
|
||||||
// std::string result;
|
std::array<char, 128> buffer;
|
||||||
|
std::string result;
|
||||||
|
|
||||||
// std::string with = cmd + " 2>&1";
|
std::string with = std::string(cmd) + " 2>&1";
|
||||||
// // Open pipe to file
|
// Open pipe to file
|
||||||
// FILE* pipe = popen(with.c_str(), "r");
|
FILE* pipe = popen(with.c_str(), "r");
|
||||||
// if (!pipe) throw std::runtime_error("popen() failed!");
|
if (!pipe) throw std::runtime_error("popen() failed!");
|
||||||
|
|
||||||
// // Read till end of process:
|
// Read till end of process:
|
||||||
// while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
|
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
|
||||||
// result += buffer.data();
|
result += buffer.data();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Close pipe
|
// Close pipe
|
||||||
// auto returnCode = pclose(pipe);
|
pclose(pipe);
|
||||||
// if (returnCode != 0) {
|
return result;
|
||||||
// // Optional: handle non-zero exit status
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
|
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;
|
export struct ClangError {
|
||||||
system(cmd.c_str());
|
std::string filename;
|
||||||
}
|
uint32_t line_number;
|
||||||
|
std::string error_message;
|
||||||
|
std::string code;
|
||||||
|
};
|
||||||
|
|
||||||
export void BounceCommandIgnore(const std::string& cmd) {
|
export std::vector<ClangError> RunClang(const std::string_view cmd) {
|
||||||
std::string with = cmd + " > /dev/null 2>&1";
|
std::string result = RunCommand(cmd);
|
||||||
FILE* pipe = popen(with.c_str(), "r");
|
std::vector<ClangError> errors;
|
||||||
if (!pipe) throw std::runtime_error("popen() failed!");
|
|
||||||
pclose(pipe);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ module;
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <print>
|
#include <print>
|
||||||
#include <execution>
|
#include <execution>
|
||||||
|
#include <tuple>
|
||||||
module Crafter.Build;
|
module Crafter.Build;
|
||||||
using namespace Crafter::Build;
|
using namespace Crafter::Build;
|
||||||
namespace fs = std::filesystem;
|
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<ClangError> ModulePartition::Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags) {
|
||||||
|
std::vector<ClangError> errors;
|
||||||
if(needsRecompiling) {
|
if(needsRecompiling) {
|
||||||
std::string defines;
|
std::string defines;
|
||||||
for(const Define& define : config.defines) {
|
for(const Define& define : config.defines) {
|
||||||
|
|
@ -98,12 +100,13 @@ void ModulePartition::Compile(std::string clangDir, const Configuration& config,
|
||||||
if(config.verbose) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
}
|
}
|
||||||
BounceCommand(command.c_str());
|
errors = RunClang(command);
|
||||||
}
|
}
|
||||||
*compiled = true;
|
*compiled = true;
|
||||||
compiled->notify_all();
|
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<ClangError> 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;
|
std::string defines;
|
||||||
for(const Define& define : config.defines) {
|
for(const Define& define : config.defines) {
|
||||||
defines+=define.ToString();
|
defines+=define.ToString();
|
||||||
|
|
@ -112,7 +115,7 @@ void ModulePartition::CompileSource(std::string clangDir, const Configuration& c
|
||||||
if(config.verbose) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
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) {
|
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<ClangError> 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;
|
std::string defines;
|
||||||
for(const Define& define : config.defines) {
|
for(const Define& define : config.defines) {
|
||||||
defines+=define.ToString();
|
defines+=define.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::mutex errorMutex;
|
||||||
|
std::vector<ClangError> errors;
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
for(auto& [key, val] : partitions) {;
|
for(auto& [key, val] : partitions) {;
|
||||||
if(val.needsRecompiling) {
|
if(val.needsRecompiling) {
|
||||||
threads.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags](){
|
threads.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &errors, &errorMutex](){
|
||||||
val.Compile(clangDir, config, pcmDir, target, march, flags);
|
std::vector<ClangError> 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();
|
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);
|
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) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
}
|
}
|
||||||
BounceCommand(command.c_str());
|
errors = RunClang(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors.size() > 0) {
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::thread> threads2;
|
std::vector<std::thread> threads2;
|
||||||
for(auto& [key, val] : partitions) {;
|
for(auto& [key, val] : partitions) {;
|
||||||
if(val.needsRecompiling) {
|
if(val.needsRecompiling) {
|
||||||
threads2.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir](){
|
threads2.emplace_back([&val, &clangDir, &config, &pcmDir, &target, &march, &flags, &buildDir, &errors, &errorMutex](){
|
||||||
val.CompileSource(clangDir, config, pcmDir, target, march, flags, buildDir);
|
std::vector<ClangError> 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);
|
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) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
}
|
}
|
||||||
BounceCommand(command.c_str());
|
std::vector<ClangError> newErrors = RunClang(command);
|
||||||
|
if(newErrors.size() > 0) {
|
||||||
|
errorMutex.lock();
|
||||||
|
errors.insert(errors.end(), newErrors.begin(), newErrors.end());
|
||||||
|
errorMutex.unlock();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for(std::thread& thread : threads2){
|
for(std::thread& thread : threads2){
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Module> 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>, std::vector<ClangError>> 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<Module> modules;
|
std::vector<Module> modules;
|
||||||
for(const fs::path& file: config.moduleFiles) {
|
for(const fs::path& file: config.moduleFiles) {
|
||||||
std::ifstream t(file.generic_string()+".cppm");
|
std::ifstream t(file.generic_string()+".cppm");
|
||||||
|
|
@ -225,9 +255,16 @@ std::vector<Module> Module::GetModules(std::string clangDir, const Configuration
|
||||||
modules.emplace_back(match[1], file, config, pcmDir, files, buildDir);
|
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<ClangError> 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.Check();
|
||||||
modulee.Compile(clangDir, config, pcmDir, target, march, flags, buildDir);
|
std::vector<ClangError> 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};
|
||||||
}
|
}
|
||||||
|
|
@ -26,9 +26,11 @@ module;
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <tuple>
|
||||||
export module Crafter.Build:ModuleFile;
|
export module Crafter.Build:ModuleFile;
|
||||||
import :Configuration;
|
import :Configuration;
|
||||||
|
import :Bounce;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
export namespace Crafter::Build {
|
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);
|
ModulePartition(const std::string& name, const fs::path& path, Module* parent, const std::string& fileContent, const fs::path& pcmDir);
|
||||||
void AddDependants();
|
void AddDependants();
|
||||||
void Check();
|
void Check();
|
||||||
void Compile(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags);
|
std::vector<ClangError> 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<ClangError> 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 {
|
class Module {
|
||||||
|
|
@ -60,7 +62,7 @@ export namespace Crafter::Build {
|
||||||
const fs::path path;
|
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);
|
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 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);
|
std::vector<ClangError> 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<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);
|
static std::tuple<std::vector<Module>, std::vector<ClangError>> 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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ module;
|
||||||
#include <glslang/SPIRV/GlslangToSpv.h>
|
#include <glslang/SPIRV/GlslangToSpv.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <tuple>
|
||||||
module Crafter.Build;
|
module Crafter.Build;
|
||||||
using namespace Crafter::Build;
|
using namespace Crafter::Build;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
@ -39,45 +40,42 @@ Project::Project(std::string name, fs::path path, std::vector<Configuration> con
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Configuration& Project::Build(std::string configuration) {
|
std::tuple<Configuration&, std::vector<ClangError>> Project::Build(std::string configuration) {
|
||||||
for(Configuration& config : configurations) {
|
for(Configuration& config : configurations) {
|
||||||
if(config.name == configuration){
|
if(config.name == configuration){
|
||||||
Build(config);
|
return {config, Build(config)};
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Configuration& Project::Build(std::string configuration, fs::path outputDir) {
|
std::tuple<Configuration&, std::vector<ClangError>> Project::Build(std::string configuration, fs::path outputDir) {
|
||||||
for(Configuration& config : configurations) {
|
for(Configuration& config : configurations) {
|
||||||
if(config.name == configuration){
|
if(config.name == configuration){
|
||||||
Build(config, outputDir);
|
return {config, Build(config, outputDir)};
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Configuration& Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) {
|
std::tuple<Configuration&, std::vector<ClangError>> Project::Build(std::string configuration, fs::path outputDir, fs::path binDir) {
|
||||||
for(Configuration& config : configurations) {
|
for(Configuration& config : configurations) {
|
||||||
if(config.name == configuration){
|
if(config.name == configuration){
|
||||||
Build(config, outputDir, binDir);
|
return {config, Build(config, outputDir, binDir)};
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
throw std::runtime_error("Configuration: " + configuration + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::Build(Configuration& configuration) {
|
std::vector<ClangError> Project::Build(Configuration& configuration) {
|
||||||
Build(configuration, configuration.outputDir);
|
return Build(configuration, configuration.outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::Build(Configuration& config, fs::path outputDir) {
|
std::vector<ClangError> Project::Build(Configuration& config, fs::path outputDir) {
|
||||||
Build(config, outputDir, outputDir);
|
return Build(config, outputDir, outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) {
|
std::vector<ClangError> Project::Build(Configuration& config, fs::path outputDir, fs::path binDir) {
|
||||||
if(config.standard.empty()) {
|
if(config.standard.empty()) {
|
||||||
config.standard = "c++26";
|
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) {
|
if (depLibSet.insert(project.name).second) {
|
||||||
libs+=std::format(" -l{}", project.name);
|
libs+=std::format(" -l{}", project.name);
|
||||||
}
|
}
|
||||||
const Configuration& depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir);
|
std::tuple<Configuration&, std::vector<ClangError>> depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir);
|
||||||
for(const std::string& lib2 : depConfig.libs) {
|
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) {
|
if (depLibSet.insert(lib2).second) {
|
||||||
libs+=std::format(" -l{}", lib2);
|
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) {
|
if (depLibSet.insert(dep2.name).second) {
|
||||||
libs+=std::format(" -l{}", dep2.name);
|
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) {
|
if (depLibSet.insert(project.name).second) {
|
||||||
libs+=std::format(" -l{}", project.name);
|
libs+=std::format(" -l{}", project.name);
|
||||||
}
|
}
|
||||||
const Configuration& depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir);
|
std::tuple<Configuration&, std::vector<ClangError>> depConfig = project.Build(config.dependencies[i].configuration, pcmDir, binDir);
|
||||||
for(const std::string& lib2 : depConfig.libs) {
|
if(std::get<1>(depConfig).size() > 0) {
|
||||||
if (depLibSet.insert(lib2).second) {
|
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);
|
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) {
|
if (depLibSet.insert(dep2.name).second) {
|
||||||
libs+=std::format(" -l{}", dep2.name);
|
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::string files;
|
||||||
std::vector<Module> modules = Module::GetModules(clangDir, config, pcmDir, target, march, flags, files, buildDir);
|
std::tuple<std::vector<Module>, std::vector<ClangError>> 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<ClangError> errors = Source::GetSourceFiles(clangDir, config, pcmDir, target, march, flags, std::get<0>(modules), files, buildDir);
|
||||||
|
if(errors.size() > 0) {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> 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++) {
|
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());
|
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")) {
|
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](){
|
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.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);
|
std::string command = std::format("{} {} {}-O{} -o {} {} {} -fuse-ld=lld", clangDir, flags, files, config.optimizationLevel, (outputDir/name).generic_string(), target, libs);
|
||||||
if(config.verbose) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
}
|
}
|
||||||
BounceCommand(command.c_str());
|
std::vector<ClangError> errors = RunClang(command);
|
||||||
|
if(errors.size() > 0) {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
} else if(config.type == "library"){
|
} 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"){
|
} 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){
|
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);
|
fs::copy(additionalFile, binDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Project Project::LoadFromJSON(fs::path path) {
|
Project Project::LoadFromJSON(fs::path path) {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ module;
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <tuple>
|
||||||
export module Crafter.Build:Project;
|
export module Crafter.Build:Project;
|
||||||
import :Configuration;
|
import :Configuration;
|
||||||
|
import :Bounce;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
export namespace Crafter::Build {
|
export namespace Crafter::Build {
|
||||||
|
|
@ -33,12 +35,12 @@ export namespace Crafter::Build {
|
||||||
fs::path path;
|
fs::path path;
|
||||||
std::vector<Configuration> configurations;
|
std::vector<Configuration> configurations;
|
||||||
Project(std::string name, fs::path path, std::vector<Configuration> configurations);
|
Project(std::string name, fs::path path, std::vector<Configuration> configurations);
|
||||||
const Configuration& Build(std::string configuration);
|
std::tuple<Configuration&, std::vector<ClangError>> Build(std::string configuration);
|
||||||
const Configuration& Build(std::string configuration, fs::path outputDir);
|
std::tuple<Configuration&, std::vector<ClangError>> Build(std::string configuration, fs::path outputDir);
|
||||||
const Configuration& Build(std::string configuration, fs::path outputDir, fs::path binDir);
|
std::tuple<Configuration&, std::vector<ClangError>> Build(std::string configuration, fs::path outputDir, fs::path binDir);
|
||||||
void Build(Configuration& configuration);
|
std::vector<ClangError> Build(Configuration& configuration);
|
||||||
void Build(Configuration& configuration, fs::path outputDir);
|
std::vector<ClangError> Build(Configuration& configuration, fs::path outputDir);
|
||||||
void Build(Configuration& configuration, fs::path outputDir, fs::path binDir);
|
std::vector<ClangError> Build(Configuration& configuration, fs::path outputDir, fs::path binDir);
|
||||||
void SaveToJSON(fs::path path);
|
void SaveToJSON(fs::path path);
|
||||||
static Project LoadFromJSON(fs::path path);
|
static Project LoadFromJSON(fs::path path);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,28 +25,41 @@ module;
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <mutex>
|
||||||
#include <execution>
|
#include <execution>
|
||||||
module Crafter.Build;
|
module Crafter.Build;
|
||||||
using namespace Crafter::Build;
|
using namespace Crafter::Build;
|
||||||
namespace fs = std::filesystem;
|
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<std::thread>& threads, const std::vector<Module>& modules, std::string& files, const fs::path& buildDir) {
|
std::vector<ClangError> 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<Module>& modules, std::string& files, const fs::path& buildDir) {
|
||||||
std::string defines;
|
std::string defines;
|
||||||
for(const Define& define : config.defines) {
|
for(const Define& define : config.defines) {
|
||||||
defines+=define.ToString();
|
defines+=define.ToString();
|
||||||
}
|
}
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
std::mutex errorMutex;
|
||||||
|
std::vector<ClangError> errors;
|
||||||
for(const fs::path& sourceFile : config.sourceFiles) {
|
for(const fs::path& sourceFile : config.sourceFiles) {
|
||||||
files+=std::format("{}_source.o ",(buildDir/sourceFile.filename()).generic_string());
|
files+=std::format("{}_source.o ",(buildDir/sourceFile.filename()).generic_string());
|
||||||
if(Source::Check(sourceFile, modules, config, buildDir)) {
|
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);
|
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) {
|
if(config.verbose) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
}
|
}
|
||||||
BounceCommand(command.c_str());
|
std::vector<ClangError> 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<Module>& modules, const Configuration& config, const fs::path& buildDir) {
|
bool Source::Check(const fs::path& path, const std::vector<Module>& modules, const Configuration& config, const fs::path& buildDir) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace fs = std::filesystem;
|
||||||
namespace Crafter::Build {
|
namespace Crafter::Build {
|
||||||
class Source {
|
class Source {
|
||||||
public:
|
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<std::thread>& threads, const std::vector<Module>& modules, std::string& files, const fs::path& buildDir);
|
static std::vector<ClangError> GetSourceFiles(std::string clangDir, const Configuration& config, fs::path pcmDir, std::string target, const std::string& march, const std::string& flags, const std::vector<Module>& modules, std::string& files, const fs::path& buildDir);
|
||||||
private:
|
private:
|
||||||
static bool Check(const fs::path& path, const std::vector<Module>& modules, const Configuration& config, const fs::path& buildDir);
|
static bool Check(const fs::path& path, const std::vector<Module>& modules, const Configuration& config, const fs::path& buildDir);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
4
build.sh
4
build.sh
|
|
@ -1,6 +1,7 @@
|
||||||
mkdir build
|
mkdir build
|
||||||
mkdir bin
|
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-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-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
|
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 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 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-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-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
|
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-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-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++ -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
|
rm -rf build
|
||||||
|
|
|
||||||
17
main.cpp
17
main.cpp
|
|
@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <tuple>
|
||||||
|
#include <iostream>
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
import Crafter.Build;
|
import Crafter.Build;
|
||||||
using namespace Crafter::Build;
|
using namespace Crafter::Build;
|
||||||
|
|
@ -58,11 +60,22 @@ int main(int argc, char* argv[]) {
|
||||||
projectPath = filepath;
|
projectPath = filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ClangError> errors;
|
||||||
Project project = Project::LoadFromJSON(projectPath);
|
Project project = Project::LoadFromJSON(projectPath);
|
||||||
if(outputDir.empty()){
|
if(outputDir.empty()){
|
||||||
project.Build(configuration);
|
errors = std::get<1>(project.Build(configuration));
|
||||||
} else{
|
} 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){
|
if(run){
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue