diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2022-08-19 18:09:25 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2022-08-19 18:09:25 +0200 |
commit | 7436d83ef371d4fee4a66bec235e102ed80275db (patch) | |
tree | 243b416b1b6e10a43b9495121af0e57522543de0 /src/rebuild.cc | |
parent | e1030dc6e69863438fe35a628bd6af9abc814b4a (diff) |
Add support for msvc tool-chain (cl.exe/link.exe and lib.exe) on windows.
Diffstat (limited to 'src/rebuild.cc')
-rw-r--r-- | src/rebuild.cc | 149 |
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; } |