summaryrefslogtreecommitdiff
path: root/src/rebuild.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebuild.cc')
-rw-r--r--src/rebuild.cc141
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));
+ }
+ }
+ }
+}