From fc854f2d89ea9ccc97aec6dcf4e343fed90c2c2a Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 16:47:51 +0200 Subject: [PATCH 01/12] win-support: Generate binary in standard directory to avoid issue on Windows --- CMakeLists.txt | 9 ++ python/CMakeLists.txt | 2 +- python/eigenpy/__init__.py | 28 +++++- python/eigenpy/windows_dll_manager.py | 62 +++++++++++++ unittest/CMakeLists.txt | 123 +++++++++++++------------- 5 files changed, 159 insertions(+), 65 deletions(-) create mode 100644 python/eigenpy/windows_dll_manager.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 47502c232..ec07537df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,14 @@ else() endif() endif() +function(set_standard_output_directory target) + set_target_properties( + ${target} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin + LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib + ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) +endfunction() + # Disable -Werror on Unix for now. set(CXX_DISABLE_WERROR True) set(CMAKE_VERBOSE_MAKEFILE True) @@ -328,6 +336,7 @@ set(${PROJECT_NAME}_SOURCES add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS}) +set_standard_output_directory(${PROJECT_NAME}) target_include_directories( ${PROJECT_NAME} SYSTEM PUBLIC $ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 4a9825a98..4781e42f3 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -67,7 +67,7 @@ if(GENERATE_PYTHON_STUBS) endif(GENERATE_PYTHON_STUBS) # --- INSTALL SCRIPTS -set(PYTHON_FILES __init__.py) +set(PYTHON_FILES __init__.py windows_dll_manager.py) foreach(python ${PYTHON_FILES}) python_build(${PROJECT_NAME} ${python}) diff --git a/python/eigenpy/__init__.py b/python/eigenpy/__init__.py index 503852acd..7fdeef13b 100644 --- a/python/eigenpy/__init__.py +++ b/python/eigenpy/__init__.py @@ -2,5 +2,29 @@ # Copyright (c) 2017-2021 CNRS INRIA # -from .eigenpy_pywrap import * # noqa -from .eigenpy_pywrap import __raw_version__, __version__ # noqa +# On Windows, if eigenpy.dll is not in the same directory than +# the .pyd, it will not be loaded. +# We first try to load eigenpy, then, if it fail and we are on Windows: +# 1. We add all paths inside eigenpy_WINDOWS_DLL_PATH to DllDirectory +# 2. If EIGENPY_WINDOWS_DLL_PATH we add the relative path from the +# package directory to the bin directory to DllDirectory +# This solution is inspired from: +# - https://github.com/PixarAnimationStudios/OpenUSD/pull/1511/files +# - https://stackoverflow.com/questions/65334494/python-c-extension-packaging-dll-along-with-pyd +# More resources on https://github.com/diffpy/pyobjcryst/issues/33 +try: + from .eigenpy_pywrap import * # noqa + from .eigenpy_pywrap import __raw_version__, __version__ # noqa +except ImportError: + import platform + + if platform.system() == "Windows": + from .windows_dll_manager import get_dll_paths, build_directory_manager + + with build_directory_manager() as dll_dir_manager: + for p in get_dll_paths(): + dll_dir_manager.add_dll_directory(p) + from .eigenpy_pywrap import * # noqa + from .eigenpy_pywrap import __raw_version__, __version__ # noqa + else: + raise diff --git a/python/eigenpy/windows_dll_manager.py b/python/eigenpy/windows_dll_manager.py new file mode 100644 index 000000000..5f6482c06 --- /dev/null +++ b/python/eigenpy/windows_dll_manager.py @@ -0,0 +1,62 @@ +import os +import sys +import contextlib + + +def get_dll_paths(): + eigenpy_paths = os.getenv("EIGENPY_WINDOWS_DLL_PATH") + if eigenpy_paths is None: + # From https://peps.python.org/pep-0250/#implementation + # lib/python-version/site-packages/package + RELATIVE_DLL_PATH1 = "..\\..\\..\\..\\bin" + # lib/site-packages/package + RELATIVE_DLL_PATH2 = "..\\..\\..\\bin" + return [ + os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH1), + os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH2), + ] + else: + return eigenpy_paths.split(os.pathsep) + + +class PathManager(contextlib.AbstractContextManager): + """Restore PATH state after importing Python module""" + + def add_dll_directory(self, dll_dir: str): + os.environ["PATH"] += os.pathsep + dll_dir + + def __enter__(self): + self.old_path = os.environ["PATH"] + return self + + def __exit__(self, *exc_details): + os.environ["PATH"] = self.old_path + + +class DllDirectoryManager(contextlib.AbstractContextManager): + """Restore DllDirectory state after importing Python module""" + + def add_dll_directory(self, dll_dir: str): + # add_dll_directory can fail on relative path and non + # existing path. + # Since we don't know all the fail criterion we just ignore + # thrown exception + try: + self.dll_dirs.append(os.add_dll_directory(dll_dir)) + except OSError: + pass + + def __enter__(self): + self.dll_dirs = [] + return self + + def __exit__(self, *exc_details): + for d in self.dll_dirs: + d.close() + + +def build_directory_manager(): + if sys.version_info >= (3, 8): + return DllDirectoryManager() + else: + return PathManager() diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index f5d573773..09b35a027 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -10,13 +10,17 @@ macro(ADD_LIB_UNIT_TEST test) else(BUILD_TESTING) add_library(${test} SHARED EXCLUDE_FROM_ALL "${test}.cpp") endif(BUILD_TESTING) + set_standard_output_directory(${test}) target_link_libraries(${test} PUBLIC ${PROJECT_NAME}) set_target_properties(${test} PROPERTIES PREFIX "") set_target_properties(${test} PROPERTIES SUFFIX ${PYTHON_EXT_SUFFIX}) - add_test(NAME ${test} COMMAND ${PYTHON_EXECUTABLE} -c "import ${test}") + add_test( + NAME ${test} + COMMAND ${PYTHON_EXECUTABLE} -c "import ${test}" + WORKING_DIRECTORY $) add_dependencies(build_tests ${test}) if(NOT BUILD_TESTING) @@ -51,6 +55,20 @@ if(CMAKE_CXX_STANDARD GREATER 14 AND CMAKE_CXX_STANDARD LESS 98) add_lib_unit_test(std_unique_ptr) endif() +function(add_python_lib_unit_test name source) + add_python_unit_test(${name} ${source} "lib" "bin") +endfunction() + +function(add_python_eigenpy_lib_unit_test name source) + add_python_unit_test(${name} ${source} "lib" "bin" "python") + set_tests_properties(${name} PROPERTIES DEPENDS ${PYWRAP}) +endfunction() + +function(add_python_eigenpy_unit_test name source) + add_python_unit_test(${name} ${source} "python") + set_tests_properties(${name} PROPERTIES DEPENDS ${PYWRAP}) +endfunction() + function(config_test test tagname opttype) set(MODNAME ${test}_${tagname}) set(TEST_TYPE ${opttype}) @@ -64,7 +82,7 @@ function(config_test test tagname opttype) add_test(NAME ${PYTHON_TEST_NAME} COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/python/${py_file}") - compute_pythonpath(ENV_VARIABLES "unittest") + compute_pythonpath(ENV_VARIABLES "lib" "bin") set_tests_properties(${PYTHON_TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARIABLES}") endfunction() @@ -81,106 +99,87 @@ endif() add_lib_unit_test(bind_virtual_factory) -add_python_unit_test("py-matrix" "unittest/python/test_matrix.py" "unittest") +add_python_lib_unit_test("py-matrix" "unittest/python/test_matrix.py") -add_python_unit_test("py-tensor" "unittest/python/test_tensor.py" "unittest") -add_python_unit_test("py-geometry" "unittest/python/test_geometry.py" - "unittest") -add_python_unit_test("py-complex" "unittest/python/test_complex.py" "unittest") -add_python_unit_test("py-return-by-ref" "unittest/python/test_return_by_ref.py" - "unittest") -add_python_unit_test("py-eigen-ref" "unittest/python/test_eigen_ref.py" - "unittest") +add_python_lib_unit_test("py-tensor" "unittest/python/test_tensor.py") +add_python_lib_unit_test("py-geometry" "unittest/python/test_geometry.py") +add_python_lib_unit_test("py-complex" "unittest/python/test_complex.py") +add_python_lib_unit_test("py-return-by-ref" + "unittest/python/test_return_by_ref.py") +add_python_lib_unit_test("py-eigen-ref" "unittest/python/test_eigen_ref.py") if(NOT NUMPY_WITH_BROKEN_UFUNC_SUPPORT) - add_python_unit_test("py-user-type" "unittest/python/test_user_type.py" - "unittest") + add_python_lib_unit_test("py-user-type" "unittest/python/test_user_type.py") endif() -add_python_unit_test("py-dimensions" "unittest/python/test_dimensions.py" - "python;unittest") -set_tests_properties("py-dimensions" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-dimensions" + "unittest/python/test_dimensions.py") -add_python_unit_test("py-version" "unittest/python/test_version.py" - "python;unittest") -set_tests_properties("py-version" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-version" "unittest/python/test_version.py") -add_python_unit_test("py-eigen-solver" "unittest/python/test_eigen_solver.py" - "python;unittest") -set_tests_properties("py-eigen-solver" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-eigen-solver" + "unittest/python/test_eigen_solver.py") -add_python_unit_test( +add_python_eigenpy_lib_unit_test( "py-self-adjoint-eigen-solver" - "unittest/python/test_self_adjoint_eigen_solver.py" "python;unittest") -set_tests_properties("py-self-adjoint-eigen-solver" PROPERTIES DEPENDS - ${PYWRAP}) + "unittest/python/test_self_adjoint_eigen_solver.py") -add_python_unit_test("py-LLT" "unittest/python/test_LLT.py" "python;unittest") -set_tests_properties("py-LLT" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-LLT" "unittest/python/test_LLT.py") -add_python_unit_test("py-LDLT" "unittest/python/test_LDLT.py" "python;unittest") -set_tests_properties("py-LDLT" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-LDLT" "unittest/python/test_LDLT.py") if(NOT WIN32) - add_python_unit_test("py-MINRES" "unittest/python/test_MINRES.py" - "python;unittest") - set_tests_properties("py-MINRES" PROPERTIES DEPENDS ${PYWRAP}) + add_python_eigenpy_lib_unit_test("py-MINRES" "unittest/python/test_MINRES.py") endif(NOT WIN32) -add_python_unit_test("py-std-vector" "unittest/python/test_std_vector.py" - "python;unittest") -set_tests_properties("py-std-vector" PROPERTIES DEPENDS ${PYWRAP}) +add_python_eigenpy_lib_unit_test("py-std-vector" + "unittest/python/test_std_vector.py") -add_python_unit_test("py-std-array" "unittest/python/test_std_array.py" - "unittest") +add_python_lib_unit_test("py-std-array" "unittest/python/test_std_array.py") -add_python_unit_test("py-std-pair" "unittest/python/test_std_pair.py" - "unittest") +add_python_lib_unit_test("py-std-pair" "unittest/python/test_std_pair.py") -add_python_unit_test("py-user-struct" "unittest/python/test_user_struct.py" - "unittest") +add_python_lib_unit_test("py-user-struct" "unittest/python/test_user_struct.py") if(CMAKE_CXX_STANDARD GREATER 14 AND CMAKE_CXX_STANDARD LESS 98) - add_python_unit_test("py-std-unique-ptr" - "unittest/python/test_std_unique_ptr.py" "unittest") + add_python_lib_unit_test("py-std-unique-ptr" + "unittest/python/test_std_unique_ptr.py") endif() -add_python_unit_test("py-bind-virtual" "unittest/python/test_bind_virtual.py" - "unittest") +add_python_lib_unit_test("py-bind-virtual" + "unittest/python/test_bind_virtual.py") if(BUILD_TESTING_SCIPY) - add_python_unit_test("py-sparse-matrix" - "unittest/python/test_sparse_matrix.py" "unittest") + add_python_lib_unit_test("py-sparse-matrix" + "unittest/python/test_sparse_matrix.py") - add_python_unit_test( + add_python_eigenpy_unit_test( "py-SimplicialLLT" - "unittest/python/decompositions/sparse/test_SimplicialLLT.py" "python") - add_python_unit_test( + "unittest/python/decompositions/sparse/test_SimplicialLLT.py") + add_python_eigenpy_unit_test( "py-SimplicialLDLT" - "unittest/python/decompositions/sparse/test_SimplicialLDLT.py" "python") + "unittest/python/decompositions/sparse/test_SimplicialLDLT.py") if(BUILD_WITH_CHOLMOD_SUPPORT) - - add_python_unit_test( + add_python_eigenpy_unit_test( "py-CholmodSimplicialLLT" "unittest/python/decompositions/sparse/cholmod/test_CholmodSimplicialLLT.py" - "python") + ) - add_python_unit_test( + add_python_eigenpy_unit_test( "py-CholmodSimplicialLDLT" "unittest/python/decompositions/sparse/cholmod/test_CholmodSimplicialLDLT.py" - "python") + ) - add_python_unit_test( + add_python_eigenpy_unit_test( "py-CholmodSupernodalLLT" "unittest/python/decompositions/sparse/cholmod/test_CholmodSupernodalLLT.py" - "python") - + ) endif(BUILD_WITH_CHOLMOD_SUPPORT) if(BUILD_WITH_ACCELERATE_SUPPORT) - add_python_unit_test( + add_python_eigenpy_unit_test( "py-Accelerate" - "unittest/python/decompositions/sparse/test_Accelerate.py" "python") + "unittest/python/decompositions/sparse/test_Accelerate.py") endif(BUILD_WITH_ACCELERATE_SUPPORT) endif() From 1971f42a58fa2fe809f2a47f2a60b51550b009a1 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 17:03:18 +0200 Subject: [PATCH 02/12] ci: Don't install eigenpy to test it in Windows --- .github/workflows/check-changelog.yml | 3 +- .github/workflows/jrl-cmakemodules.yml | 23 +++++++++++- .github/workflows/linux.yml | 22 ++++++++++- .github/workflows/macos-linux-conda.yml | 26 +++++++++++-- .github/workflows/reloc.yml | 22 ++++++++++- .github/workflows/ros_ci.yml | 22 ++++++++++- .github/workflows/windows-conda.yml | 50 +++++++++++++++++++------ 7 files changed, 144 insertions(+), 24 deletions(-) diff --git a/.github/workflows/check-changelog.yml b/.github/workflows/check-changelog.yml index a4f874c0b..a9bc9801f 100644 --- a/.github/workflows/check-changelog.yml +++ b/.github/workflows/check-changelog.yml @@ -1,4 +1,5 @@ -name: Check-changelog +name: CI - Check-changelog + on: pull_request: types: [assigned, opened, synchronize, reopened, labeled, unlabeled, edited] diff --git a/.github/workflows/jrl-cmakemodules.yml b/.github/workflows/jrl-cmakemodules.yml index 4ae45554c..1cb001a0b 100644 --- a/.github/workflows/jrl-cmakemodules.yml +++ b/.github/workflows/jrl-cmakemodules.yml @@ -1,5 +1,24 @@ -name: JRL-cmakemodules -on: [push,pull_request] +name: CI - JRL-cmakemodules + +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index f48a606c5..4e920e42f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -1,6 +1,24 @@ -name: Check build on linux +name: CI - Linux via APT -on: ["push", "pull_request"] +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index a64e61149..a8f9d4358 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -1,6 +1,24 @@ -name: Conda-CI - -on: [push,pull_request] +name: CI - OSX/Linux via Conda + +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -42,7 +60,7 @@ jobs: with: submodules: recursive - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: .ccache key: ccache-macos-linux-conda-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_options }}-${{ matrix.python-version }}-${{ github.sha }} diff --git a/.github/workflows/reloc.yml b/.github/workflows/reloc.yml index 6f317f7b5..390336aa0 100644 --- a/.github/workflows/reloc.yml +++ b/.github/workflows/reloc.yml @@ -1,6 +1,24 @@ -name: Ensure relocatable +name: CI - Ensure relocatable -on: [push,pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/ros_ci.yml b/.github/workflows/ros_ci.yml index 330f8379a..a2e843bf4 100644 --- a/.github/workflows/ros_ci.yml +++ b/.github/workflows/ros_ci.yml @@ -1,10 +1,28 @@ # This config uses industrial_ci (https://github.com/ros-industrial/industrial_ci.git). # For troubleshooting, see readme (https://github.com/ros-industrial/industrial_ci/blob/master/README.rst) -name: ROS-CI +name: CI - Linux via ROS # This determines when this workflow is run -on: [push, pull_request] # on all pushes and PRs +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index 6315c0f4a..1b5b01d79 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -1,5 +1,24 @@ -name: Build Eigenpy on Windows via Conda -on: [push,pull_request] +name: CI - Windows via Conda + +on: + push: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' + pull_request: + paths-ignore: + - 'doc/**' + - '.gitlab-ci.yml' + - '.gitignore' + - '*.md' + - 'LICENSE' + - 'colcon.pkg' + - '.pre-commit-config.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -17,12 +36,19 @@ jobs: fail-fast: false matrix: os: [windows-latest] + compiler: ["cl", "clang-cl"] steps: - uses: actions/checkout@v4 with: submodules: recursive + - uses: actions/cache@v4 + with: + path: .ccache + key: ccache-windows-conda-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-windows-conda-${{ matrix.os }}- + - uses: conda-incubator/setup-miniconda@v3 with: activate-environment: eigenpy @@ -31,15 +57,14 @@ jobs: python-version: "3.10" auto-activate-base: false - - uses: actions/cache@v3 - with: - path: .ccache - key: ccache-windows-conda-${{ matrix.os }}-${{ github.sha }} - restore-keys: ccache-windows-conda-${{ matrix.os }}- - - name: Build Eigenpy shell: cmd /C CALL {0} + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.compiler }} run: | + call conda list + :: start building call "%programfiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 if errorlevel 1 exit 1 @@ -57,14 +82,17 @@ jobs: .. if errorlevel 1 exit 1 - :: Build and Install - cmake --build . -j3 --config Release --target install + :: Build + cmake --build . -j3 if errorlevel 1 exit 1 :: Testing - ctest --output-on-failure -C Release -V + ctest --output-on-failure if errorlevel 1 exit 1 + :: Install + cmake --install . + :: Test Python import cd .. python -c "import eigenpy" From e28e503fab8b18dfab4e0c830a0ed63132bee878 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:04:41 +0000 Subject: [PATCH 03/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- python/eigenpy/__init__.py | 4 ++-- python/eigenpy/windows_dll_manager.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/eigenpy/__init__.py b/python/eigenpy/__init__.py index 7fdeef13b..f143e13a6 100644 --- a/python/eigenpy/__init__.py +++ b/python/eigenpy/__init__.py @@ -14,12 +14,12 @@ # More resources on https://github.com/diffpy/pyobjcryst/issues/33 try: from .eigenpy_pywrap import * # noqa - from .eigenpy_pywrap import __raw_version__, __version__ # noqa + from .eigenpy_pywrap import __raw_version__, __version__ except ImportError: import platform if platform.system() == "Windows": - from .windows_dll_manager import get_dll_paths, build_directory_manager + from .windows_dll_manager import build_directory_manager, get_dll_paths with build_directory_manager() as dll_dir_manager: for p in get_dll_paths(): diff --git a/python/eigenpy/windows_dll_manager.py b/python/eigenpy/windows_dll_manager.py index 5f6482c06..d1cc0950b 100644 --- a/python/eigenpy/windows_dll_manager.py +++ b/python/eigenpy/windows_dll_manager.py @@ -1,6 +1,6 @@ +import contextlib import os import sys -import contextlib def get_dll_paths(): From 4ea0861afc50a50bca695ac75de381c55c4d69f0 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 17:06:49 +0200 Subject: [PATCH 04/12] changelog: Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12eeb5369..a157ae50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix CMake export ([#446](https://github.com/stack-of-tasks/eigenpy/pull/446) - Fix `int` management on Windows ([#455](https://github.com/stack-of-tasks/eigenpy/pull/455)) - Fix `long long` management on Mac ([#455](https://github.com/stack-of-tasks/eigenpy/pull/455)) +- Allow to run test in the build directory on Windows ([#457](https://github.com/stack-of-tasks/eigenpy/pull/457)) ### Removed - Remove casting when converting from Eigen scalar to Numpy scalar. From c4218ffa4315c4a93e3b73e27cefb97434752056 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 17:21:16 +0200 Subject: [PATCH 05/12] pre-commit: Deactivate ruff outdated-version-block check --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbb6f04a2..6701acff3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,8 @@ repos: args: - --fix - --exit-non-zero-on-fix + - --ignore + - UP036 - id: ruff-format - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 From 3925aedb0a3b1cc4cd922ecd5242c319d32a3193 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 17:31:57 +0200 Subject: [PATCH 06/12] python: Add a hack in windows_dll_manager.py to find eigenpy.dll --- python/eigenpy/windows_dll_manager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/eigenpy/windows_dll_manager.py b/python/eigenpy/windows_dll_manager.py index d1cc0950b..8edb419f2 100644 --- a/python/eigenpy/windows_dll_manager.py +++ b/python/eigenpy/windows_dll_manager.py @@ -11,9 +11,12 @@ def get_dll_paths(): RELATIVE_DLL_PATH1 = "..\\..\\..\\..\\bin" # lib/site-packages/package RELATIVE_DLL_PATH2 = "..\\..\\..\\bin" + # For unit test + RELATIVE_DLL_PATH3 = "..\\..\\bin" return [ os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH1), os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH2), + os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH3), ] else: return eigenpy_paths.split(os.pathsep) From ca3f6cce8ce72b6afb5a12fd7bb94c312c02c8fd Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 17:32:57 +0200 Subject: [PATCH 07/12] ci: Use the right cache key on Windows --- .github/workflows/windows-conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index 1b5b01d79..706c14b48 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -46,8 +46,8 @@ jobs: - uses: actions/cache@v4 with: path: .ccache - key: ccache-windows-conda-${{ matrix.os }}-${{ github.sha }} - restore-keys: ccache-windows-conda-${{ matrix.os }}- + key: ccache-windows-conda-${{ matrix.compiler }}-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-windows-conda-${{ matrix.compiler }}-${{ matrix.os }}- - uses: conda-incubator/setup-miniconda@v3 with: From b4e15e9e98d4063e3cd9c679001947f4825e5f9b Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 20:24:46 +0200 Subject: [PATCH 08/12] ci: Try not to call vcvarsall.bat (should be call by cxx-compiler activation script --- .github/workflows/conda/environment_windows.yml | 1 + .github/workflows/windows-conda.yml | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/conda/environment_windows.yml b/.github/workflows/conda/environment_windows.yml index af5e1c07a..5d8e21c5e 100644 --- a/.github/workflows/conda/environment_windows.yml +++ b/.github/workflows/conda/environment_windows.yml @@ -8,5 +8,6 @@ dependencies: - pkg-config - boost - ccache + - cxx-compiler - ninja - scipy diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index 706c14b48..286c0300f 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -65,10 +65,6 @@ jobs: run: | call conda list - :: start building - call "%programfiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 - if errorlevel 1 exit 1 - mkdir build pushd build cmake ^ From d5b6ccf797d09fa6dd139e2927709ab65bc49129 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 20:45:52 +0200 Subject: [PATCH 09/12] ci: Use same conda environment for Mac/Linux/Windows --- ...ironment_macos_linux.yml => environment_all.yml} | 0 .github/workflows/conda/environment_windows.yml | 13 ------------- .github/workflows/macos-linux-conda.yml | 2 +- .github/workflows/windows-conda.yml | 2 +- 4 files changed, 2 insertions(+), 15 deletions(-) rename .github/workflows/conda/{environment_macos_linux.yml => environment_all.yml} (100%) delete mode 100644 .github/workflows/conda/environment_windows.yml diff --git a/.github/workflows/conda/environment_macos_linux.yml b/.github/workflows/conda/environment_all.yml similarity index 100% rename from .github/workflows/conda/environment_macos_linux.yml rename to .github/workflows/conda/environment_all.yml diff --git a/.github/workflows/conda/environment_windows.yml b/.github/workflows/conda/environment_windows.yml deleted file mode 100644 index 5d8e21c5e..000000000 --- a/.github/workflows/conda/environment_windows.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: eigenpy -channels: - - conda-forge -dependencies: - - eigen - - cmake - - numpy - - pkg-config - - boost - - ccache - - cxx-compiler - - ninja - - scipy diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index a8f9d4358..2e5358e66 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -71,7 +71,7 @@ jobs: with: activate-environment: eigenpy auto-update-conda: true - environment-file: .github/workflows/conda/environment_macos_linux.yml + environment-file: .github/workflows/conda/environment_all.yml python-version: ${{ matrix.python-version }} auto-activate-base: false diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index 286c0300f..150edd51a 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -53,7 +53,7 @@ jobs: with: activate-environment: eigenpy auto-update-conda: true - environment-file: .github/workflows/conda/environment_windows.yml + environment-file: .github/workflows/conda/environment_all.yml python-version: "3.10" auto-activate-base: false From 20a6c0618954a943bffbcdc5ab5620aee09371a3 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 20:48:16 +0200 Subject: [PATCH 10/12] ci: Increase parallel build --- .github/workflows/macos-linux-conda.yml | 3 +-- .github/workflows/windows-conda.yml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index 2e5358e66..0dad572b8 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -97,12 +97,11 @@ jobs: cmake .. \ -G "Ninja" \ -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DPYTHON_EXECUTABLE=$(which python3) \ -DGENERATE_PYTHON_STUBS=ON \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -DCMAKE_CXX_FLAGS=${{ matrix.cxx_options }} - cmake --build . -j2 + cmake --build . -j4 ctest --output-on-failure cmake --install . diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index 150edd51a..a8869f9e6 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -70,7 +70,6 @@ jobs: cmake ^ -G "Ninja" ^ -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^ -DCMAKE_BUILD_TYPE=Release ^ -DGENERATE_PYTHON_STUBS=ON ^ -DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^ @@ -79,7 +78,7 @@ jobs: if errorlevel 1 exit 1 :: Build - cmake --build . -j3 + cmake --build . -j4 if errorlevel 1 exit 1 :: Testing From e1fe83e308711e14d2216e1eb8033d6f92ccb278 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 21:30:54 +0200 Subject: [PATCH 11/12] ci: Use the right environment file for MacOS 14 --- .github/workflows/macos-linux-conda.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index 0dad572b8..00e349818 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -80,7 +80,7 @@ jobs: with: activate-environment: eigenpy auto-update-conda: true - environment-file: .github/workflows/conda/environment_macos_linux.yml + environment-file: .github/workflows/conda/environment_all.yml python-version: ${{ matrix.python-version }} auto-activate-base: false installer-url: https://github.com/conda-forge/miniforge/releases/download/23.11.0-0/Mambaforge-23.11.0-0-MacOSX-arm64.sh From b3dafb3e0220a130242faf48c684a898754206c0 Mon Sep 17 00:00:00 2001 From: Joris Vaillant Date: Tue, 9 Apr 2024 22:10:00 +0200 Subject: [PATCH 12/12] ci: Setup back ccache --- .github/workflows/macos-linux-conda.yml | 1 + .github/workflows/windows-conda.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index 00e349818..9d87ed95f 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -97,6 +97,7 @@ jobs: cmake .. \ -G "Ninja" \ -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DPYTHON_EXECUTABLE=$(which python3) \ -DGENERATE_PYTHON_STUBS=ON \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index a8869f9e6..81a4da77f 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -70,6 +70,7 @@ jobs: cmake ^ -G "Ninja" ^ -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^ -DCMAKE_BUILD_TYPE=Release ^ -DGENERATE_PYTHON_STUBS=ON ^ -DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^