diff options
Diffstat (limited to 'src/rebuild.cc')
-rw-r--r-- | src/rebuild.cc | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/rebuild.cc b/src/rebuild.cc new file mode 100644 index 0000000..43c4c98 --- /dev/null +++ b/src/rebuild.cc @@ -0,0 +1,141 @@ +#include "rebuild.h" + +#include <iostream> +#include <filesystem> +#include <algorithm> + +#include "execute.h" +#include "configure.h" +#include "settings.h" +#include "libcppbuild.h" + +std::array<BuildConfigurationEntry, 1024> configFiles; +std::size_t numConfigFiles{0}; + +// TODO: Use c++20 when ready, somehing like this: +//int reg(const std::source_location location = std::source_location::current()) +int reg(const char* location, std::vector<BuildConfiguration> (*cb)()) +{ + // NOTE: std::cout cannot be used here + if(numConfigFiles >= configFiles.size()) + { + fprintf(stderr, "Max %d build configurations currently supported.\n", + (int)configFiles.size()); + exit(1); + } + + configFiles[numConfigFiles].file = location; + configFiles[numConfigFiles].cb = cb; + ++numConfigFiles; + + return 0; +} + +int unreg(const char* location) +{ + std::size_t found{0}; + for(std::size_t i = 0; i < numConfigFiles;) + { + if(std::string(location) == configFiles[i].file) + { + ++found; + for(std::size_t j = i; j < numConfigFiles; ++j) + { + configFiles[j] = configFiles[j + 1]; + } + --numConfigFiles; + } + else + { + ++i; + } + } + + return found; +} + +void recompileCheck(const Settings& settings, int argc, char* argv[], + bool force, bool relaunch_allowed) +{ + bool dirty{force}; + + std::vector<std::string> args; + args.push_back("-s"); + args.push_back("-O3"); + args.push_back("-std=c++17"); + args.push_back("-pthread"); + + std::filesystem::path binFile(argv[0]); + + if(std::filesystem::exists(configurationFile)) + { + args.push_back(configurationFile.string()); + + if(std::filesystem::last_write_time(binFile) <= + std::filesystem::last_write_time(configurationFile)) + { + dirty = true; + } + + const auto& c = configuration(); + if(&c == &default_configuration) + { + // configuration.cc exists, but currently compiled with the default one. + dirty = true; + } + } + + if(settings.verbose > 1) + { + std::cout << "Recompile check (" << numConfigFiles << "):\n"; + } + + for(std::size_t i = 0; i < numConfigFiles; ++i) + { + std::string location = configFiles[i].file; + if(settings.verbose > 1) + { + std::cout << " - " << location << "\n"; + } + std::filesystem::path configFile(location); + if(std::filesystem::last_write_time(binFile) <= + std::filesystem::last_write_time(configFile)) + { + dirty = true; + } + + // Support adding multiple config functions from the same file + if(std::find(args.begin(), args.end(), location) == std::end(args)) + { + args.push_back(location); + } + } + args.push_back("libcppbuild.a"); + args.push_back("-o"); + args.push_back(binFile.string()); + + if(dirty) + { + std::cout << "Rebuilding config\n"; + auto tool = getConfiguration(cfg::build_cxx, "/usr/bin/g++"); + auto ret = execute(tool, args, settings.verbose > 0); + if(ret != 0) + { + std::cerr << "Failed: ." << ret << "\n"; + exit(1); + } + else + { + if(relaunch_allowed) + { + std::cout << "Re-launch\n"; + std::vector<std::string> args; + for(int i = 1; i < argc; ++i) + { + args.push_back(argv[i]); + } + exit(execute(argv[0], args, settings.verbose > 0)); + } + } + } +} |