diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 40eb684..be91256 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,8 +11,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Prepare - run: sudo apt install clang lld - name: Build run: ./build.sh - name: Release diff --git a/Crafter.Build-Configuration.cpp b/Crafter.Build-Configuration.cpp index b1e436d..b9271da 100644 --- a/Crafter.Build-Configuration.cpp +++ b/Crafter.Build-Configuration.cpp @@ -20,11 +20,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA module; #include "json.hpp" +#include module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; -Configuration::Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags): name(name), standard(standard), sourceFiles(sourceFiles), moduleFiles(moduleFiles), optimizationLevel(optimizationLevel), buildDir(buildDir), outputDir(outputDir), type(type), target(target), march(march), dependencies(dependencies), additionalFiles(additionalFiles), flags(flags) { +Configuration::Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose): name(name), standard(standard), sourceFiles(sourceFiles), moduleFiles(moduleFiles), optimizationLevel(optimizationLevel), buildDir(buildDir), outputDir(outputDir), type(type), target(target), march(march), dependencies(dependencies), additionalFiles(additionalFiles), flags(flags), debug(debug), libs(libs), lib_paths(lib_paths), c_files(c_files), shaderFiles(shaderFiles), includeDirs(includeDirs), verbose(verbose) { } @@ -33,9 +34,13 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json for (auto& [key, val] : config.items()) { if(key == "standard"){ - standard = val.get(); + standard = val.get(); } else if(key == "target") { - target = val.get(); + target = val.get(); + } else if(key == "debug") { + debug = val.get(); + } else if(key == "verbose") { + verbose = val.get(); } else if(key == "type") { type = val.get(); } else if(key == "march") { @@ -48,8 +53,22 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json const std::filesystem::path fullFilePath = workingDir / filePath; sourceFiles[i] = fullFilePath.generic_string(); } + } else if(key == "c_files") { + const std::vector tempSourceFiles = val.get>(); + c_files = std::vector(tempSourceFiles.size()); + for(std::int_fast32_t i = 0; i < c_files.size(); i++){ + const std::filesystem::path filePath (tempSourceFiles[i]); + const std::filesystem::path fullFilePath = workingDir / filePath; + c_files[i] = fullFilePath.generic_string(); + } } else if(key == "flags") { flags = val.get>(); + } else if(key == "lib_paths") { + lib_paths = val.get>(); + } else if(key == "include_dirs") { + includeDirs = val.get>(); + } else if(key == "libs") { + libs = val.get>(); } else if(key == "module_files") { const std::vector tempModuleFiles = val.get>(); moduleFiles = std::vector(tempModuleFiles.size()); @@ -58,6 +77,12 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json const std::filesystem::path fullFilePath = workingDir / filePath; moduleFiles[i] = fullFilePath.generic_string(); } + } else if(key == "shaders") { + for (auto it : val) { + const std::filesystem::path filePath (it["path"].get()); + const std::filesystem::path fullFilePath = workingDir / filePath; + shaderFiles.emplace_back(fullFilePath, it["entrypoint"].get(), static_cast(it["type"].get())); + } } else if(key == "additional_files") { const std::vector tempAdditionalFiles = val.get>(); additionalFiles = std::vector(tempAdditionalFiles.size()); @@ -133,9 +158,30 @@ Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json if(!extendData.march.empty() && march.empty()) { march = extendData.march; } + if(!extendData.lib_paths.empty()){ + lib_paths.insert(lib_paths.end(), extendData.lib_paths.begin(), extendData.lib_paths.end()); + } + if(!extendData.c_files.empty()){ + c_files.insert(c_files.end(), extendData.c_files.begin(), extendData.c_files.end()); + } if(!extendData.flags.empty()){ flags.insert(flags.end(), extendData.flags.begin(), extendData.flags.end()); } + if(extendData.debug){ + debug = true; + } + if(extendData.verbose){ + verbose = true; + } + if(!extendData.libs.empty()){ + libs.insert(libs.end(), extendData.libs.begin(), extendData.libs.end()); + } + if(!extendData.shaderFiles.empty()){ + shaderFiles.insert(shaderFiles.end(), extendData.shaderFiles.begin(), extendData.shaderFiles.end()); + } + if(!extendData.includeDirs.empty()){ + includeDirs.insert(includeDirs.end(), extendData.includeDirs.begin(), extendData.includeDirs.end()); + } break; } } diff --git a/Crafter.Build-Configuration.cppm b/Crafter.Build-Configuration.cppm index 2900575..f9f0a18 100644 --- a/Crafter.Build-Configuration.cppm +++ b/Crafter.Build-Configuration.cppm @@ -25,6 +25,7 @@ module; #include export module Crafter.Build:Configuration; import :Dependency; +import :Shader; namespace fs = std::filesystem; @@ -34,18 +35,25 @@ export namespace Crafter::Build { std::string name; std::string standard; std::vector sourceFiles; + std::vector c_files; std::vector moduleFiles; + std::vector shaderFiles; std::vector additionalFiles; + std::vector includeDirs; std::string optimizationLevel; std::string buildDir; std::string outputDir; std::string type; std::string target; std::string march; + bool debug; + std::vector libs; + std::vector lib_paths; std::vector dependencies; std::unordered_map additionalProperties; std::vector flags; - Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags); + bool verbose; + Configuration(std::string name, std::string standard, std::vector sourceFiles, std::vector moduleFiles, std::string optimizationLevel, std::string buildDir, std::string outputDir, std::string type, std::string target, std::string march, std::vector dependencies, std::vector additionalFiles, std::vector flags, bool debug, std::vector libs, std::vector lib_paths, std::vector c_files, std::vector shaderFiles, std::vector includeDirs, bool verbose); Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir); }; } diff --git a/Crafter.Build-ModuleFile.cpp b/Crafter.Build-ModuleFile.cpp index 2c8d6c9..5a20e47 100644 --- a/Crafter.Build-ModuleFile.cpp +++ b/Crafter.Build-ModuleFile.cpp @@ -99,18 +99,32 @@ void ModuleFile::Compile(std::string clangDir, const Configuration& config, fs:: for(const std::string& flag : config.flags) { flags+=flag; } + + if(config.debug) { + flags+=" -g"; + } std::string march; if(config.target != "wasm32-unknown-wasi"){ march = std::format("-march={}", config.march); } - system(std::format("{} -std={} {}.cppm --precompile {} {} -fprebuilt-module-path={} -o {}.pcm {}", clangDir, config.standard, path.generic_string(), march, flags, pcmDir.generic_string(), (pcmDir/path.filename()).generic_string(), target).c_str()); + std::string command = std::format("{} {} -std={} {}.cppm --precompile {} -fprebuilt-module-path={} -o {}.pcm {}", clangDir, flags, config.standard, path.generic_string(), march, pcmDir.generic_string(), (pcmDir/path.filename()).generic_string(), target); + if(config.verbose) { + std::cout << command << std::endl; + } + system(command.c_str()); + + recompiled = true; fileMutex.unlock(); - system(std::format("{} -std={} {}.pcm -fprebuilt-module-path={} -c -O{} {} {} -o {}.o {}", clangDir, config.standard, (pcmDir/path.filename()).generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (config.buildDir/path.filename()).generic_string(), target).c_str()); + command = std::format("{} -std={} {}.pcm -fprebuilt-module-path={} -c -O{} {} {} -o {}.o {}", clangDir, config.standard, (pcmDir/path.filename()).generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (config.buildDir/path.filename()).generic_string(), target); + if(config.verbose) { + std::cout << command << std::endl; + } + system(command.c_str()); } else { fileMutex.unlock(); } diff --git a/Crafter.Build-Project.cpp b/Crafter.Build-Project.cpp index de91118..d6bb771 100644 --- a/Crafter.Build-Project.cpp +++ b/Crafter.Build-Project.cpp @@ -27,6 +27,7 @@ module; #include "json.hpp" #include #include +#include module Crafter.Build; using namespace Crafter::Build; namespace fs = std::filesystem; @@ -102,7 +103,24 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c pcmDir = config.buildDir; } - std::string libs; + + std::string libs = " -L/usr/local/lib"; + + if(config.target != "x86_64-w64-mingw64" && config.target != "x86_64-w64-mingw32") { + libs += " -L/usr/lib/"; + } + + for(const std::string& path : config.lib_paths) { + libs += std::format(" -L{}", path); + } + + for(const std::string& path : config.includeDirs) { + libs += std::format(" -I{}", path); + } + + for(Shader& shader : config.shaderFiles) { + shader.Compile(outputDir); + } std::vector depThreads = std::vector(config.dependencies.size()); @@ -161,6 +179,14 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c flags+=flag; } + if(config.debug) { + flags+=" -g"; + } + + for(const std::string& lib : config.libs) { + libs+= std::format(" -l{}",lib); + } + for(std::thread& thread : depThreads){ thread.join(); } @@ -182,12 +208,26 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c march = std::format("-march={}", config.march); } + std::vector threads; for(std::uint_fast32_t i = 0; i < config.sourceFiles.size(); i++) { files+=std::format("{}_source.o ",(config.buildDir/config.sourceFiles[i].filename()).generic_string()); //if(!fs::exists((config.buildDir/config.sourceFiles[i].filename()).generic_string()+"_source.o") || fs::last_write_time(config.sourceFiles[i].generic_string()+".cpp") > fs::last_write_time((config.buildDir/config.sourceFiles[i].filename()).generic_string()+"_source.o")) { threads.emplace_back([i, &config, pcmDir, target, clangDir, flags, march](){ - system(std::format("{} -std={} {}.cpp -fprebuilt-module-path={} -c -O{} {} {} -o {}_source.o {}", clangDir, config.standard, config.sourceFiles[i].generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (config.buildDir/config.sourceFiles[i].filename()).generic_string(), target).c_str()); + std::string command = std::format("{} -std={} {}.cpp -fprebuilt-module-path={} -c -O{} {} {} -o {}_source.o {}", clangDir, config.standard, config.sourceFiles[i].generic_string(), pcmDir.generic_string(), config.optimizationLevel, march, flags, (config.buildDir/config.sourceFiles[i].filename()).generic_string(), target); + if(config.verbose) { + std::cout << command << std::endl; + } + system(command.c_str()); + }); + //} + } + + for(std::uint_fast32_t i = 0; i < config.c_files.size(); i++) { + files+=std::format("{}_source.o ",(config.buildDir/config.c_files[i].filename()).generic_string()); + //if(!fs::exists((config.buildDir/config.sourceFiles[i].filename()).generic_string()+"_source.o") || fs::last_write_time(config.sourceFiles[i].generic_string()+".cpp") > fs::last_write_time((config.buildDir/config.sourceFiles[i].filename()).generic_string()+"_source.o")) { + threads.emplace_back([i, &config, pcmDir, target, clangDir, flags, march](){ + system(std::format("clang {}.c -c -O{} {} {} -o {}_source.o {}", config.c_files[i].generic_string(), config.optimizationLevel, march, flags, (config.buildDir/config.c_files[i].filename()).generic_string(), target).c_str()); }); //} } @@ -197,9 +237,18 @@ void Project::Build(Configuration config, fs::path outputDir, fs::path binDir) c } if(config.type == "executable"){ - system(std::format("{} {}-O{} -o {} {} {} -fuse-ld=lld", clangDir, files, config.optimizationLevel, (outputDir/name).generic_string(), target, libs).c_str()); + //std::cout << std::format("{} {} {}-O{} -o {} {} {} -fuse-ld=lld", clangDir, flags, files, config.optimizationLevel, (outputDir/name).generic_string(), target, libs).c_str() << std::endl; + 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; + } + system(command.c_str()); } else if(config.type == "library"){ - system(std::format("ar r {}.a {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); + system(std::format("ar r {}.a {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); } else if(config.type == "shared-library"){ system(std::format("ar r {}.so {}", (outputDir/fs::path("lib"+name)).generic_string(), files).c_str()); } diff --git a/Crafter.Build-Shader.cpp b/Crafter.Build-Shader.cpp new file mode 100644 index 0000000..3a1338a --- /dev/null +++ b/Crafter.Build-Shader.cpp @@ -0,0 +1,99 @@ +/* +Crafter.Build +Copyright (C) 2025 Catcrafts + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3.0 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +module; +#include +#include +#include +#include +#include +#include +#include "DirStackFileIncluder.h" +#include +#include +module Crafter.Build; +using namespace Crafter::Build; + +Shader::Shader(fs::path path, std::string entrypoint, EShLanguage type): path(path), entrypoint(entrypoint), type(type) { + +} + +void Shader::Compile(fs::path outputDir) { + glslang::InitializeProcess(); + EShMessages messages = static_cast(EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules); + std::ifstream fileStream(path, std::ios::in | std::ios::binary); + if (!fileStream) { + throw std::ios_base::failure("Failed to open file: " + path.string()); + } + std::ostringstream contents; + contents << fileStream.rdbuf(); + std::string src = contents.str(); + + const char *file_name_list[1] = {""}; + const char *shader_source = reinterpret_cast(src.data()); + + glslang::TShader shader(type); + shader.setStringsWithLengthsAndNames(&shader_source, nullptr, file_name_list, 1); + shader.setEntryPoint(entrypoint.c_str()); + shader.setSourceEntryPoint(entrypoint.c_str()); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4); + DirStackFileIncluder includeDir; + includeDir.pushExternalLocalDirectory(path.parent_path().generic_string()); + std::string info_log; + if (!shader.parse(GetDefaultResources(), 100, false, messages, includeDir)) + { + info_log = std::string(shader.getInfoLog()) + std::string(shader.getInfoDebugLog()); + } + // Add shader to new program object. + glslang::TProgram program; + program.addShader(&shader); + + // Link program. + if (!program.link(messages)) + { + info_log = std::string(program.getInfoLog()) + std::string(program.getInfoDebugLog()); + } + + // Save any info log that was generated. + if (shader.getInfoLog()) + { + info_log += std::string(shader.getInfoLog()) + std::string(shader.getInfoDebugLog()); + } + + if (program.getInfoLog()) + { + info_log += std::string(program.getInfoLog()) + std::string(program.getInfoDebugLog()); + } + + glslang::TIntermediate* intermediate = program.getIntermediate(type); + if (!intermediate) + { + info_log += "Failed to get shared intermediate code."; + } + + spv::SpvBuildLogger logger; + std::vector spirv; + std::cout << info_log; + glslang::GlslangToSpv(*intermediate, spirv, &logger); + std::cout << logger.getAllMessages(); + glslang::FinalizeProcess(); + path.replace_extension("spirv"); + std::ofstream file(outputDir/path, std::ios::binary); + file.write(reinterpret_cast(spirv.data()), spirv.size() * sizeof(std::uint32_t)); +} diff --git a/Crafter.Build-Shader.cppm b/Crafter.Build-Shader.cppm new file mode 100644 index 0000000..ca65d25 --- /dev/null +++ b/Crafter.Build-Shader.cppm @@ -0,0 +1,36 @@ +/* +Crafter.Build +Copyright (C) 2025 Catcrafts + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3.0 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +module; +#include +#include +#include +export module Crafter.Build:Shader; +namespace fs = std::filesystem; + +export namespace Crafter::Build { + class Shader { + public: + fs::path path; + std::string entrypoint; + EShLanguage type; + Shader(fs::path path, std::string entrypoint, EShLanguage type); + void Compile(fs::path outputDir); + }; +} diff --git a/Crafter.Build.cppm b/Crafter.Build.cppm index d48624f..cfd99c1 100644 --- a/Crafter.Build.cppm +++ b/Crafter.Build.cppm @@ -23,3 +23,4 @@ export import :Dependency; export import :Project; export import :Configuration; export import :ModuleFile; +export import :Shader; diff --git a/DirStackFileIncluder.h b/DirStackFileIncluder.h new file mode 100644 index 0000000..f36212f --- /dev/null +++ b/DirStackFileIncluder.h @@ -0,0 +1,149 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2017 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#pragma once + +#include +#include +#include +#include +#include + +#include + +// Default include class for normal include convention of search backward +// through the stack of active include paths (for nested includes). +// Can be overridden to customize. +class DirStackFileIncluder : public glslang::TShader::Includer { +public: + DirStackFileIncluder() : externalLocalDirectoryCount(0) { } + + virtual IncludeResult* includeLocal(const char* headerName, + const char* includerName, + size_t inclusionDepth) override + { + return readLocalPath(headerName, includerName, (int)inclusionDepth); + } + + virtual IncludeResult* includeSystem(const char* headerName, + const char* /*includerName*/, + size_t /*inclusionDepth*/) override + { + return readSystemPath(headerName); + } + + // Externally set directories. E.g., from a command-line -I. + // - Most-recently pushed are checked first. + // - All these are checked after the parse-time stack of local directories + // is checked. + // - This only applies to the "local" form of #include. + // - Makes its own copy of the path. + virtual void pushExternalLocalDirectory(const std::string& dir) + { + directoryStack.push_back(dir); + externalLocalDirectoryCount = (int)directoryStack.size(); + } + + virtual void releaseInclude(IncludeResult* result) override + { + if (result != nullptr) { + delete [] static_cast(result->userData); + delete result; + } + } + + virtual std::set getIncludedFiles() + { + return includedFiles; + } + + virtual ~DirStackFileIncluder() override { } + +protected: + typedef char tUserDataElement; + std::vector directoryStack; + int externalLocalDirectoryCount; + std::set includedFiles; + + // Search for a valid "local" path based on combining the stack of include + // directories and the nominal name of the header. + virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) + { + // Discard popped include directories, and + // initialize when at parse-time first level. + directoryStack.resize(depth + externalLocalDirectoryCount); + if (depth == 1) + directoryStack.back() = getDirectory(includerName); + + // Find a directory that works, using a reverse search of the include stack. + for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) { + std::string path = *it + '/' + headerName; + std::replace(path.begin(), path.end(), '\\', '/'); + std::ifstream file(path, std::ios_base::binary | std::ios_base::ate); + if (file) { + directoryStack.push_back(getDirectory(path)); + includedFiles.insert(path); + return newIncludeResult(path, file, (int)file.tellg()); + } + } + + return nullptr; + } + + // Search for a valid path. + // Not implemented yet; returning nullptr signals failure to find. + virtual IncludeResult* readSystemPath(const char* /*headerName*/) const + { + return nullptr; + } + + // Do actual reading of the file, filling in a new include result. + virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const + { + char* content = new tUserDataElement [length]; + file.seekg(0, file.beg); + file.read(content, length); + return new IncludeResult(path, content, length, content); + } + + // If no path markers, return current working directory. + // Otherwise, strip file name and return path leading up to it. + virtual std::string getDirectory(const std::string path) const + { + size_t last = path.find_last_of("/\\"); + return last == std::string::npos ? "." : path.substr(0, last); + } +}; \ No newline at end of file diff --git a/build.sh b/build.sh index 7c950ac..0aba0cc 100755 --- a/build.sh +++ b/build.sh @@ -5,19 +5,22 @@ clang++ -std=c++26 Crafter.Build-Dependency.cppm --precompile -fprebuilt-module- 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-ModuleFile.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-ModuleFile.pcm clang++ -std=c++26 Crafter.Build-Project.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build-Project.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.cppm --precompile -fprebuilt-module-path=./build -o ./build/Crafter.Build.pcm clang++ -std=c++26 Crafter.Build-Dependency.cpp -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Dependency_source.o clang++ -std=c++26 Crafter.Build-Configuration.cpp -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Configuration_source.o clang++ -std=c++26 Crafter.Build-ModuleFile.cpp -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-ModuleFile_source.o +clang++ -std=c++26 Crafter.Build-Shader.cpp -fprebuilt-module-path=./build -c -O3 -o ./build/Crafter.Build-Shader_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 ./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 +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.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 +clang++ -Llibvulkan -LlibMachineIndependent, -LlibOSDependent, -LlibGenericCodeGen -Llibglslang -Lglslang-default-resource-limits -LlibSPIRV -LlibSPVRemapper ./build/main.o ./build/Crafter.Build-ModuleFile_source.o ./build/Crafter.Build-ModuleFile.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 rm -rf build diff --git a/main.cpp b/main.cpp index b42b34c..e9a1547 100644 --- a/main.cpp +++ b/main.cpp @@ -66,8 +66,11 @@ int main(int argc, char* argv[]) { } if(run){ - for(const Configuration& config : project.configurations) { - if(config.name == configuration){ + for(Configuration& config : project.configurations) { + if(config.name == configuration) { + if(config.target == "x86_64-w64-mingw64" || config.target == "x86_64-w64-mingw32") { + project.name += ".exe"; + } system(std::format("{}", (projectPath/fs::path(config.outputDir)/project.name).generic_string()).c_str()); return 0; } diff --git a/project.json b/project.json index a50f787..392ead6 100644 --- a/project.json +++ b/project.json @@ -4,10 +4,11 @@ { "name": "base", "standard": "c++26", - "source_files": ["Crafter.Build-Configuration", "Crafter.Build-Project", "Crafter.Build-Dependency", "Crafter.Build-ModuleFile"], - "module_files": ["Crafter.Build-Dependency", "Crafter.Build-Configuration", "Crafter.Build-Project", "Crafter.Build", "Crafter.Build-ModuleFile"], + "source_files": ["Crafter.Build-Configuration", "Crafter.Build-Project", "Crafter.Build-Dependency", "Crafter.Build-ModuleFile", "Crafter.Build-Shader"], + "module_files": ["Crafter.Build-Dependency", "Crafter.Build-Configuration", "Crafter.Build-Project", "Crafter.Build-Shader", "Crafter.Build", "Crafter.Build-ModuleFile"], "build_dir": "./build", - "output_dir": "./bin" + "output_dir": "./bin", + "libs": ["vulkan", "MachineIndependent", "OSDependent", "GenericCodeGen", "glslang", "glslang-default-resource-limits", "SPIRV", "SPVRemapper"] }, { "name": "executable", @@ -23,7 +24,8 @@ { "name": "debug", "extends": ["executable"], - "optimization_level": "0" + "optimization_level": "0", + "debug": true }, { "name": "release",