diff --git a/.appveyor.yml b/.appveyor.yml index 3a58477c..61af3be4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -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 @@ -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/*" @@ -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 diff --git a/.travis.yml b/.travis.yml index 29d155d0..9fbe9ec5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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" diff --git a/appveyor/vendor_vcomp140.py b/appveyor/vendor_vcomp140.py new file mode 100644 index 00000000..f06bd0d7 --- /dev/null +++ b/appveyor/vendor_vcomp140.py @@ -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() diff --git a/scikit-learn b/scikit-learn index 7389dbac..c8c21ae1 160000 --- a/scikit-learn +++ b/scikit-learn @@ -1 +1 @@ -Subproject commit 7389dbac82d362f296dc2746f10e43ffa1615660 +Subproject commit c8c21ae18a7289d8ae9f837946e1e7f85b0337b8