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

Commit 979cc8b

Browse files
authored
Include vcomp140.dll in windows wheels (#43)
1 parent 38adbcc commit 979cc8b

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

.appveyor.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

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

129131
artifacts:
130132
# Archive the generated wheel package in the ci.appveyor.com build report.
131-
- path: dist\*
133+
- path: 'scikit-learn\dist\*'
132134

133135
on_success:
134136
# Upload the generated wheel package to Rackspace

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
env:
22
global:
33
- REPO_DIR="scikit-learn"
4-
- BUILD_COMMIT=0.22
4+
- BUILD_COMMIT=0.22.1
55
- PLAT=x86_64
66
- UNICODE_WIDTH=32
77
- NP_BUILD_DEP="numpy==1.11.0"

appveyor/vendor_vcomp140.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""Embed the vcomp dll before generating the scikit-learn Windows wheel.
2+
3+
This script should be run from the root of the scikit-learn source tree,
4+
after running the `python setup.py build` command and before running
5+
the `python setup.py bdist_wheel` command.
6+
"""
7+
8+
import os
9+
import os.path as op
10+
import shutil
11+
from glob import glob
12+
import textwrap
13+
14+
VCOMP140_SRC_PATH = "C:\\Windows\System32\\vcomp140.dll"
15+
TARGET_FOLDER_GLOB_PATTERN = "build/lib.*/sklearn"
16+
17+
18+
def make_distributor_init(sklearn_dirname, dll_filename):
19+
"""Create a _distributor_init.py file for the vcomp dll.
20+
21+
This file is imported first when importing the sklearn package so as
22+
to pre-load the vendored vcomp dll.
23+
"""
24+
distributor_init = op.join(sklearn_dirname, '_distributor_init.py')
25+
with open(distributor_init, 'wt') as f:
26+
f.write(textwrap.dedent("""
27+
'''
28+
Helper to preload the OpenMP dll to prevent "dll not found"
29+
errors.
30+
Once a DLL is preloaded, its namespace is made available to any
31+
subsequent DLL. This file originated in the scikit-learn-wheels
32+
github repo, and is created as part of the scripts that build the
33+
wheel.
34+
'''
35+
import os
36+
import os.path as op
37+
from ctypes import WinDLL
38+
39+
40+
if os.name == 'nt':
41+
# Pre-load the DLL stored in sklearn/.libs by convention.
42+
dll_path = op.join(op.dirname(__file__), '.libs', '{}')
43+
WinDLL(op.abspath(dll_path))
44+
45+
""".format(dll_filename)))
46+
return op.abspath(distributor_init)
47+
48+
49+
def main():
50+
# TODO: use threadpoolctl to dynamically locate the right vcomp dll
51+
# instead? This would require first in-place building scikit-learn
52+
# to make it "importable".
53+
if not op.exists(VCOMP140_SRC_PATH):
54+
raise ValueError("Could not find %r" % VCOMP140_SRC_PATH)
55+
56+
if not op.isdir("build"):
57+
raise RuntimeError("Could not find ./build/ folder. "
58+
"Run 'python setup.py build' first")
59+
target_folders = glob(TARGET_FOLDER_GLOB_PATTERN)
60+
if len(target_folders) == 0:
61+
raise RuntimeError("Could not find folder matching '%s'"
62+
% TARGET_FOLDER_GLOB_PATTERN)
63+
if len(target_folders) > 1:
64+
raise RuntimeError("Found too many target folders: '%s'"
65+
% "', '".join(target_folders))
66+
target_folder = op.abspath(op.join(target_folders[0], ".libs"))
67+
68+
# create the "sklearn/.libs" subfolder
69+
if not op.exists(target_folder):
70+
os.mkdir(target_folder)
71+
72+
print("Copying '%s' to:\n%s" % (VCOMP140_SRC_PATH, target_folder))
73+
shutil.copy2(VCOMP140_SRC_PATH, target_folder)
74+
75+
# Generate the _distributor_init file in the source tree.
76+
print("Generating the '_distributor_init.py' file in:")
77+
print(make_distributor_init("sklearn", op.basename(VCOMP140_SRC_PATH)))
78+
79+
80+
if __name__ == "__main__":
81+
main()

scikit-learn

Submodule scikit-learn updated 1084 files

0 commit comments

Comments
 (0)