diff --git a/.github/workflows/test-python-win.yml b/.github/workflows/test-python-win.yml index 212e9b75e1..27855b3963 100644 --- a/.github/workflows/test-python-win.yml +++ b/.github/workflows/test-python-win.yml @@ -18,12 +18,32 @@ jobs: python-version: ${{ matrix.python }} - name: Install build dependencies - run: python -m pip install numpy setuptools wheel pytest - - - name: Test python install + run: python -m pip install numpy setuptools wheel pytest meson ninja delvewheel build + + - name: Build project run: | - python -m pip install . - pytest + meson setup bbdir --prefix=${{ github.workspace }}/local_install + meson compile -C bbdir + + - name: Install project to custom directory + run: meson install -C bbdir + + - name: Build Python package + run: python -m build + + - name: Repair the wheel + shell: pwsh + run: | + $installedPath = "${{ github.workspace }}/local_install" + $wheels = Get-ChildItem -Path dist -Filter *.whl + foreach ($wheel in $wheels) { + delvewheel repair $wheel.FullName --add-path "$installedPath/bin;$installedPath/lib" -w repaired_wheels + } + + - name: Install the repaired wheel + run: | + pip install repaired_wheels/*.whl + pytest - name: Test Python Examples run: | diff --git a/meson.build b/meson.build index 881e1d7011..1b21771e43 100644 --- a/meson.build +++ b/meson.build @@ -68,9 +68,6 @@ if is_mingw endif # --------------------- Dependencies -threads_dep = dependency('threads', required: false) -_deps += threads_dep - # Determine whether it is necessary to link libatomic. This could be the case # e.g. on 32-bit platforms when atomic operations are used on 64-bit types. # The check is copied from SciPy which in turn came from @@ -110,6 +107,11 @@ endif _deps += atomic_dep +threads_dep = null_dep +if not is_windows + threads_dep = dependency('threads', required: false) +endif +_deps += threads_dep # Optional zlib_dep = dependency('zlib', required: get_option('use_zlib')) diff --git a/pyproject.toml b/pyproject.toml index 1ed858d359..1065082583 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["meson-python<0.14.0", "meson>=1.2.0", "pybind11", "ninja"] +requires = ["meson-python>=0.16.0", "meson>=1.2.0", "pybind11", "ninja"] build-backend = "mesonpy" [project] @@ -32,7 +32,7 @@ test = ["pytest", "numpy"] [tool.meson-python.args] setup = ['-Dwith_pybind11=True', - '-Dhighsint64=True', + '-Dhighsint64=False', '-Dwrap_mode=forcefallback', # ^-- collects pybind11, see https://github.com/ERGO-Code/HiGHS/pull/1343#discussion_r1252446966 ] @@ -70,6 +70,11 @@ repair-wheel-command = [ "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}", ] +#[tool.cibuildwheel.windows] +#before-build = "pip install delvewheel" +#repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" + [tool.cibuildwheel.windows] -before-build = "pip install delvewheel" -repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" \ No newline at end of file +# Use delvewheel on windows, and install the project so delvewheel can find it +before-build = "pip install delvewheel meson ninja && meson setup bbdir && meson install -C bbdir" +repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w {dest_dir} {wheel}" diff --git a/scripts/post_install_win.bat b/scripts/post_install_win.bat new file mode 100644 index 0000000000..35ae5c49dd --- /dev/null +++ b/scripts/post_install_win.bat @@ -0,0 +1,10 @@ +pip install delvewheel meson ninja + +meson setup bbdir +meson compile -C bbdir + +REM Repair the wheel using delvewheel +set destDir=%1 +set wheel=%2 + +delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w %destDir% %wheel% diff --git a/src/HConfig.h.meson.in b/src/HConfig.h.meson.in index 7b2fb3318c..eff4bc810c 100644 --- a/src/HConfig.h.meson.in +++ b/src/HConfig.h.meson.in @@ -8,6 +8,7 @@ #mesondefine HIGHS_HAVE_MM_PAUSE #mesondefine HIGHS_HAVE_BUILTIN_CLZ #mesondefine HIGHS_HAVE_BITSCAN_REVERSE +#mesondefine HIGHS_NO_DEFAULT_THREADS #define HIGHS_GITHASH "_HIGHS_GITHASH_" #define HIGHS_VERSION_MAJOR @HIGHS_VERSION_MAJOR@ diff --git a/src/highspy/__init__.py b/src/highspy/__init__.py index 3638f094c2..78005667b7 100644 --- a/src/highspy/__init__.py +++ b/src/highspy/__init__.py @@ -1,6 +1,6 @@ # from __future__ import annotations -from ._core import \ +from highspy._core import \ ObjSense, \ MatrixFormat, \ HessianFormat, \ diff --git a/src/highspy/highs.py b/src/highspy/highs.py index 9abf20ea26..5576abfc91 100644 --- a/src/highspy/highs.py +++ b/src/highspy/highs.py @@ -1,4 +1,4 @@ -from ._core import ( +from highspy._core import ( # enum classes ObjSense, MatrixFormat, diff --git a/src/meson.build b/src/meson.build index 6c566f4ee5..153e32c8a8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,12 +10,22 @@ conf_data.set('HIGHS_VERSION_PATCH', meson.project_version().split('.')[2]) conf_data.set('ZLIB_FOUND', zlib_dep.found()) -# Is the use of the following two lines the cause of the meson build -# failure? + +if is_windows +# There is a bug with threading on windows, see CMakeList.txt:307 +# Also https://github.com/ERGO-Code/HiGHS/issues/1382#issuecomment-1670967735 +# Generally, no point using threading with HiGHs at this point (May 2024) + conf_data.set('HIGHS_NO_DEFAULT_THREADS', + true) +else + conf_data.set('HIGHS_NO_DEFAULT_THREADS', + threads_dep.found()) +endif +# This dependency hasn't been setup.. #conf_data.set('CUPDLP_CPU', # cupdlp_cpu.found()) # 64 bit numbers -if host_machine.cpu_family() == 'x86_64' +if host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'amd64' # Get user's option, if it's not provided, enable highsint64 by default on x86_64 highsint64_opt = get_option('highsint64') conf_data.set('HIGHSINT64', highsint64_opt) @@ -291,6 +301,8 @@ if get_option('default_library') == 'static' symbol_visibility = 'inlineshidden' endif + +if not get_option('with_pybind11') highslib = library('highs', highslib_srcs, dependencies: _deps, @@ -300,6 +312,12 @@ highslib = library('highs', gnu_symbol_visibility: symbol_visibility, pic: true, install: true) + +highs_dep = declare_dependency(link_with: highslib, + dependencies: _deps, + include_directories: _incdirs, + ) +endif # --------------- Interfaces @@ -335,15 +353,27 @@ if get_option('with_csharp') install: true) endif -highs_dep = declare_dependency(link_with: highslib, - dependencies: _deps, - include_directories: _incdirs, - ) if get_option('with_pybind11') - _deps += highs_dep py = import('python').find_installation(pure: false) + highslib = library('highs', + highslib_srcs, + dependencies: _deps, + cpp_args: _args, + c_args: _args, + include_directories: _incdirs, + gnu_symbol_visibility: symbol_visibility, + pic: true, + install: true, + install_dir: py.get_install_dir() / 'highspy') + +highs_dep = declare_dependency(link_with: highslib, + dependencies: _deps, + include_directories: _incdirs, + ) + _deps += highs_dep + pyb11_dep = [ # py_dep is auto-added for Python >= 3.9, so it can be dropped here when # that is the minimum supported Python version @@ -361,10 +391,9 @@ if get_option('with_pybind11') py.extension_module( '_core', - sources : highspy_cpp, + sources : highspy_cpp + highs_conf_file, dependencies: _deps, cpp_args: _args, - link_with: highslib, install: true, subdir: 'highspy', include_directories: _incdirs, @@ -372,7 +401,7 @@ if get_option('with_pybind11') py.extension_module( '_highs_options', - sources : highsoptions_cpp, + sources : highsoptions_cpp + highs_conf_file, dependencies: _deps, cpp_args: _args, install: true, @@ -388,4 +417,9 @@ if get_option('with_pybind11') subdir: 'highspy' ) +if is_windows + rootdir = meson.source_root() + meson.add_install_script(f'@rootdir@' / 'scripts' / 'post_install_win.bat', '{dest_dir}', '{wheel}') +endif + endif