summaryrefslogtreecommitdiff
path: root/src/rebuild.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebuild.cc')
-rw-r--r--src/rebuild.cc149
1 files changed, 143 insertions, 6 deletions
diff --git a/src/rebuild.cc b/src/rebuild.cc
index 9ddf5ba..4b0c8e5 100644
--- a/src/rebuild.cc
+++ b/src/rebuild.cc
@@ -143,6 +143,92 @@ bool contains(const std::vector<Source>& sources, const std::string& file)
}
}
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// From: http://www.catch22.net/tuts/win32/self-deleting-executables
+void DeleteSelf()
+{
+//#ifdef Windows NT/2000
+#if 1
+ char buf[MAX_PATH];
+ HMODULE module;
+
+ module = GetModuleHandle(0);
+ GetModuleFileName(module, buf, MAX_PATH);
+ CloseHandle((HANDLE)4);
+
+ __asm
+ {
+ lea eax, buf
+ push 0
+ push 0
+ push eax
+ push ExitProcess
+ push module
+ push DeleteFile
+ push UnmapViewOfFile
+ ret
+ }
+#endif
+//#elif Windows 95/98
+#if 0
+ char buf[MAX_PATH];
+ HMODULE module;
+
+ module = GetModuleHandle(0);
+ GetModuleFileName(module, buf, MAX_PATH);
+
+ __asm
+ {
+ lea eax, buf
+ push 0
+ push 0
+ push eax
+ push ExitProcess
+ push module
+ push DeleteFile
+ push FreeLibrary
+ ret
+ }
+#endif
+//endif
+}
+#endif // _WIN32
+
+void copyAndRelaunch(bool dirty_tasks, bool delete_me,
+ int argc, char* argv[],
+ const std::string& copy_src,
+ const std::string& copy_tar,
+ const std::string& compilation_name)
+{
+#ifdef _WIN32
+ if(dirty_tasks && !delete_me)
+ {
+ CopyFile(copy_src.data(), copy_tar.data(), false);
+ SetFileAttributes(copy_tar.data(), FILE_ATTRIBUTE_HIDDEN);
+ auto t = std::filesystem::last_write_time(copy_src);
+ std::filesystem::last_write_time(copy_tar, t);
+
+ STARTUPINFO si{};
+ PROCESS_INFORMATION pi{};
+ si.cb = sizeof(pi);
+ std::string args = copy_tar;
+ for(int i = 1; i < argc; ++i)
+ {
+ args += " ";
+ args += argv[i];
+ }
+ args += " --name ";
+ args += compilation_name;
+
+ CreateProcess(nullptr, args.data(), 0,0,0,0,0,0,&si,&pi);
+ exit(0);
+ }
+#endif // _WIN32
+}
+
bool recompileCheck(const Settings& global_settings, int argc, char* argv[],
bool relaunch_allowed)
{
@@ -152,40 +238,65 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[],
{
std::cout << "Recompile check (" << numConfigFiles << "):\n";
}
+ std::filesystem::path settings_file(global_settings.name);
+ std::filesystem::path argv0_file(argv[0]);
+
+ if(settings_file.is_relative())
+ {
+ settings_file = std::filesystem::current_path() / settings_file;
+ }
+ if(argv0_file.is_relative())
+ {
+ argv0_file = std::filesystem::current_path() / argv0_file;
+ }
+
+ bool delete_me = settings_file.string() != argv0_file.string();
BuildConfiguration config;
+ config.type = TargetType::Executable;
config.name = "ctor";
config.system = OutputSystem::Build;
auto tool_chain = getToolChain(config.system);
append(config.flags.cxxflags,
- getOption(tool_chain, opt::optimization, "3"));
+ getOption(tool_chain, opt::optimization, "2"));
append(config.flags.cxxflags,
getOption(tool_chain, opt::cpp_std, "c++20"));
+ config.flags.cxxflags.push_back("/nologo");
if(hasConfiguration(cfg::ctor_includedir))
{
append(config.flags.cxxflags,
getOption(tool_chain, opt::include_path,
getConfiguration(cfg::ctor_includedir)));
}
+
if(hasConfiguration(cfg::ctor_libdir))
{
append(config.flags.ldflags,
getOption(tool_chain, opt::library_path,
getConfiguration(cfg::ctor_libdir)));
}
- append(config.flags.ldflags, getOption(tool_chain, opt::link, "ctor"));
+// append(config.flags.ldflags, getOption(tool_chain, opt::link, "ctor"));
+ config.flags.ldflags.push_back("build/libctor.lib");
append(config.flags.ldflags, getOption(tool_chain, opt::threads));
+ config.flags.ldflags.push_back("/nologo");
+ config.flags.ldflags.push_back("/SUBSYSTEM:CONSOLE");
+
Settings settings{global_settings};
- settings.verbose = -1; // Make check completely silent.
+ settings.parallel_processes = 1;
+ settings.verbose = 2;//-1; // Make check completely silent.
settings.builddir += "/ctor"; // override builddir to use ctor subdir
-
{
std::filesystem::path buildfile = settings.builddir;
- std::filesystem::path currentfile = argv[0];
+ std::filesystem::path currentfile = settings.name;
+
+ if(currentfile.is_relative())
+ {
+ currentfile = std::filesystem::current_path() / currentfile;
+ }
config.target = std::filesystem::relative(currentfile, buildfile).string();
}
@@ -247,35 +358,61 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[],
}
auto dirty_tasks = build(settings, "ctor", tasks, true); // dryrun
+
+ copyAndRelaunch(dirty_tasks, delete_me, argc, argv,
+ settings.name/*argv[0]*/, "ctor-rebuild-tmp.exe", settings.name);
+
+ bool was_rebuilt{false};
if(dirty_tasks)
{
std::cout << "Rebuilding config.\n";
auto ret = build(settings, "ctor", tasks); // run for real
if(ret != 0)
{
+ if(delete_me)
+ {
+ DeleteSelf();
+ }
return ret;
}
+ was_rebuilt = true;
}
if(reconfigure)
{
+ copyAndRelaunch(true, delete_me, argc, argv,
+ settings.name,
+ "ctor-reconfigure-tmp.exe", settings.name);
std::vector<std::string> args;
args.push_back("reconfigure");
if(!relaunch_allowed)
{
args.push_back("--no-rerun");
}
+ if(delete_me)
+ {
+ args.push_back("--name " + settings.name);
+ }
for(int i = 1; i < argc; ++i)
{
args.push_back(argv[i]);
}
- auto ret = execute(argv[0], args);
+ auto ret = execute(settings.name, args, {});
//if(ret != 0)
{
+ if(delete_me)
+ {
+ DeleteSelf();
+ }
exit(ret);
}
}
+ if(delete_me)
+ {
+ DeleteSelf();
+ }
+
return dirty_tasks;
}