diff --git a/README.md b/README.md index fee5784..be843ef 100644 --- a/README.md +++ b/README.md @@ -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`) diff --git a/binlib/wasi-sysroot-28.0/runtime.js b/binlib/wasi-sysroot-28.0/runtime.js index 4cceb09..248fcb0 100644 --- a/binlib/wasi-sysroot-28.0/runtime.js +++ b/binlib/wasi-sysroot-28.0/runtime.js @@ -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"), { diff --git a/examples/wasi/README.md b/examples/wasi/README.md new file mode 100644 index 0000000..21c4278 --- /dev/null +++ b/examples/wasi/README.md @@ -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 \ No newline at end of file diff --git a/examples/wasi/project.json b/examples/wasi/project.json index 3f98f62..3a3b305 100644 --- a/examples/wasi/project.json +++ b/examples/wasi/project.json @@ -2,7 +2,7 @@ "name": "main", "configurations": [ { - "name": "example", + "name": "executable", "implementations": ["main"], "target": "wasm32-wasi" } diff --git a/examples/wasi/run.sh b/examples/wasi/run.sh index c6bfe92..e706621 100644 --- a/examples/wasi/run.sh +++ b/examples/wasi/run.sh @@ -1 +1 @@ -caddy file-server --listen :8080 --root bin/example \ No newline at end of file +caddy file-server --listen :8080 --root bin/executable \ No newline at end of file diff --git a/implementations/Crafter.Build-Project.cpp b/implementations/Crafter.Build-Project.cpp index 14b246e..834dff6 100644 --- a/implementations/Crafter.Build-Project.cpp +++ b/implementations/Crafter.Build-Project.cpp @@ -29,6 +29,7 @@ namespace fs = std::filesystem; namespace Crafter { Project::Project(std::string&& name, fs::path&& path, std::vector&& configurations) : name(std::move(name)), path(std::move(path)), configurations(std::move(configurations)) {} + Project::Project(std::string&& name, fs::path&& path, std::vector&& 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 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 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(); - } if(data.contains("bin_dir")) { - project.binDir = workingDir / data["bin_dir"].get(); + project.binDir = data["bin_dir"].get(); + } else { + project.binDir = "bin"; + } + if(data.contains("build_dir")) { + project.buildDir = data["build_dir"].get(); + } 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())}; } diff --git a/implementations/main.cpp b/implementations/main.cpp index 287e644..66e63cf 100644 --- a/implementations/main.cpp +++ b/implementations/main.cpp @@ -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()); diff --git a/interfaces/Crafter.Build-Configuration.cppm b/interfaces/Crafter.Build-Configuration.cppm index 407d49e..bb4afb4 100644 --- a/interfaces/Crafter.Build-Configuration.cppm +++ b/interfaces/Crafter.Build-Configuration.cppm @@ -51,6 +51,8 @@ namespace Crafter { export class Configuration { public: std::string name; + fs::path buildDir; + fs::path binDir; std::string standard; std::vector> interfaces; std::vector implementations; diff --git a/interfaces/Crafter.Build-Project.cppm b/interfaces/Crafter.Build-Project.cppm index 866998d..1d2184a 100644 --- a/interfaces/Crafter.Build-Project.cppm +++ b/interfaces/Crafter.Build-Project.cppm @@ -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 configurations; std::vector tests; Project(std::string&& name, fs::path&& path, std::vector&& configurations); + Project(std::string&& name, fs::path&& path, std::vector&& 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 RunTests();