diff --git a/.github/workflows/conda/environment_macos_linux.yml b/.github/workflows/conda/environment_macos_linux.yml new file mode 100644 index 0000000000..a465fe2ad5 --- /dev/null +++ b/.github/workflows/conda/environment_macos_linux.yml @@ -0,0 +1,17 @@ +name: pinocchio +channels: + - conda-forge +dependencies: + - eigen=3.4.0 + - hpp-fcl + - numpy + - boost + - eigenpy + - urdfdom + - python + - cmake + - ccache + - pkg-config + - ninja + - llvm-openmp + - cxx-compiler diff --git a/.github/workflows/conda/conda-env.yml b/.github/workflows/conda/environment_windows.yml similarity index 75% rename from .github/workflows/conda/conda-env.yml rename to .github/workflows/conda/environment_windows.yml index 6d0dc37225..426ee8a438 100644 --- a/.github/workflows/conda/conda-env.yml +++ b/.github/workflows/conda/environment_windows.yml @@ -1,7 +1,6 @@ name: pinocchio channels: - conda-forge - - nodefaults dependencies: - eigen=3.4.0 - hpp-fcl @@ -10,4 +9,7 @@ dependencies: - eigenpy - urdfdom - python - - mamba + - cmake + - ccache + - pkg-config + - ninja diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index 8e09544c32..7c45fc236a 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -4,10 +4,13 @@ on: [push,pull_request] jobs: pinocchio-conda: - name: Pinocchio on ${{ matrix.os }} in ${{ matrix.build_type }} mode with Conda + name: ${{ matrix.os }} - Python ${{ matrix.python-version }} ${{ matrix.build_type }} with Conda runs-on: ${{ matrix.os }} env: - CCACHE_DIR: ${{ matrix.CCACHE_DIR }} + CCACHE_BASEDIR: "${GITHUB_WORKSPACE}" + CCACHE_DIR: "${GITHUB_WORKSPACE}/.ccache" + CCACHE_COMPRESS: true + CCACHE_COMPRESSLEVEL: 6 BUILD_ADVANCED_TESTING: ${{ matrix.BUILD_ADVANCED_TESTING }} strategy: @@ -15,13 +18,12 @@ jobs: matrix: os: ["ubuntu-latest", "macos-latest"] build_type: [Release, Debug] + python-version: ["3.8", "3.12"] include: - os: ubuntu-latest - CCACHE_DIR: /home/runner/.ccache BUILD_ADVANCED_TESTING: OFF - os: macos-latest - CCACHE_DIR: /Users/runner/.ccache BUILD_ADVANCED_TESTING: ON steps: @@ -31,40 +33,61 @@ jobs: - uses: actions/cache@v3 with: - path: ${{ env.CCACHE_DIR }} - key: ccache-conda-${{ matrix.os }}-${{ matrix.build_type }} + path: .ccache + key: ccache-macos-linux-conda-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.python-version }}-${{ github.sha }} + restore-keys: ccache-macos-linux-conda-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.python-version }}- - uses: conda-incubator/setup-miniconda@v3 with: activate-environment: pinocchio auto-update-conda: true - environment-file: .github/workflows/conda/conda-env.yml - python-version: 3.8 + environment-file: .github/workflows/conda/environment_macos_linux.yml + python-version: ${{ matrix.python-version }} + auto-activate-base: false - - name: Install cmake and update conda - shell: bash -l {0} - run: | - conda activate pinocchio - conda install cmake ccache llvm-openmp compilers=1.4.2 -c conda-forge - conda list - name: Build Pinocchio - shell: bash -l {0} + shell: bash -el {0} run: | - conda activate pinocchio + conda list echo $CONDA_PREFIX mkdir build cd build - cmake .. -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_WITH_COLLISION_SUPPORT=ON -DBUILD_ADVANCED_TESTING=${{ env.BUILD_ADVANCED_TESTING }} -DBUILD_WITH_CASADI_SUPPORT=OFF -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_WITH_OPENMP_SUPPORT=ON -DINSTALL_DOCUMENTATION=ON -DOpenMP_ROOT=$CONDA_PREFIX - make - make build_tests - CTEST_OUTPUT_ON_FAILURE=1 make test - make install + cmake .. \ + -G "Ninja" \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DBUILD_WITH_COLLISION_SUPPORT=ON \ + -DBUILD_ADVANCED_TESTING=${{ env.BUILD_ADVANCED_TESTING }} \ + -DBUILD_WITH_CASADI_SUPPORT=OFF \ + -DPYTHON_EXECUTABLE=$(which python3) \ + -DBUILD_WITH_OPENMP_SUPPORT=ON \ + -DINSTALL_DOCUMENTATION=ON \ + -DOpenMP_ROOT=$CONDA_PREFIX + cmake --build . -j2 + ctest --output-on-failure + cmake --install . - name: Uninstall Pinocchio - shell: bash -l {0} + shell: bash -el {0} run: | cd build - make uninstall + cmake --build . --target uninstall + + check: + if: always() + name: check-macos-linux-conda + + needs: + - pinocchio-conda + + runs-on: Ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/ros-ci.yml b/.github/workflows/ros-ci.yml index 6e57d1abf0..e5d9e89b87 100644 --- a/.github/workflows/ros-ci.yml +++ b/.github/workflows/ros-ci.yml @@ -37,7 +37,8 @@ jobs: - uses: actions/cache@v3 with: path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.env.ROS_DISTRO }}-${{ matrix.env.ROS_REPO }} + key: ccache-${{ matrix.env.ROS_DISTRO }}-${{ matrix.env.ROS_REPO }}-${{ github.sha }} + restore-keys: ccache-${{ matrix.env.ROS_DISTRO }}-${{ matrix.env.ROS_REPO }}- # Run industrial_ci - uses: 'ros-industrial/industrial_ci@3ed9846c96ed1e0bb36193e8e250632eaac980d0' env: ${{ matrix.env }} diff --git a/.github/workflows/windows-conda-clang.yml b/.github/workflows/windows-conda-clang.yml deleted file mode 100644 index 028bc8f348..0000000000 --- a/.github/workflows/windows-conda-clang.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: CI - Windows (CLANG) via Conda -on: - pull_request: - push: - -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - name: [windows-latest-clang-cl] - - include: - - name: windows-latest-clang-cl - os: windows-2019 - compiler: clang-cl - - steps: - - uses: actions/checkout@v4 - - name: Checkout submodules - run: | - git submodule update --init - - uses: goanpeca/setup-miniconda@v2 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - with: - activate-environment: pinocchio - environment-file: .github/workflows/conda/conda-env.yml - python-version: 3.7 - - name: Install cmake and update conda - run: | - conda install cmake -c main - conda list - - - name: Build Pinocchio - shell: cmd /C CALL {0} - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - run: | - :: unset extra Boost envs - set Boost_ROOT= - set BOOST_ROOT_1_69_0= - set BOOST_ROOT_1_72_0= - set PATH=%PATH:C:\hostedtoolcache\windows\Boost\1.72.0;=% - - call "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 - - :: Create build directory - mkdir build - pushd build - - :: Configure - cmake ^ - -G "Visual Studio 16 2019" -T "ClangCl" -DCMAKE_GENERATOR_PLATFORM=x64 ^ - -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ - -DCMAKE_BUILD_TYPE=Release ^ - -DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^ - -DPYTHON_EXECUTABLE=%CONDA_PREFIX%\python.exe ^ - -DBUILD_WITH_URDF_SUPPORT=ON ^ - -DBUILD_PYTHON_INTERFACE=ON ^ - -DBUILD_WITH_COLLISION_SUPPORT=ON ^ - -DINSTALL_DOCUMENTATION=ON ^ - .. - - :: Build - cmake --build . --config Release --target install - - :: Testing - set PATH=%PATH%;%CONDA_PREFIX%\Lib\site-packages\pinocchio - ctest --output-on-failure -C Release -V - - :: Test Python import - cd .. - python -c "import pinocchio" diff --git a/.github/workflows/windows-conda-v142.yml b/.github/workflows/windows-conda-v142.yml deleted file mode 100644 index 29e8d3d741..0000000000 --- a/.github/workflows/windows-conda-v142.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: CI - Windows (v142) via Conda -on: - pull_request: - push: - -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - name: [windows-latest] - - include: - - name: windows-latest - os: windows-2019 - - steps: - - uses: actions/checkout@v4 - - name: Checkout submodules - run: | - git submodule update --init - - uses: goanpeca/setup-miniconda@v2 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - with: - activate-environment: pinocchio - environment-file: .github/workflows/conda/conda-env.yml - python-version: 3.7 - - name: Install cmake and update conda - run: | - conda install cmake -c main - conda list - - - name: Display the path - run: echo %cd% - shell: cmd - - - name: Build Pinocchio - shell: cmd /C CALL {0} - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - run: | - :: unset extra Boost envs - set Boost_ROOT= - set BOOST_ROOT_1_69_0= - set BOOST_ROOT_1_72_0= - - call "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 - - :: Create build directory - mkdir build - pushd build - - :: Configure - cmake ^ - -G "Visual Studio 16 2019" -T "v142" -DCMAKE_GENERATOR_PLATFORM=x64 ^ - -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ - -DCMAKE_BUILD_TYPE=Release ^ - -DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^ - -DPYTHON_EXECUTABLE=%CONDA_PREFIX%\python.exe ^ - -DBUILD_WITH_URDF_SUPPORT=ON ^ - -DBUILD_PYTHON_INTERFACE=OFF ^ - -DBUILD_WITH_COLLISION_SUPPORT=ON ^ - -DBUILD_TESTING=ON ^ - -DINSTALL_DOCUMENTATION=ON ^ - .. - - :: Build - cmake --build . --config Release --target install - -# - name: Start SSH session -# uses: luchihoratiu/debug-via-ssh@main -# with: -# NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }} -# SSH_PASS: ${{ secrets.SSH_PASS }} -# - - name: Testing - shell: cmd /C CALL {0} - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - run: | - :: Testing - pushd build - set PATH=%PATH%;%CONDA_PREFIX%\Lib\site-packages\pinocchio - set PATH=%PATH%;%CONDA_PREFIX%\Library\Lib - set PATH=%PATH%;%CONDA_PREFIX%\Library\bin - .\unittest\Release\test-cpp-urdf.exe - .\examples\Release\example-cpp-geometry-models.exe - ctest --output-on-failure -C Release -V --repeat until-pass:1 - -# :: Test Python import -# cd .. -# python -c "import pinocchio" diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml new file mode 100644 index 0000000000..9f08e8fa5e --- /dev/null +++ b/.github/workflows/windows-conda.yml @@ -0,0 +1,99 @@ +name: CI - Windows via Conda +on: + pull_request: + push: + +jobs: + build: + name: ${{ matrix.os }} - ${{ matrix.compiler }} with Conda + runs-on: ${{ matrix.os }} + env: + CCACHE_BASEDIR: "${GITHUB_WORKSPACE}" + CCACHE_DIR: "${GITHUB_WORKSPACE}/.ccache" + CCACHE_COMPRESS: true + CCACHE_COMPRESSLEVEL: 6 + + strategy: + fail-fast: false + matrix: + os: ["windows-2019"] + compiler: ["cl", "clang-cl"] + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: actions/cache@v3 + with: + path: .ccache + 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: + activate-environment: pinocchio + auto-update-conda: true + environment-file: .github/workflows/conda/environment_windows.yml + python-version: "3.10" + auto-activate-base: false + + - name: Build Pinocchio + shell: cmd /C CALL {0} + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.compiler }} + run: | + call conda list + + call "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 + + :: Create build directory + mkdir build + pushd build + + :: Configure (Ninja use CC and CXX to determine the compiler) + cmake ^ + -G "Ninja" ^ + -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^ + -DPYTHON_EXECUTABLE=%CONDA_PREFIX%\python.exe ^ + -DBUILD_WITH_URDF_SUPPORT=ON ^ + -DBUILD_PYTHON_INTERFACE=ON ^ + -DBUILD_WITH_COLLISION_SUPPORT=ON ^ + -DBUILD_TESTING=ON ^ + -DINSTALL_DOCUMENTATION=ON ^ + .. + + :: Build + cmake --build . + if errorlevel 1 exit 1 + + :: Testing + ctest --output-on-failure + if errorlevel 1 exit 1 + + :: Install + cmake --install . + + :: Test Python import + cd .. + python -c "import pinocchio" + if errorlevel 1 exit 1 + + check: + if: always() + name: check-windows-conda + + needs: + - build + + runs-on: Ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f55803364..5ef06eb8d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,6 +285,15 @@ FUNCTION(PREPEND_PATH_FROM_LIST list_name path_name dest_list) SET(${dest_list} ${list_name_} PARENT_SCOPE) ENDFUNCTION(PREPEND_PATH_FROM_LIST) +# Define PINOCCHIO_WINDOWS_DLL_PATH environment variable on Windows +FUNCTION(ADD_WINDOWS_DLL_PATH_TO_TEST TEST_NAME) + IF(WIN32) + GET_TEST_PROPERTY(${TEST_NAME} ENVIRONMENT ENV_VARIABLES) + LIST(APPEND ENV_VARIABLES "PINOCCHIO_WINDOWS_DLL_PATH=$") + SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARIABLES}") + ENDIF() +ENDFUNCTION() + # Enforce the preprocessed version of boost::list and boost::vector # This information is redundant with the content of include/pinocchio/container/boost-container-limits.hpp # but it avoids any compilation issue. diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 05dd837537..72c88be6dd 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -78,6 +78,8 @@ IF(BUILD_PYTHON_INTERFACE) SUFFIX ${PYTHON_EXT_SUFFIX} OUTPUT_NAME "${PYWRAP}" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" + # On Windows, shared library are treat as binary + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}" ) IF(UNIX) @@ -107,6 +109,7 @@ IF(BUILD_PYTHON_INTERFACE) romeo_wrapper.py explog.py shortcuts.py + windows_dll_manager.py ) FOREACH(python ${PYTHON_FILES}) diff --git a/bindings/python/pinocchio/__init__.py b/bindings/python/pinocchio/__init__.py index 1354d404a4..4831c8de4e 100644 --- a/bindings/python/pinocchio/__init__.py +++ b/bindings/python/pinocchio/__init__.py @@ -3,9 +3,32 @@ # import numpy -from .pinocchio_pywrap import * -from .pinocchio_pywrap import __version__, __raw_version__ +# On Windows, if pinocchio.dll is not in the same directory than +# the .pyd, it will not be loaded. +# We first try to load pinocchio, then, if it fail and we are on Windows: +# 1. We add all paths inside PINOCCHIO_WINDOWS_DLL_PATH to DllDirectory +# 2. If PINOCCHIO_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 .pinocchio_pywrap import * + from .pinocchio_pywrap import __version__, __raw_version__ +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 .pinocchio_pywrap import * + from .pinocchio_pywrap import __version__, __raw_version__ + else: + raise from . import utils from .explog import exp, log diff --git a/bindings/python/pinocchio/windows_dll_manager.py b/bindings/python/pinocchio/windows_dll_manager.py new file mode 100644 index 0000000000..e718970814 --- /dev/null +++ b/bindings/python/pinocchio/windows_dll_manager.py @@ -0,0 +1,56 @@ +import os +import sys +import contextlib + + +def get_dll_paths(): + pinocchio_paths = os.getenv('PINOCCHIO_WINDOWS_DLL_PATH') + if pinocchio_paths is None: + # Standard site-packages to bin path + RELATIVE_DLL_PATH = "..\\..\\..\\bin" + return [os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH)] + else: + return pinocchio_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/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2f498e48f3..e8f6141724 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -7,6 +7,13 @@ FUNCTION(ADD_PINOCCHIO_CPP_EXAMPLE EXAMPLE) SET(EXAMPLE_NAME "example-cpp-${EXAMPLE_NAME}") ADD_UNIT_TEST(${EXAMPLE_NAME} "${EXAMPLE}.cpp") TARGET_LINK_LIBRARIES(${EXAMPLE_NAME} PUBLIC ${PROJECT_NAME}) + + # There is no RPATH in Windows, then we must use the PATH to find the DLL + IF(WIN32) + STRING(REPLACE ";" "\\\;" _PATH "$ENV{PATH}") + SET(ENV_VARIABLES "PATH=${_PATH}\\\;${CMAKE_BINARY_DIR}/src\\\;${CMAKE_BINARY_DIR}/bindings/python/pinocchio") + SET_TESTS_PROPERTIES(${EXAMPLE_NAME} PROPERTIES ENVIRONMENT "${ENV_VARIABLES}") + ENDIF() ENDFUNCTION() SET(${PROJECT_NAME}_EXAMPLES @@ -106,7 +113,9 @@ IF(BUILD_PYTHON_INTERFACE) ENDIF(BUILD_WITH_OPENMP_SUPPORT) FOREACH(EXAMPLE ${${PROJECT_NAME}_PYTHON_EXAMPLES}) - ADD_PYTHON_UNIT_TEST("example-py-${EXAMPLE}" "examples/${EXAMPLE}.py" "bindings/python") + SET(EXAMPLE_NAME "example-py-${EXAMPLE}") + ADD_PYTHON_UNIT_TEST("${EXAMPLE_NAME}" "examples/${EXAMPLE}.py" "bindings/python") + ADD_WINDOWS_DLL_PATH_TO_TEST(${EXAMPLE_NAME}) ENDFOREACH(EXAMPLE ${${PROJECT_NAME}_PYTHON_EXAMPLES}) ENDIF(BUILD_PYTHON_INTERFACE) diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 795bb33c84..cdf30713bc 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -22,6 +22,14 @@ MACRO(ADD_PINOCCHIO_UNIT_TEST NAME) SET(TEST_NAME "test-cpp-${NAME}") ADD_UNIT_TEST(${TEST_NAME} ${NAME}.cpp) + + # There is no RPATH in Windows, then we must use the PATH to find the DLL + IF(WIN32) + STRING(REPLACE ";" "\\\;" _PATH "$ENV{PATH}") + SET(ENV_VARIABLES "PATH=${_PATH}\\\;${CMAKE_BINARY_DIR}/src\\\;${CMAKE_BINARY_DIR}/bindings/python/pinocchio") + SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES ENVIRONMENT "${ENV_VARIABLES}") + ENDIF() + SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES LINKER_LANGUAGE CXX) TARGET_INCLUDE_DIRECTORIES(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) @@ -107,17 +115,22 @@ IF(BUILD_WITH_LIBPYTHON) TARGET_LINK_LIBRARIES(test-cpp-python_parser PUBLIC ${PYWRAP}) TARGET_LINK_LIBRARIES(test-cpp-python_parser PUBLIC ${PYTHON_LIBRARIES}) - SET(ENV_VARIABLES "PYTHONPATH=${CMAKE_BINARY_DIR}/bindings/python:$ENV{PYTHONPATH}") + GET_TEST_PROPERTY(test-cpp-python_parser ENVIRONMENT ENV_VARIABLES) IF(WIN32) GET_FILENAME_COMPONENT(PYTHONHOME ${PYTHON_EXECUTABLE} PATH) LIST(APPEND ENV_VARIABLES "PYTHONHOME=${PYTHONHOME}") UNSET(PYTHONHOME) - ENDIF(WIN32) + + STRING(REPLACE ";" "\\\;" _PYTHONPATH "$ENV{PYTHONPATH}") + LIST(APPEND ENV_VARIABLES "PYTHONPATH=${_PYTHONPATH}\\\;${CMAKE_BINARY_DIR}/bindings/python") + ELSE() + LIST(APPEND ENV_VARIABLES "PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_BINARY_DIR}/bindings/python") + ENDIF() IF(APPLE) LIST(APPEND ENV_VARIABLES "LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}") LIST(APPEND ENV_VARIABLES "DYLD_LIBRARY_PATH=$ENV{DYLD_LIBRARY_PATH}") ENDIF(APPLE) - SET_PROPERTY(TEST test-cpp-python_parser PROPERTY ENVIRONMENT ${ENV_VARIABLES}) + SET_TESTS_PROPERTIES(test-cpp-python_parser PROPERTIES ENVIRONMENT "${ENV_VARIABLES}") ADD_SUBDIRECTORY(python) ENDIF(BUILD_WITH_LIBPYTHON) diff --git a/unittest/python/CMakeLists.txt b/unittest/python/CMakeLists.txt index 2fb9fba4cf..5ac0adb7d1 100644 --- a/unittest/python/CMakeLists.txt +++ b/unittest/python/CMakeLists.txt @@ -78,16 +78,20 @@ SET(${PROJECT_NAME}_PYTHON_MEMORYCHECK_TESTS ) FOREACH(TEST ${${PROJECT_NAME}_PYTHON_TESTS}) - ADD_PYTHON_UNIT_TEST("test-py-${TEST}" "unittest/python/${TEST}.py" "bindings/python") + SET(TEST_NAME "test-py-${TEST}") + ADD_PYTHON_UNIT_TEST(${TEST_NAME} "unittest/python/${TEST}.py" "bindings/python") + ADD_WINDOWS_DLL_PATH_TO_TEST(${TEST_NAME}) ENDFOREACH(TEST ${${PROJECT_NAME}_PYTHON_TESTS}) MAKE_DIRECTORY("${CMAKE_CURRENT_BINARY_DIR}/serialization-data") IF(MEMORYCHECK_COMMAND AND MEMORYCHECK_COMMAND MATCHES ".*valgrind$") FOREACH(TEST ${${PROJECT_NAME}_PYTHON_MEMORYCHECK_TESTS}) - ADD_PYTHON_MEMORYCHECK_UNIT_TEST("test-py-memory-${TEST}" + SET(TEST_NAME "test-py-memory-${TEST}") + ADD_PYTHON_MEMORYCHECK_UNIT_TEST(${TEST_NAME} "unittest/python/${TEST}.py" "bindings/python") + ADD_WINDOWS_DLL_PATH_TO_TEST(${TEST_NAME}) ENDFOREACH() ELSE() MESSAGE(STATUS "Valgrind not found, memory checks are disabled")