diff --git a/PC/VS8.0/_bsddb.vcproj b/PC/VS8.0/_bsddb.vcproj index 0dbeb2850e8..59b7ce246f6 100644 --- a/PC/VS8.0/_bsddb.vcproj +++ b/PC/VS8.0/_bsddb.vcproj @@ -42,7 +42,7 @@ /> @@ -423,7 +418,7 @@ /> diff --git a/PC/VS8.0/_elementtree.vcproj b/PC/VS8.0/_elementtree.vcproj index 32fac0c7547..457da72f04d 100644 --- a/PC/VS8.0/_elementtree.vcproj +++ b/PC/VS8.0/_elementtree.vcproj @@ -56,7 +56,6 @@ /> @@ -437,7 +431,6 @@ /> diff --git a/PC/VS8.0/_sqlite3.vcproj b/PC/VS8.0/_sqlite3.vcproj index 2343afa3517..689585f9ce2 100644 --- a/PC/VS8.0/_sqlite3.vcproj +++ b/PC/VS8.0/_sqlite3.vcproj @@ -42,7 +42,7 @@ /> @@ -435,7 +417,7 @@ /> diff --git a/PC/VS8.0/_ssl.vcproj b/PC/VS8.0/_ssl.vcproj index 72d42920b2b..69f77263178 100644 --- a/PC/VS8.0/_ssl.vcproj +++ b/PC/VS8.0/_ssl.vcproj @@ -27,7 +27,7 @@ > - - diff --git a/PC/VS8.0/_tkinter.vcproj b/PC/VS8.0/_tkinter.vcproj index f1d9bb4f7f1..9700bdea74a 100644 --- a/PC/VS8.0/_tkinter.vcproj +++ b/PC/VS8.0/_tkinter.vcproj @@ -56,7 +56,7 @@ /> + @@ -104,6 +107,96 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + diff --git a/PC/VS8.0/debug.vsprops b/PC/VS8.0/debug.vsprops index 803da6ea8f5..bc643cb6be5 100644 --- a/PC/VS8.0/debug.vsprops +++ b/PC/VS8.0/debug.vsprops @@ -8,4 +8,8 @@ Name="VCCLCompilerTool" PreprocessorDefinitions="_DEBUG" /> - \ No newline at end of file + + diff --git a/PC/VS8.0/kill_python.c b/PC/VS8.0/kill_python.c new file mode 100644 index 00000000000..8ee22e826aa --- /dev/null +++ b/PC/VS8.0/kill_python.c @@ -0,0 +1,178 @@ +/* + * Helper program for killing lingering python[_d].exe processes before + * building, thus attempting to avoid build failures due to files being + * locked. + */ + +#include +#include +#include +#include + +#pragma comment(lib, "psapi") + +#ifdef _DEBUG +#define PYTHON_EXE (L"python_d.exe") +#define PYTHON_EXE_LEN (12) +#define KILL_PYTHON_EXE (L"kill_python_d.exe") +#define KILL_PYTHON_EXE_LEN (17) +#else +#define PYTHON_EXE (L"python.exe") +#define PYTHON_EXE_LEN (10) +#define KILL_PYTHON_EXE (L"kill_python.exe") +#define KILL_PYTHON_EXE_LEN (15) +#endif + +int +main(int argc, char **argv) +{ + HANDLE hp, hsp, hsm; /* process, snapshot processes, snapshot modules */ + DWORD dac, our_pid; + size_t len; + wchar_t path[MAX_PATH+1]; + + MODULEENTRY32W me; + PROCESSENTRY32W pe; + + me.dwSize = sizeof(MODULEENTRY32W); + pe.dwSize = sizeof(PROCESSENTRY32W); + + memset(path, 0, MAX_PATH+1); + + our_pid = GetCurrentProcessId(); + + hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid); + if (hsm == INVALID_HANDLE_VALUE) { + printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError()); + return 1; + } + + if (!Module32FirstW(hsm, &me)) { + printf("Module32FirstW[1] failed: %d\n", GetLastError()); + CloseHandle(hsm); + return 1; + } + + /* + * Enumerate over the modules for the current process in order to find + * kill_process[_d].exe, then take a note of the directory it lives in. + */ + do { + if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN)) + continue; + + len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN; + wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); + + break; + + } while (Module32NextW(hsm, &me)); + + CloseHandle(hsm); + + if (path == NULL) { + printf("failed to discern directory of running process\n"); + return 1; + } + + /* + * Take a snapshot of system processes. Enumerate over the snapshot, + * looking for python processes. When we find one, verify it lives + * in the same directory we live in. If it does, kill it. If we're + * unable to kill it, treat this as a fatal error and return 1. + * + * The rationale behind this is that we're called at the start of the + * build process on the basis that we'll take care of killing any + * running instances, such that the build won't encounter permission + * denied errors during linking. If we can't kill one of the processes, + * we can't provide this assurance, and the build shouldn't start. + */ + + hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hsp == INVALID_HANDLE_VALUE) { + printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError()); + return 1; + } + + if (!Process32FirstW(hsp, &pe)) { + printf("Process32FirstW failed: %d\n", GetLastError()); + CloseHandle(hsp); + return 1; + } + + dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE; + do { + + /* + * XXX TODO: if we really wanted to be fancy, we could check the + * modules for all processes (not just the python[_d].exe ones) + * and see if any of our DLLs are loaded (i.e. python30[_d].dll), + * as that would also inhibit our ability to rebuild the solution. + * Not worth loosing sleep over though; for now, a simple check + * for just the python executable should be sufficient. + */ + + if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN)) + /* This isn't a python process. */ + continue; + + /* It's a python process, so figure out which directory it's in... */ + hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID); + if (hsm == INVALID_HANDLE_VALUE) + /* + * If our module snapshot fails (which will happen if we don't own + * the process), just ignore it and continue. (It seems different + * versions of Windows return different values for GetLastError() + * in this situation; it's easier to just ignore it and move on vs. + * stopping the build for what could be a false positive.) + */ + continue; + + if (!Module32FirstW(hsm, &me)) { + printf("Module32FirstW[2] failed: %d\n", GetLastError()); + CloseHandle(hsp); + CloseHandle(hsm); + return 1; + } + + do { + if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN)) + /* Wrong module, we're looking for python[_d].exe... */ + continue; + + if (_wcsnicmp(path, me.szExePath, len)) + /* Process doesn't live in our directory. */ + break; + + /* Python process residing in the right directory, kill it! */ + hp = OpenProcess(dac, FALSE, pe.th32ProcessID); + if (!hp) { + printf("OpenProcess failed: %d\n", GetLastError()); + CloseHandle(hsp); + CloseHandle(hsm); + return 1; + } + + if (!TerminateProcess(hp, 1)) { + printf("TerminateProcess failed: %d\n", GetLastError()); + CloseHandle(hsp); + CloseHandle(hsm); + CloseHandle(hp); + return 1; + } + + CloseHandle(hp); + break; + + } while (Module32NextW(hsm, &me)); + + CloseHandle(hsm); + + } while (Process32NextW(hsp, &pe)); + + CloseHandle(hsp); + + return 0; +} + +/* vi: set ts=8 sw=4 sts=4 expandtab */ diff --git a/PC/VS8.0/make_versioninfo.vcproj b/PC/VS8.0/make_versioninfo.vcproj index b097162f790..9dbf10d95a3 100644 --- a/PC/VS8.0/make_versioninfo.vcproj +++ b/PC/VS8.0/make_versioninfo.vcproj @@ -67,7 +67,6 @@ /> + + + + + + + + diff --git a/PC/VS8.0/python.vcproj b/PC/VS8.0/python.vcproj index 7d10e1446de..2f47c0ee8dd 100644 --- a/PC/VS8.0/python.vcproj +++ b/PC/VS8.0/python.vcproj @@ -62,7 +62,6 @@ /> + + @@ -866,6 +870,10 @@ RelativePath="..\..\Include\pymactoolbox.h" > + + @@ -914,10 +922,6 @@ RelativePath="..\..\Include\sliceobject.h" > - - @@ -986,10 +990,10 @@ RelativePath="..\..\Modules\_fileio.c" > - - + + @@ -1338,6 +1342,10 @@ RelativePath="..\..\Objects\bytes_methods.c" > + + @@ -1458,10 +1466,6 @@ RelativePath="..\..\Objects\sliceobject.c" > - - diff --git a/PC/VS8.0/release.vsprops b/PC/VS8.0/release.vsprops index c4f85678e30..08def90651b 100644 --- a/PC/VS8.0/release.vsprops +++ b/PC/VS8.0/release.vsprops @@ -8,4 +8,8 @@ Name="VCCLCompilerTool" PreprocessorDefinitions="NDEBUG" /> + diff --git a/PC/VS8.0/x64.vsprops b/PC/VS8.0/x64.vsprops index 551469216a4..9f88d443fe4 100644 --- a/PC/VS8.0/x64.vsprops +++ b/PC/VS8.0/x64.vsprops @@ -15,4 +15,8 @@ Name="VCLinkerTool" TargetMachine="17" /> + diff --git a/PCbuild/_elementtree.vcproj b/PCbuild/_elementtree.vcproj index c22c252014c..b308c186986 100644 --- a/PCbuild/_elementtree.vcproj +++ b/PCbuild/_elementtree.vcproj @@ -56,7 +56,6 @@ /> @@ -437,7 +431,6 @@ /> diff --git a/PCbuild/make_versioninfo.vcproj b/PCbuild/make_versioninfo.vcproj index dcb922bf1e8..e2b86c73f2f 100644 --- a/PCbuild/make_versioninfo.vcproj +++ b/PCbuild/make_versioninfo.vcproj @@ -67,7 +67,6 @@ />