additional file fix

This commit is contained in:
Jorijn van der Graaf 2025-11-09 20:08:23 +01:00
commit 698665215b
9 changed files with 64 additions and 88 deletions

View file

@ -143,8 +143,6 @@ extern "C" {
- **interfaces**: C++20 module files (`.cppm` extension)
- **implementations**: Source files (`.cpp` extension)
- **additional_files**: Files copied to output directory
- **build_dir**: Directory for intermediate build files (default: `build`)
- **output_dir**: Directory for final output files (default: `bin`)
- **type**: Project type (`executable`, `library`, `shared-library`, default: `executable`)
- **extends**: Array of configuration names to extend, later entries overwrite previous ones
- **debug**: Boolean enabling debug mode (default: `false`)

View file

@ -162,6 +162,10 @@ const wasi = new Wasi({
args: []
});
if(!window.crafter_webbuild_env){
window.crafter_webbuild_env = {};
}
window.crafter_webbuild_env.table = new WebAssembly.Table({ initial: 4, element: 'anyfunc' });
const { instance } = await WebAssembly.instantiateStreaming(fetch("main.wasm"), {

21
examples/wasi/README.md Normal file
View file

@ -0,0 +1,21 @@
# WASI Example
## Description
This example demonstrates how to build a WASI project
## Expected Result
Hello World! appears in the browser console.
## How to Run
```bash
crafter-build build executable
run.sh
```
and go to `http://localhost:8080/`
if caddy is not installed you can use your favorite static file server instead

View file

@ -2,7 +2,7 @@
"name": "main",
"configurations": [
{
"name": "example",
"name": "executable",
"implementations": ["main"],
"target": "wasm32-wasi"
}

View file

@ -1 +1 @@
caddy file-server --listen :8080 --root bin/example
caddy file-server --listen :8080 --root bin/executable

View file

@ -29,6 +29,7 @@ namespace fs = std::filesystem;
namespace Crafter {
Project::Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations) : name(std::move(name)), path(std::move(path)), configurations(std::move(configurations)) {}
Project::Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations, fs::path&& binDir, fs::path&& buildDir) : name(std::move(name)), path(std::move(path)), configurations(std::move(configurations)), binDir(std::move(binDir)), buildDir(std::move(buildDir)) {}
Configuration& Project::Build(std::string_view configuration) {
for(Configuration& config : configurations) {
@ -39,71 +40,42 @@ namespace Crafter {
}
throw std::runtime_error(std::format("Configuration: {} not found.", configuration));
}
Configuration& Project::Build(std::string_view configuration, const fs::path& binDir) {
Configuration& Project::Build(std::string_view configuration, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName) {
for(Configuration& config : configurations) {
if(config.name == configuration){
Build(config, binDir, name);
return config;
}
}
throw std::runtime_error(std::format("Configuration: {} not found.", configuration));
}
Configuration& Project::Build(std::string_view configuration, const fs::path& binDir, const fs::path& buildDir) {
for(Configuration& config : configurations) {
if(config.name == configuration){
Build(config, binDir, buildDir, name);
return config;
}
}
throw std::runtime_error(std::format("Configuration: {} not found.", configuration));
}
Configuration& Project::Build(std::string_view configuration, const fs::path& binDir, const fs::path& buildDir, std::string outputName) {
for(Configuration& config : configurations) {
if(config.name == configuration){
Build(config, binDir, buildDir, outputName);
Build(config, binDir, binDir, outputDir, outputName);
return config;
}
}
throw std::runtime_error(std::format("Configuration: {} not found.", configuration));
}
void Project::Build(Configuration& config) const {
if(binDir.empty()) {
Build(config, path/("bin"/fs::path(config.name)));
} else {
Build(config, path/this->binDir/config.name);
Build(config, binDir/config.name, binDir/config.name, buildDir/config.name, name);
}
}
void Project::Build(Configuration& config, const fs::path& binDir) const {
fs::path buildDir;
if(this->buildDir.empty()) {
buildDir = path/("build"/fs::path(config.name));
} else {
buildDir = path/this->buildDir/config.name;
}
Build(config, binDir, buildDir, name);
}
void Project::Build(Configuration& config, const fs::path& binDir, const fs::path& buildDir) const {
Build(config, binDir, buildDir, name);
}
void Project::Build(Configuration& config, const fs::path& binDir, const fs::path& buildDir, std::string outputName) const {
void Project::Build(Configuration& config, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName) const {
if (!fs::exists(binDir)) {
fs::create_directories(binDir);
}
if (!fs::exists(outputDir)) {
fs::create_directories(outputDir);
}
if (!fs::exists(buildDir)) {
fs::create_directories(buildDir);
}
std::vector<std::thread> threads;
for(const Shader& shader : config.shaders) {
if(shader.Check(binDir)) {
threads.emplace_back(&Shader::Compile, &shader, binDir);
if(shader.Check(outputDir)) {
threads.emplace_back(&Shader::Compile, &shader, outputDir);
}
}
std::thread fileThread([&config, &binDir](){
std::thread fileThread([&config, &outputDir](){
for (const fs::path& additionalFile : config.additionalFiles) {
fs::path destination = binDir / additionalFile.filename();
fs::path destination = outputDir / additionalFile.filename();
std::cout << destination << std::endl;
if (fs::is_directory(additionalFile)) {
if (!fs::exists(destination)) {
@ -236,13 +208,8 @@ namespace Crafter {
Project project = Project::LoadFromJSON(config.dependencies[i].path);
for(Configuration& depConfig : project.configurations) {
if(depConfig.name == config.dependencies[i].configuration){
fs::path depBuildDir;
if(project.buildDir.empty()) {
depBuildDir = fs::path(config.dependencies[i].path).parent_path()/"build"/fs::path(depConfig.name);
} else {
depBuildDir = fs::path(config.dependencies[i].path).parent_path()/project.buildDir/depConfig.name;
}
project.Build(depConfig, pcmDir, depBuildDir);
fs::path depBuildDir = fs::path(config.dependencies[i].path).parent_path()/depConfig.buildDir;
project.Build(depConfig, pcmDir, binDir, depBuildDir, project.name);
libMutex.lock();
if (depLibSet.insert(project.name).second) {
libsString+=std::format(" -l{}", project.name);
@ -298,10 +265,6 @@ namespace Crafter {
command += " -L/usr/local/lib";
}
if(config.target == "wasm32-wasi") {
outputName += ".wasm";
}
command += libsString;
for(const std::string& lib : config.libs) {
@ -317,6 +280,9 @@ namespace Crafter {
if(repack) {
if(config.type == CRAFTER_CONFIGURATION_TYPE_EXECUTABLE){
if(config.target == "wasm32-wasi") {
outputName += ".wasm";
}
RunClang(std::format("{}{} -o {} -fuse-ld=lld", command, files, (binDir/outputName).string()));
} else if(config.type == CRAFTER_CONFIGURATION_TYPE_LIBRARY){
std::cout << std::format("ar r {}.a {}", (binDir/fs::path(std::string("lib")+outputName)).string(), files) << std::endl;
@ -344,7 +310,6 @@ namespace Crafter {
std::vector<Test> tests;
nlohmann::json testJson = data["tests"];
for (nlohmann::json::iterator it = configs.begin(); it != configs.end(); ++it) {
configurations.emplace_back(configs, (*it), workingDir);
}
@ -354,11 +319,15 @@ namespace Crafter {
}
Project project(std::move(name), std::move(workingDir), std::move(configurations));
if(data.contains("build_dir")) {
project.buildDir = workingDir / data["build_dir"].get<std::string>();
}
if(data.contains("bin_dir")) {
project.binDir = workingDir / data["bin_dir"].get<std::string>();
project.binDir = data["bin_dir"].get<std::string>();
} else {
project.binDir = "bin";
}
if(data.contains("build_dir")) {
project.buildDir = data["build_dir"].get<std::string>();
} else {
project.buildDir = "build";
}
project.tests = std::move(tests);
return project;
@ -382,21 +351,11 @@ namespace Crafter {
}
TestResult Project::RunTest(Test& test) const {
fs::path binDir;
if(this->binDir.empty()) {
binDir = path/("bin"/fs::path(test.config.name));
} else {
binDir = path/this->binDir/test.config.name;
}
fs::path buildDir;
if(this->buildDir.empty()) {
buildDir = path/("build"/fs::path(test.config.name));
} else {
buildDir = path/this->buildDir/test.config.name;
}
fs::path binDir = path/this->binDir/test.config.name;
fs::path buildDir = path/this->buildDir/test.config.name;
try {
Build(test.config, binDir, buildDir, test.config.name);
Build(test.config, binDir, binDir, buildDir, test.config.name);
} catch(std::exception& e) {
return {test.config.name, std::string(e.what())};
}

View file

@ -71,12 +71,7 @@ int main(int argc, char* argv[]) {
if(command == "build") {
Configuration& config = project.Build(argument);
if(run){
std::string binDir;
if(project.binDir.empty()) {
binDir = std::format("bin/{}", config.name);
} else {
binDir = std::format("{}/{}", project.binDir.string(), config.name);
}
std::string binDir = std::format("{}/{}", project.binDir.string(), config.name);
if(config.debug) {
system(std::format("cd {} && ./{}", (fs::path(projectPath).parent_path()/binDir).string(), project.name).c_str());
//system(std::format("cd {} && lldb -o run {}", (fs::path(projectPath).parent_path()/binDir).string(), project.name).c_str());

View file

@ -51,6 +51,8 @@ namespace Crafter {
export class Configuration {
public:
std::string name;
fs::path buildDir;
fs::path binDir;
std::string standard;
std::vector<std::unique_ptr<Module>> interfaces;
std::vector<Implementation> implementations;

View file

@ -27,21 +27,18 @@ namespace Crafter {
export class Project {
public:
std::string name;
fs::path path;
fs::path buildDir;
fs::path binDir;
fs::path path;
std::vector<Configuration> configurations;
std::vector<Test> tests;
Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations);
Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations, fs::path&& buildDir, fs::path&& binDir);
static Project LoadFromJSON(const fs::path& path);
Configuration& Build(std::string_view configuration);
Configuration& Build(std::string_view configuration, const fs::path& outputDir);
Configuration& Build(std::string_view configuration, const fs::path& outputDir, const fs::path& binDir);
Configuration& Build(std::string_view configuration, const fs::path& outputDir, const fs::path& binDir, std::string outputName);
Configuration& Build(std::string_view configuration, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName);
void Build(Configuration& configuration) const;
void Build(Configuration& configuration, const fs::path& binDir) const;
void Build(Configuration& configuration, const fs::path& binDir, const fs::path& builDir) const;
void Build(Configuration& configuration, const fs::path& binDir, const fs::path& builDir, std::string outputName) const;
void Build(Configuration& configuration, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName) const;
TestResult RunTest(const std::string_view test);
TestResult RunTest(Test& test) const;
std::vector<TestResult> RunTests();