From c8e7d8922310108f2d46189a8f48abcb68e72534 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 21 Aug 2022 12:38:35 +0200 Subject: WIP: Deferred linking of self --- src/configure.cc | 39 ------------------- src/execute.cc | 6 ++- src/execute.h | 2 +- src/rebuild.cc | 114 +------------------------------------------------------ src/task_ld.cc | 5 ++- src/task_ld.h | 4 +- src/tasks.cc | 7 ++-- src/tasks.h | 3 +- 8 files changed, 19 insertions(+), 161 deletions(-) diff --git a/src/configure.cc b/src/configure.cc index bb94202..8348c19 100644 --- a/src/configure.cc +++ b/src/configure.cc @@ -51,40 +51,6 @@ const Configuration& defConfiguration() #endif -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif - -void _copyAndRelaunch(int argc, char* argv[], - const std::string& copy_src, - const std::string& copy_tar, - const std::string& compilation_name) -{ -#ifdef _WIN32 - 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 + " configure"; - 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(1); -#endif // _WIN32 -} - namespace ctor { std::optional includedir; @@ -428,11 +394,6 @@ int regenerateCache(Settings& settings, argv0_file = std::filesystem::current_path() / argv0_file; } - if(settings_file.string() == argv0_file.string()) - { - _copyAndRelaunch(vargs.size(), vargs.data(), vargs[0], "ctor-configure-tmp.exe", settings.name); - exit(0); - } if(host_arch.empty()) { diff --git a/src/execute.cc b/src/execute.cc index 5e59ff6..85c1da1 100644 --- a/src/execute.cc +++ b/src/execute.cc @@ -44,7 +44,7 @@ int parent_waitpid(pid_t pid) int execute(const std::string& command, const std::vector& args, const std::map& env, - bool verbose) + bool verbose, bool terminate) { std::vector argv; argv.push_back(command.data()); @@ -176,6 +176,10 @@ int execute(const std::string& command, return 1; // Could not start process; } + if(terminate) + { + ExitProcess(0); + } // Now 'pi.hProcess' contains the process HANDLE, which you can use to // wait for it like this: const DWORD infinite = 0xFFFFFFFF; diff --git a/src/execute.h b/src/execute.h index 2ad81d1..e0626ab 100644 --- a/src/execute.h +++ b/src/execute.h @@ -10,4 +10,4 @@ int execute(const std::string& command, const std::vector& args, const std::map& env, - bool verbose = true); + bool verbose = true, bool terminate = false); diff --git a/src/rebuild.cc b/src/rebuild.cc index 4b0c8e5..cfbe790 100644 --- a/src/rebuild.cc +++ b/src/rebuild.cc @@ -143,92 +143,6 @@ bool contains(const std::vector& sources, const std::string& file) } } -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include - -// 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) { @@ -250,8 +164,6 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[], argv0_file = std::filesystem::current_path() / argv0_file; } - bool delete_me = settings_file.string() != argv0_file.string(); - BuildConfiguration config; config.type = TargetType::Executable; @@ -335,7 +247,7 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[], } } - auto tasks = taskFactory({config}, settings, {}); + auto tasks = taskFactory({config}, settings, {}, true); for(auto task : tasks) { @@ -359,9 +271,6 @@ 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) { @@ -369,10 +278,6 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[], auto ret = build(settings, "ctor", tasks); // run for real if(ret != 0) { - if(delete_me) - { - DeleteSelf(); - } return ret; } was_rebuilt = true; @@ -380,19 +285,12 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[], if(reconfigure) { - copyAndRelaunch(true, delete_me, argc, argv, - settings.name, - "ctor-reconfigure-tmp.exe", settings.name); std::vector 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]); @@ -400,18 +298,8 @@ bool recompileCheck(const Settings& global_settings, int argc, char* argv[], auto ret = execute(settings.name, args, {}); //if(ret != 0) { - if(delete_me) - { - DeleteSelf(); - } exit(ret); } - - } - - if(delete_me) - { - DeleteSelf(); } return dirty_tasks; diff --git a/src/task_ld.cc b/src/task_ld.cc index ba1eb1b..3d89f90 100644 --- a/src/task_ld.cc +++ b/src/task_ld.cc @@ -15,11 +15,12 @@ TaskLD::TaskLD(const BuildConfiguration& config, const Settings& settings, const std::string& target, const std::vector& objects, - const std::string& sourceDir) + const std::string& sourceDir, bool is_self) : Task(config, settings, sourceDir) , config(config) , settings(settings) , sourceDir(sourceDir) + , is_self(is_self) { target_type = config.type; if(target_type == TargetType::Auto) @@ -117,7 +118,7 @@ int TaskLD::runInner() auto tool = linker(); const auto& cfg = configuration(); - return execute(tool, args, cfg.env, settings.verbose > 0); + return execute(tool, args, cfg.env, settings.verbose > 0, is_self); } int TaskLD::clean() diff --git a/src/task_ld.h b/src/task_ld.h index 8625075..348d23b 100644 --- a/src/task_ld.h +++ b/src/task_ld.h @@ -21,7 +21,8 @@ public: const Settings& settings, const std::string& target, const std::vector& objects, - const std::string& _sourceDir); + const std::string& _sourceDir, + bool is_self); virtual ~TaskLD() = default; bool dirtyInner() override; @@ -47,4 +48,5 @@ private: const BuildConfiguration& config; const Settings& settings; std::string sourceDir; + bool is_self; }; diff --git a/src/tasks.cc b/src/tasks.cc index d621cd9..435bef1 100644 --- a/src/tasks.cc +++ b/src/tasks.cc @@ -79,7 +79,8 @@ const std::deque& getTargets(const Settings& settings, std::set> taskFactory(const BuildConfiguration& config, const Settings& settings, - const std::string& sourceDir) + const std::string& sourceDir, + bool is_self) { std::set> tasks; @@ -161,7 +162,7 @@ std::set> taskFactory(const BuildConfiguration& config, case TargetType::Executable: case TargetType::UnitTest: tasks.insert(std::make_shared(config, settings, config.target, - objects, sourceDir)); + objects, sourceDir, is_self)); break; case TargetType::Object: @@ -207,7 +208,7 @@ std::set> getTasks(const Settings& settings, std::find(std::begin(names), std::end(names), target.config.target) != std::end(names)) { std::vector objects; - auto t = taskFactory(target.config, settings, target.path); + auto t = taskFactory(target.config, settings, target.path, false); tasks.insert(t.begin(), t.end()); } } diff --git a/src/tasks.h b/src/tasks.h index d7634b7..97b115c 100644 --- a/src/tasks.h +++ b/src/tasks.h @@ -40,4 +40,5 @@ std::set> getTasks(const Settings& settings, //! link target and all its objects files (if any). std::set> taskFactory(const BuildConfiguration& config, const Settings& settings, - const std::string& sourceDir); + const std::string& sourceDir, + bool is_self); -- cgit v1.2.3