Skip to content

[bpo-30916] Pre-build OpenSSL and Tcl/Tk for Windows #2688

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Doc/make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@ pushd %~dp0

set this=%~n0

if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build
call ..\PCBuild\find_python.bat %PYTHON%
if "%SPHINXBUILD%" EQU "" if "%PYTHON%" NEQ "" (
set SPHINXBUILD=%PYTHON%\..\Scripts\sphinx-build.exe
rem Cannot use %SPHINXBUILD% in the same block where we set it
if not exist "%PYTHON%\..\Scripts\sphinx-build.exe" (
echo Installing sphinx with %PYTHON%
"%PYTHON%" -m pip install sphinx
if errorlevel 1 exit /B
)
)

if "%PYTHON%" EQU "" set PYTHON=py
if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build

if "%1" NEQ "htmlhelp" goto :skiphhcsearch
if exist "%HTMLHELP%" goto :skiphhcsearch
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,7 @@ def test_load_default_certs_env(self):
self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})

@unittest.skipUnless(sys.platform == "win32", "Windows specific")
@unittest.skipIf(hasattr(sys, "gettotalrefcount"), "Debug build does not share environment between CRTs")
def test_load_default_certs_env_windows(self):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
ctx.load_default_certs()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pre-build OpenSSL, Tcl and Tk and include the binaries in the build.
38 changes: 37 additions & 1 deletion Modules/_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
#ifdef WITH_THREAD
#include "pythread.h"

/* Redefined below for Windows debug builds after important #includes */
#define _PySSL_FIX_ERRNO

#define PySSL_BEGIN_ALLOW_THREADS_S(save) \
do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0)
#define PySSL_END_ALLOW_THREADS_S(save) \
do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } } while (0)
do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0)
#define PySSL_BEGIN_ALLOW_THREADS { \
PyThreadState *_save = NULL; \
PySSL_BEGIN_ALLOW_THREADS_S(_save);
Expand Down Expand Up @@ -96,6 +98,40 @@ struct py_ssl_library_code {
int code;
};

#if defined(MS_WINDOWS) && defined(Py_DEBUG)
/* Debug builds on Windows rely on getting errno directly from OpenSSL.
* However, because it uses a different CRT, we need to transfer the
* value of errno from OpenSSL into our debug CRT.
*
* Don't be fooled - this is horribly ugly code. The only reasonable
* alternative is to do both debug and release builds of OpenSSL, which
* requires much uglier code to transform their automatically generated
* makefile. This is the lesser of all the evils.
*/

static void _PySSLFixErrno(void) {
HMODULE ucrtbase = GetModuleHandleW(L"ucrtbase.dll");
if (!ucrtbase) {
/* If ucrtbase.dll is not loaded but the SSL DLLs are, we likely
* have a catastrophic failure, but this function is not the
* place to raise it. */
return;
}

typedef int *(__stdcall *errno_func)(void);
errno_func ssl_errno = (errno_func)GetProcAddress(ucrtbase, "_errno");
if (ssl_errno) {
errno = *ssl_errno();
*ssl_errno() = 0;
} else {
errno = ENOTRECOVERABLE;
}
}

#undef _PySSL_FIX_ERRNO
#define _PySSL_FIX_ERRNO _PySSLFixErrno()
#endif

/* Include generated data (error codes) */
#include "_ssl_data.h"

Expand Down
14 changes: 2 additions & 12 deletions PCbuild/_hashlib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,15 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
<Import Project="openssl.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
Expand All @@ -78,14 +76,6 @@
<Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="ssleay.vcxproj">
<Project>{10615b24-73bf-4efa-93aa-236916321317}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="libeay.vcxproj">
<Project>{e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
19 changes: 6 additions & 13 deletions PCbuild/_ssl.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,22 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
<Import Project="openssl.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Modules\_ssl.c" />
<ClCompile Include="$(opensslIncludeDir)\applink.c">
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
Expand All @@ -78,14 +79,6 @@
<Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="libeay.vcxproj">
<Project>{e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="ssleay.vcxproj">
<Project>{10615b24-73bf-4efa-93aa-236916321317}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="_socket.vcxproj">
<Project>{86937f53-c189-40ef-8ce8-8759d8e7d480}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
Expand All @@ -94,4 +87,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
6 changes: 6 additions & 0 deletions PCbuild/_ssl.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@
<ClCompile Include="..\Modules\_ssl.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(opensslIncludeDir)\applink.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
</ItemGroup>
</Project>
16 changes: 10 additions & 6 deletions PCbuild/_tkinter.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,23 @@
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
</ItemGroup>
<ItemGroup>
<_TclTkDLL Include="$(tcltkdir)\bin\$(tclDllName)" />
<_TclTkDLL Include="$(tcltkdir)\bin\$(tkDllName)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="pythoncore.vcxproj">
<Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="tcl.vcxproj">
<Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project>
</ProjectReference>
<ProjectReference Include="tk.vcxproj">
<Project>{7e85eccf-a72c-4da4-9e52-884508e80ba1}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="_CopyTclTkDLL" Inputs="@(_TclTkDLL)" Outputs="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build">
<Copy SourceFiles="@(_TclTkDLL)" DestinationFolder="$(OutDir)" />
</Target>
<Target Name="_CleanTclTkDLL" BeforeTargets="Clean">
<Delete Files="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" />
</Target>
</Project>
2 changes: 0 additions & 2 deletions PCbuild/build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ echo.%~nx0 [flags and arguments] [quoted MSBuild options]
echo.
echo.Build CPython from the command line. Requires the appropriate
echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt).
echo.Also requires Subversion (svn.exe) to be on PATH if the '-e' flag is
echo.given.
echo.
echo.After the flags recognized by this script, up to 9 arguments to be passed
echo.directly to MSBuild may be passed. If the argument contains an '=', the
Expand Down
15 changes: 8 additions & 7 deletions PCbuild/find_msbuild.bat
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,21 @@
@where msbuild > "%TEMP%\msbuild.loc" 2> nul && set /P MSBUILD= < "%TEMP%\msbuild.loc" & del "%TEMP%\msbuild.loc"
@if exist "%MSBUILD%" set MSBUILD="%MSBUILD%" & (set _Py_MSBuild_Source=PATH) & goto :found

@rem VS 2017 sets exactly one install as the "main" install, so we may find MSBuild in there.
@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32 >nul 2>nul
@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32') DO @(
@if "%%i"=="15.0" @if exist "%%k\MSBuild\15.0\Bin\msbuild.exe" @(set MSBUILD="%%k\MSBuild\15.0\Bin\msbuild.exe")
)
@if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio 2017 registry) & goto :found

@rem VS 2015 and earlier register MSBuild separately, so we can find it.
@rem Prefer MSBuild 14.0 over MSBuild 15.0, since the latter may not be able to find a VC14 install.
@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32 >nul 2>nul
@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32') DO @(
@if "%%i"=="MSBuildToolsPath" @if exist "%%k\msbuild.exe" @(set MSBUILD="%%k\msbuild.exe")
)
@if exist %MSBUILD% (set _Py_MSBuild_Source=registry) & goto :found

@rem VS 2017 sets exactly one install as the "main" install, so we may find MSBuild in there.
@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32 >nul 2>nul
@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32') DO @(
@if "%%i"=="15.0" @if exist "%%k\MSBuild\15.0\Bin\msbuild.exe" @(set MSBUILD="%%k\MSBuild\15.0\Bin\msbuild.exe")
)
@if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio 2017 registry) & goto :found


@exit /b 1

Expand Down
57 changes: 57 additions & 0 deletions PCbuild/find_python.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@rem
@rem Searches for python.exe and may download a private copy from nuget.
@rem
@rem This file is supposed to modify the state of the caller (specifically
@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid
@rem changing any other persistent state.
@rem

@rem No arguments provided means do full search
@if '%1' EQU '' goto :begin_search

@rem One argument may be the full path. Use a goto so we don't try to
@rem parse the next if statement - incorrect quoting in the multi-arg
@rem case can cause us to break immediately.
@if '%2' EQU '' goto :one_arg

@rem Entire command line may represent the full path if quoting failed.
@if exist "%*" (set PYTHON="%*") & (set _Py_Python_Source=from environment) & goto :found
@goto :begin_search

:one_arg
@if exist "%~1" (set PYTHON="%~1") & (set _Py_Python_Source=from environment) & goto :found

:begin_search
@set PYTHON=

@set _Py_EXTERNALS_DIR=%EXTERNAL_DIR%
@if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals)

@rem If we have Python in externals, use that one
@if exist "%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found in externals directory) & goto :found

@rem If py.exe finds a recent enough version, use that one
@py -3.6 -V >nul 2>&1 && (set PYTHON=py -3.6) && (set _Py_Python_Source=found with py.exe) && goto :found

@if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%"
@set _Py_NUGET=%NUGET%
@set _Py_NUGET_URL=%NUGET_URL%
@if "%_Py_NUGET%"=="" (set _Py_NUGET=%EXTERNALS_DIR%\nuget.exe)
@if "%_Py_NUGET_URL%"=="" (set _Py_NUGET_URL=https://aka.ms/nugetclidl)
@if NOT exist "%_Py_NUGET%" (
@echo Downloading nuget...
@rem NB: Must use single quotes around NUGET here, NOT double!
@rem Otherwise, a space in the path would break things
@powershell.exe -Command Invoke-WebRequest %_Py_NUGET_URL% -OutFile '%_Py_NUGET%'
)
@echo Installing Python via nuget...
@"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%"
@rem Quote it here; it's not quoted later because "py -3.6" wouldn't work
@if not errorlevel 1 (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found on nuget.org) & goto :found


@exit /b 1

:found
@echo Using %PYTHON% (%_Py_Python_Source%)
@set _Py_Python_Source=
Loading