diff --git a/implementations/Crafter.Build-Command.cpp b/implementations/Crafter.Build-Command.cpp index 44e69b7..39aab2f 100644 --- a/implementations/Crafter.Build-Command.cpp +++ b/implementations/Crafter.Build-Command.cpp @@ -124,18 +124,19 @@ namespace Crafter { fs::path exeDir = GetPath(); fs::create_directories(exeDir/config.target); std::string stdPcm = std::format("{}\\{}\\std.pcm", exeDir.string(), config.target); + std::string stdcppm = std::format("{}\\{}\\std.cppm", exeDir.string(), config.target); std::string vsPath = "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe"; std::string command = vsPath + " -latest -property installationPath"; - std::string directoryPath = RunCommand("C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe -latest -property installationPath") + "\\VC\\Tools\\MSVC"; + std::string directoryPath = RunCommand("C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe -latest -property installationPath") + "\\VC\\Tools"; std::vector folders; // Iterate through the directory and collect all subdirectories - for (const auto& entry : fs::directory_iterator(directoryPath)) { + for (const auto& entry : fs::directory_iterator(directoryPath+"\\MSVC")) { if (entry.is_directory()) { folders.push_back(entry.path().filename().string()); } @@ -148,15 +149,18 @@ namespace Crafter { std::string msvcVersion = folders.front(); + clDir = std::format("{}\\{}\\bin\\Hostx64\\x64", directoryPath, msvcVersion); + clangClDir = std::format("{}\\Llvm\\x64\\bin", directoryPath); + std::string sourceFilePath = directoryPath + "\\" + msvcVersion + "\\modules\\std.ixx"; - fs::copy(sourceFilePath, stdPcm, fs::copy_options::overwrite_existing); - if(!fs::exists(stdPcm) || fs::last_write_time(stdPcm) < fs::last_write_time(sourceFilePath)) { - std::string result = RunCommand(std::format("clang++ -std=c++26 -target x86_64-pc-windows-msvc -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile {}\\{}\\std.cppm -o {}", exeDir.string(), config.target, stdPcm)); + fs::copy(sourceFilePath, stdcppm, fs::copy_options::overwrite_existing); + std::string result = RunCommand(std::format("cd {}\\{} && {}\\clang-cl.exe /EHsc /MD /std:c++latest --target=x86_64-pc-windows-msvc -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile std.cppm -o std.pcm", exeDir.string(), config.target, clangClDir, stdPcm)); if(result != "") { throw std::runtime_error(result); } + result = RunCommand(std::format("cd {}\\{} && {}\\cl.exe /std:c++latest /EHsc /nologo /W4 /MD /c {}", exeDir.string(), config.target, clDir, sourceFilePath)); } } diff --git a/implementations/Crafter.Build-Configuration.cpp b/implementations/Crafter.Build-Configuration.cpp index 08b3dc8..7770845 100644 --- a/implementations/Crafter.Build-Configuration.cpp +++ b/implementations/Crafter.Build-Configuration.cpp @@ -58,7 +58,12 @@ namespace Crafter { if(config.contains("standard")) { standard = config["standard"].get(); } else { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu standard = "c++26"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + standard = "c++latest"; + #endif } if(config.contains("target")) { target = config["target"].get(); diff --git a/implementations/Crafter.Build-Project.cpp b/implementations/Crafter.Build-Project.cpp index 0f8dfbe..4070f09 100644 --- a/implementations/Crafter.Build-Project.cpp +++ b/implementations/Crafter.Build-Project.cpp @@ -146,13 +146,23 @@ namespace Crafter { void AddLibsRecursive(std::string& libsString, std::unordered_set depLibSet, Configuration& depConfig) { for(const std::string& lib2 : depConfig.libs) { if (depLibSet.insert(lib2).second) { - libsString+=std::format(" -l{}", lib2); + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu + libsString += std::format(" -l{}", lib2); + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + libsString+=std::format(" {}.lib", lib2); + #endif } } for(const std::tuple, Configuration&>& dep2 : depConfig.dependencies) { std::string outputLib = std::get<0>(dep2)->name+std::get<1>(dep2).name; if (depLibSet.insert(outputLib).second) { - libsString+=std::format(" -l{}", outputLib); + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu + libsString += std::format(" -l{}", outputLib); + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + libsString+=std::format(" {}.lib", outputLib); + #endif } AddLibsRecursive(libsString, depLibSet, std::get<1>(dep2)); } @@ -230,39 +240,82 @@ namespace Crafter { std::string editedTarget = config.target; std::replace(editedTarget.begin(), editedTarget.end(), '-', '_'); + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu std::string command = std::format("clang++ --target={} -march={} -mtune={} -std={} -D CRAFTER_BUILD_CONFIGURATION_TARGET_{} -fprebuilt-module-path={}", config.target, config.march, config.march, config.standard, editedTarget, (exeDir/config.target).string()); + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + std::string command = std::format("{}\\clang-cl.exe /EHsc --target={} -march={} -mtune={} /std:{} /D CRAFTER_BUILD_CONFIGURATION_TARGET_{} -fprebuilt-module-path={}", clangClDir, config.target, config.march, config.march, config.standard, editedTarget, (exeDir/config.target).string()); + #endif if(config.target == "wasm32-wasi") { command += std::format(" --sysroot={} -fno-exceptions -fno-c++-static-destructors", (exeDir/"wasi-sysroot-28.0").string()); } - for(const Define& define : config.defines) { - if(define.value.empty()) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu + if(define.value.empty()) { command += std::format(" -D {}", define.name); } else { command += std::format(" -D {}={}", define.name, define.value); } } + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + if(define.value.empty()) { + command += std::format(" /D {}", define.name); + } else { + command += std::format(" /D {}={}", define.name, define.value); + } + } + #endif + + + for(const Define& define : config.defines) { + fs::path pcmDir; if(config.type == CRAFTER_CONFIGURATION_TYPE_SHARED_LIBRARY) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu command += " -fPIC -D CRAFTER_BUILD_CONFIGURATION_TYPE_SHARED_LIBRARY"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + command += " /D CRAFTER_BUILD_CONFIGURATION_TYPE_SHARED_LIBRARY"; + #endif pcmDir = binDir; } else if(config.type == CRAFTER_CONFIGURATION_TYPE_LIBRARY) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu command += " -D CRAFTER_BUILD_CONFIGURATION_TYPE_LIBRARY"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + command += " /D CRAFTER_BUILD_CONFIGURATION_TYPE_LIBRARY"; + #endif pcmDir = binDir; } else { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu command += " -D CRAFTER_BUILD_CONFIGURATION_TYPE_EXECUTABLE"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + command += " /D CRAFTER_BUILD_CONFIGURATION_TYPE_EXECUTABLE"; + #endif pcmDir = buildDir; } command += std::format(" -fprebuilt-module-path={}", pcmDir.string()); if(config.debug) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu command += " -g -D CRAFTER_BUILD_CONFIGURATION_DEBUG"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + command += " -g /MDd /D CRAFTER_BUILD_CONFIGURATION_DEBUG"; + #endif } else { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu command += " -O3"; + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + command += " /Ot"; + #endif } for(const std::string& dir : config.includeDirs) { @@ -272,7 +325,12 @@ namespace Crafter { std::unordered_set depLibSet; std::vector depThreads = std::vector(config.dependencies.size()); std::mutex libMutex; + std::string files; + + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu) std::string libsString; + #endif + std::vector resultsDep(config.dependencies.size()); for(std::uint_fast32_t i = 0; i < depThreads.size(); i++) { @@ -289,11 +347,18 @@ namespace Crafter { } resultsDep[i] = depResult.errors; + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu if (depLibSet.insert(outputLib).second) { libsString+=std::format(" -l{}", outputLib); } - AddLibsRecursive(libsString, depLibSet, std::get<1>(config.dependencies[i])); + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + if (depLibSet.insert(outputLib).second) { + files+=std::format(" {}.lib", outputLib); + } + AddLibsRecursive(files, depLibSet, std::get<1>(config.dependencies[i])); + #endif libMutex.unlock(); }); } @@ -311,13 +376,15 @@ namespace Crafter { return buildResult; } - std::string files; - - for(const fs::path& cFile: config.c_files) { files+=std::format(" {}_source.o ",(buildDir/cFile.filename()).string()); if(!fs::exists((buildDir/cFile.filename()).string()+"_source.o") || fs::last_write_time(cFile.string()+".c") > fs::last_write_time((buildDir/cFile.filename()).string()+"_source.o")) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu threads.emplace_back(&RunClang, std::format("clang {}.c -c -o {}_source.o", cFile.string(), (buildDir/cFile.filename()).string())); + #endif + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + threads.emplace_back(&RunClang, std::format("{} {}.c -c -o {}_source.o", command, cFile.string(), (buildDir/cFile.filename()).string())); + #endif } } @@ -373,6 +440,7 @@ namespace Crafter { command += libsString; + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu for(const std::string& lib : config.libs) { depLibSet.insert(lib); command += std::format(" -l{}", lib); @@ -381,6 +449,7 @@ namespace Crafter { for(const std::string& dir : config.libDirs) { command += std::format(" -L{}", dir); } + #endif fileThread.join(); @@ -389,15 +458,34 @@ namespace Crafter { } if(buildResult.repack) { - if(config.type == CRAFTER_CONFIGURATION_TYPE_EXECUTABLE){ + if(config.type == CRAFTER_CONFIGURATION_TYPE_EXECUTABLE) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu if(config.target == "wasm32-wasi") { outputName += ".wasm"; } buildResult.errors = RunClang(std::format("{}{} -o {} -fuse-ld=lld", command, files, (binDir/outputName).string())); - } else if(config.type == CRAFTER_CONFIGURATION_TYPE_LIBRARY){ + #endif + + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + std::string libPath = ""; + for(const std::string_view lib : config.libDirs) { + libPath += std::format(" /LIBPATH:{}", lib); + } + + buildResult.errors = RunCommand(std::format("link {} {} .\\build\\std.o msvcrt.lib kernel32.lib user32.lib /OUT:{}.exe", lib, files, (binDir/outputName).string())); + #endif + } else if(config.type == CRAFTER_CONFIGURATION_TYPE_LIBRARY) { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu RunCommandIgnore(std::format("ar r {}.a {}", (binDir/fs::path(std::string("lib")+outputName)).string(), files)); + #endif + + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + RunCommandIgnore(std::format("lib {} /OUT:{}.lib", files, (binDir/fs::path(outputName)).string())); + #endif } else { + #ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu buildResult.errors = RunClang(std::format("{}{} -shared -o {}.so -Wl,-rpath,'$ORIGIN' -fuse-ld=lld", command, files, (binDir/(std::string("lib")+outputName)).string())); + #endif } } diff --git a/interfaces/Crafter.Build-Command.cppm b/interfaces/Crafter.Build-Command.cppm index bc127d0..638574d 100644 --- a/interfaces/Crafter.Build-Command.cppm +++ b/interfaces/Crafter.Build-Command.cppm @@ -38,6 +38,10 @@ namespace Crafter { export class Project; export class Configuration; + #if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32) + export std::string clDir; + export std::string clangClDir; + #endif export std::string RunCommand(const std::string_view cmd); export void RunCommandIgnore(const std::string_view cmd); export std::string RunClang(const std::string_view cmd); diff --git a/project.json b/project.json index 28985be..b553389 100644 --- a/project.json +++ b/project.json @@ -4,50 +4,66 @@ { "name": "base", "interfaces": ["interfaces/Crafter.Build-Command", "interfaces/Crafter.Build-Configuration", "interfaces/Crafter.Build-Module", "interfaces/Crafter.Build-Project", "interfaces/Crafter.Build-Shader", "interfaces/Crafter.Build", "interfaces/Crafter.Build-Implementation", "interfaces/Crafter.Build-Test", "interfaces/Crafter.Build-CompileStatus"], - "implementations": ["implementations/Crafter.Build-Command", "implementations/Crafter.Build-Configuration", "implementations/Crafter.Build-Module", "implementations/Crafter.Build-Project", "implementations/Crafter.Build-Shader", "implementations/Crafter.Build-Implementation", "implementations/Crafter.Build-Test"], + "implementations": ["implementations/Crafter.Build-Command", "implementations/Crafter.Build-Configuration", "implementations/Crafter.Build-Module", "implementations/Crafter.Build-Project", "implementations/Crafter.Build-Shader", "implementations/Crafter.Build-Implementation", "implementations/Crafter.Build-Test"] + }, + { + "name": "libs-linux-gnu", + "target": "x86_64-pc-linux-gnu", "libs": ["vulkan", "MachineIndependent", "OSDependent", "GenericCodeGen", "glslang", "glslang-default-resource-limits", "SPIRV", "tbb"] }, { - "name": "libs-gnu", - "libs": ["vulkan", "MachineIndependent", "OSDependent", "GenericCodeGen", "glslang", "glslang-default-resource-limits", "SPIRV", "tbb"] + "name": "libs-windows-msvc", + "target": "x86_64-pc-windows-msvc", + "libs": ["vulkan-1", "MachineIndependent", "OSDependent", "GenericCodeGen", "glslang", "glslang-default-resource-limits", "SPIRV", "SPIRV-Tools-opt", "SPIRV-Tools"] }, { - "name": "executable", - "extends": ["base", "libs-gnu"], - "type":"executable", + "name": "libs-windows-msvc-debug", + "target": "x86_64-pc-windows-msvc", + "libs": ["vulkan-1", "MachineIndependentd", "OSDependentd", "GenericCodeGend", "glslangd", "glslang-default-resource-limitsd", "SPIRVd", "SPIRV-Tools-optd", "SPIRV-Toolsd"] + }, + { + "name": "executable-linux-gnu", + "extends": ["base", "libs-linux-gnu"], "implementations": ["implementations/main"] }, { - "name": "executable-debug", - "extends": ["executable", "libs-gnu"], + "name": "executable-linux-gnu-debug", + "extends": ["executable-linux-gnu"], "debug": true }, { - "name": "lib", - "extends": ["base", "libs-gnu"], + "name": "lib-linux-gnu", + "extends": ["base", "libs-linux-gnu"], "type":"library" }, { - "name": "lib-shared", - "extends": ["base", "libs-gnu"], - "type":"shared-library" + "name": "lib-linux-gnu-dev", + "extends": ["lib-linux-gnu"], + "debug": true }, { - "name": "lib-debug", - "extends": ["lib", "libs-gnu"], - "debug": true - } - ], - "tests": [ + "name": "executable-windows-msvc", + "extends": ["base", "libs-windows-msvc"], + "implementations": ["implementations/main"] + }, { - "name": "should-compile", - "implementations": ["tests/ShouldCompile"], - "dependencies": [ - { - "path":"./project.json", - "configuration":"lib-shared" - } - ] + "name": "executable-windows-msvc-debug", + "extends": ["base", "libs-windows-msvc-debug"], + "implementations": ["implementations/main"], + "debug": true + }, + { + "name": "lib-windows-msvc", + "extends": ["base", "libs-windows-msvc"], + "type":"library", + "implementations": ["implementations/main"] + }, + { + "name": "lib-windows-msvc-debug", + "extends": ["base", "libs-windows-msvc-debug"], + "type":"library", + "implementations": ["implementations/main"], + "debug": true } ] } \ No newline at end of file