Skip to content
This repository was archived by the owner on Feb 14, 2023. It is now read-only.

Include vcomp140.dll in windows wheels #43

Merged
merged 12 commits into from
Jan 2, 2020
6 changes: 4 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

environment:
global:
BUILD_COMMIT: 0.22
BUILD_COMMIT: 0.22.1
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
# /E:ON and /V:ON options are not enabled in the batch script interpreter
# See: http://stackoverflow.com/a/13751649/163740
Expand Down Expand Up @@ -102,6 +102,8 @@ install:
# Install the build and runtime dependencies of the project.
- "%CMD_IN_ENV% pip install --timeout=60 numpy==%NP_BUILD_DEP%"
- "%CMD_IN_ENV% pip install --timeout=60 -r ../appveyor/requirements.txt"
- "%CMD_IN_ENV% python setup.py build"
- "%CMD_IN_ENV% python ../appveyor/vendor_vcomp140.py"
- "%CMD_IN_ENV% python setup.py bdist_wheel"
- ps: "ls dist"
- "%CMD_IN_ENV% twine check dist/*"
Expand All @@ -128,7 +130,7 @@ test_script:

artifacts:
# Archive the generated wheel package in the ci.appveyor.com build report.
- path: dist\*
- path: 'scikit-learn\dist\*'

on_success:
# Upload the generated wheel package to Rackspace
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
env:
global:
- REPO_DIR="scikit-learn"
- BUILD_COMMIT=0.22
- BUILD_COMMIT=0.22.1
- PLAT=x86_64
- UNICODE_WIDTH=32
- NP_BUILD_DEP="numpy==1.11.0"
Expand Down
81 changes: 81 additions & 0 deletions appveyor/vendor_vcomp140.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Embed the vcomp dll before generating the scikit-learn Windows wheel.

This script should be run from the root of the scikit-learn source tree,
after running the `python setup.py build` command and before running
the `python setup.py bdist_wheel` command.
"""

import os
import os.path as op
import shutil
from glob import glob
import textwrap

VCOMP140_SRC_PATH = "C:\\Windows\System32\\vcomp140.dll"
TARGET_FOLDER_GLOB_PATTERN = "build/lib.*/sklearn"


def make_distributor_init(sklearn_dirname, dll_filename):
"""Create a _distributor_init.py file for the vcomp dll.

This file is imported first when importing the sklearn package so as
to pre-load the vendored vcomp dll.
"""
distributor_init = op.join(sklearn_dirname, '_distributor_init.py')
with open(distributor_init, 'wt') as f:
f.write(textwrap.dedent("""
'''
Helper to preload the OpenMP dll to prevent "dll not found"
errors.
Once a DLL is preloaded, its namespace is made available to any
subsequent DLL. This file originated in the scikit-learn-wheels
github repo, and is created as part of the scripts that build the
wheel.
'''
import os
import os.path as op
from ctypes import WinDLL


if os.name == 'nt':
# Pre-load the DLL stored in sklearn/.libs by convention.
dll_path = op.join(op.dirname(__file__), '.libs', '{}')
WinDLL(op.abspath(dll_path))

""".format(dll_filename)))
return op.abspath(distributor_init)


def main():
# TODO: use threadpoolctl to dynamically locate the right vcomp dll
# instead? This would require first in-place building scikit-learn
# to make it "importable".
if not op.exists(VCOMP140_SRC_PATH):
raise ValueError("Could not find %r" % VCOMP140_SRC_PATH)

if not op.isdir("build"):
raise RuntimeError("Could not find ./build/ folder. "
"Run 'python setup.py build' first")
target_folders = glob(TARGET_FOLDER_GLOB_PATTERN)
if len(target_folders) == 0:
raise RuntimeError("Could not find folder matching '%s'"
% TARGET_FOLDER_GLOB_PATTERN)
if len(target_folders) > 1:
raise RuntimeError("Found too many target folders: '%s'"
% "', '".join(target_folders))
target_folder = op.abspath(op.join(target_folders[0], ".libs"))

# create the "sklearn/.libs" subfolder
if not op.exists(target_folder):
os.mkdir(target_folder)

print("Copying '%s' to:\n%s" % (VCOMP140_SRC_PATH, target_folder))
shutil.copy2(VCOMP140_SRC_PATH, target_folder)

# Generate the _distributor_init file in the source tree.
print("Generating the '_distributor_init.py' file in:")
print(make_distributor_init("sklearn", op.basename(VCOMP140_SRC_PATH)))


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion scikit-learn
Submodule scikit-learn updated 1084 files