/* Crafter.Build Copyright (C) 2025 Catcrafts® Catcrafts.net 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 module Crafter.Build; using namespace Crafter::Build; 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& threads, const std::vector& modules, std::string& files, const fs::path& buildDir) { std::string defines; for(const Define& define : config.defines) { defines+=define.ToString(); } for(const fs::path& sourceFile : config.sourceFiles) { files+=std::format("{}_source.o ",(buildDir/sourceFile.filename()).generic_string()); if(Source::Check(sourceFile, modules, config, buildDir)) { threads.emplace_back([&config, sourceFile, pcmDir, target, clangDir, flags, march, buildDir, defines](){ 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) { std::cout << command << std::endl; } BounceCommand(command.c_str()); }); } } } bool Source::Check(const fs::path& path, const std::vector& modules, const Configuration& config, const fs::path& buildDir) { if(!fs::exists((buildDir/path.filename()).generic_string()+"_source.o") || fs::last_write_time((path).generic_string()+".cpp") > fs::last_write_time((buildDir/path.filename()).generic_string()+"_source.o")) { return true; } std::ifstream t(path.generic_string()+".cpp"); std::stringstream buffer; buffer << t.rdbuf(); std::string fileContent = buffer.str(); { std::regex pattern(R"(module ([a-zA-Z_\-0-9\.]*);)"); std::sregex_iterator currentMatch(fileContent.begin(), fileContent.end(), pattern); std::sregex_iterator lastMatch; while (currentMatch != lastMatch) { std::smatch match = *currentMatch; for(const Module& module : modules) { if(module.name == match[1] && module.needsRecompiling) { return true; } } ++currentMatch; } } { std::regex pattern(R"(import ([a-zA-Z_\-0-9\.]*);)"); std::sregex_iterator currentMatch(fileContent.begin(), fileContent.end(), pattern); std::sregex_iterator lastMatch; while (currentMatch != lastMatch) { std::smatch match = *currentMatch; for(const Module& module : modules) { if(module.name == match[1] && module.needsRecompiling) { return true; } } ++currentMatch; } } return false; }