Skip to content

Commit

Permalink
[misc] Provide CMmake configuration file in wheels. (#324)
Browse files Browse the repository at this point in the history
* [misc] Fix wheel deploy. Add project URLs to pypi project page.
* [misc] Refactor legacy CMake Python finding to be consistent with CMake>=3.12.
* [misc] Bundle cmake configuration file in wheel.
* [misc] Cleanup pinocchio include and move them in cpp if possible.
* [misc] Provide pip-install-based build of C++ executable.
* [misc] Remove legacy compilation mode since no longer necessary.

Co-authored-by: Alexis Duburcq <alexis.duburcq@wandercraft.eu>
  • Loading branch information
duburcqa and Alexis Duburcq authored Apr 19, 2021
1 parent ab67a29 commit 499f842
Show file tree
Hide file tree
Showing 44 changed files with 730 additions and 247 deletions.
17 changes: 16 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,26 @@ jobs:
-DBoost_NO_SYSTEM_PATHS=TRUE -DBoost_NO_BOOST_CMAKE=TRUE \
-DBoost_USE_STATIC_LIBS=ON -DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}" \
-DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_PYTHON_INTERFACE=ON \
-DCMAKE_CXX_FLAGS="-fPIC" -DCMAKE_BUILD_TYPE="$BUILD_TYPE"
-DCMAKE_CXX_FLAGS="-fPIC" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
make install -j2
#####################################################################################

- name: Build extension module
run: |
export LD_LIBRARY_PATH="/opt/openrobots/lib:$InstallDir/lib/:/usr/local/lib"
"$InstallDir/bin/jiminy_double_pendulum"
mkdir -p "$RootDir/examples/pip_extension/build"
cd "$RootDir/examples/pip_extension/build"
cmake "$RootDir/examples/pip_extension" -DCMAKE_INSTALL_PREFIX="$InstallDir" \
-DCMAKE_PREFIX_PATH="$InstallDir" -DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}" \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
make install
"$InstallDir/bin/pip_double_pendulum"
- name: Run unit tests
run: |
export LD_LIBRARY_PATH="/opt/openrobots/lib:$InstallDir/lib/:/usr/local/lib"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/manylinux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ jobs:
password: ${{ secrets.PYPI_DEPLOY }}
packages_dir: build/wheelhouse
- name: Publish on PyPi the wheel of Gym Jiminy (Any platform / Any python3 version)
if: matrix.PYTHON_VERSION == '3.6' && success() && github.repository == 'duburcqa/jiminy' && github.event_name == 'push' && github.ref == 'refs/heads/master'
if: >-
matrix.container == 'manylinux2010_x86_64' && matrix.PYTHON_VERSION == '3.6' && success() &&
github.repository == 'duburcqa/jiminy' && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ jobs:
#####################################################################################

- name: Build extension module
run: |
"$InstallDir/bin/jiminy_double_pendulum"
mkdir -p "$RootDir/examples/pip_extension/build"
cd "$RootDir/examples/pip_extension/build"
cmake "$RootDir/examples/pip_extension" -DCMAKE_INSTALL_PREFIX="$InstallDir" \
-DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
make install
"$InstallDir/bin/pip_double_pendulum"
- name: Run unit tests
run: |
"$RootDir/build/unit/unit"
Expand Down Expand Up @@ -121,8 +133,10 @@ jobs:
cd build
cmake . -DCOMPONENT=docs -P ./cmake_install.cmake
- name: Deploy to GitHub Pages
if: success() && github.repository == 'duburcqa/jiminy' && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: crazy-max/ghaction-github-pages@v1
if: >-
matrix.os == 'ubuntu-18.04' && success() &&
github.repository == 'duburcqa/jiminy' && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: crazy-max/ghaction-github-pages@v2
with:
target_branch: gh-pages
build_dir: docs/html
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,29 @@ jobs:

#####################################################################################

- name: Build extension module
run: |
$ErrorActionPreference = "Stop"
Set-PSDebug -Trace 1
$RootDir = "${env:GITHUB_WORKSPACE}" -replace '\\', '/'
$InstallDir = "$RootDir/install"
& "$InstallDir/bin/jiminy_double_pendulum.exe"
mkdir -p "$RootDir/examples/pip_extension/build"
cd "$RootDir/examples/pip_extension/build"
$JIMINY_LIB_DIR = (python -c "import os, jiminy_py ; print(os.path.dirname(jiminy_py.get_libraries()))")
$env:Path += ";$JIMINY_LIB_DIR"
cmake "$RootDir/examples/pip_extension" -DCMAKE_INSTALL_PREFIX="$InstallDir" `
-DCMAKE_PREFIX_PATH="$InstallDir" -DPYTHON_REQUIRED_VERSION="${{ matrix.python-version }}" `
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
cmake --build . --target INSTALL --config "${env:BUILD_TYPE}"
& "$InstallDir/bin/pip_double_pendulum.exe"
- name: Running unit tests
run: |
$RootDir = "${env:GITHUB_WORKSPACE}" -replace '\\', '/'
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.10)

# Set the build version
set(BUILD_VERSION 1.6.10)
set(BUILD_VERSION 1.6.11)

# Extract major, minor and patch version
string(REPLACE "." ";" _VERSION "${BUILD_VERSION}")
Expand All @@ -13,6 +13,9 @@ list(GET _VERSION 2 BUILD_VERSION_PATCH)
# Add definition of Jiminy version for C++ headers
add_definitions("-DJIMINY_VERSION=\"${BUILD_VERSION}\"")

# Enable C++ language
enable_language(CXX)

# Project and library name
project(jiminy VERSION ${BUILD_VERSION})
set(LIBRARY_NAME ${PROJECT_NAME})
Expand Down
28 changes: 14 additions & 14 deletions build_tools/cmake/FindNumPy.cmake
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
# Find the Python NumPy package
# NUMPY_INCLUDE_DIRS
# NUMPY_FOUND
# NumPy_INCLUDE_DIRS
# NumPy_FOUND
# will be set by this script

cmake_minimum_required(VERSION 3.10)

if(PYTHON_EXECUTABLE)
if(Python_EXECUTABLE)
# Find out the include path
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n"
COMMAND "${Python_EXECUTABLE}" -c
"try: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n"
OUTPUT_VARIABLE __numpy_path)
# And the version
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n"
COMMAND "${Python_EXECUTABLE}" -c
"try: import numpy; print(numpy.__version__, end='')\nexcept:pass\n"
OUTPUT_VARIABLE __numpy_version)
else()
message(FATAL_ERROR "Python executable not found.")
endif()

unset(NUMPY_INCLUDE_DIRS)
unset(NUMPY_INCLUDE_DIRS CACHE)
find_path(NUMPY_INCLUDE_DIRS numpy/arrayobject.h
HINTS "${__numpy_path}" "${PYTHON_INCLUDE_DIRS}" NO_DEFAULT_PATH)
unset(NumPy_INCLUDE_DIRS)
unset(NumPy_INCLUDE_DIRS CACHE)
find_path(NumPy_INCLUDE_DIRS numpy/arrayobject.h
HINTS "${__numpy_path}" "${Python_INCLUDE_DIRS}" NO_DEFAULT_PATH)

if(NUMPY_INCLUDE_DIRS)
set(NUMPY_FOUND 1 CACHE INTERNAL "Python numpy found")
if(NumPy_INCLUDE_DIRS)
set(NumPy_FOUND 1 CACHE INTERNAL "Python numpy found")
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NumPy REQUIRED_VARS NUMPY_INCLUDE_DIRS
find_package_handle_standard_args(NumPy REQUIRED_VARS NumPy_INCLUDE_DIRS
VERSION_VAR __numpy_version)
28 changes: 0 additions & 28 deletions build_tools/cmake/base.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,7 @@ if(Boost_NO_SYSTEM_PATHS AND (NOT DEFINED BOOST_ROOT))
set(BOOST_ROOT "/opt/install/pc/")
endif()

# Determine if the old legacy old for Ubuntu 18 must be used.
# It will not use "find_package" but instead plain old "link_directories"
# and "include_directories" directives.
# Thus it requires the dependencies to be installed from robotpkg apt repository.
# TODO: Remove legacy mode after dropping support of Ubuntu 18 and moving to
# Eigen >= 3.3.7, Boost >= 1.71, and Pinocchio >=2.4.0.
find_package(Boost QUIET)
string(REPLACE "_" "." BOOST_VERSION "${Boost_LIB_VERSION}")
if(BOOST_VERSION VERSION_LESS "1.71.0")
set(LEGACY_MODE ON)
endif()
if(LEGACY_MODE)
if(WIN32)
message(FATAL_ERROR "Boost >= 1.71.0 required.")
else()
message(WARNING "Boost version < 1.71.0 detected. Falling back to Ubuntu 18 legacy mode. "
"Make sure depedencies have been installed via `apt-get`, and building "
"against Pinocchio >= 2.5.2, and Hpp-Fcl >= 1.5.4.")
endif()
endif()

# Add Fallback search paths for headers and libraries
if(LEGACY_MODE)
link_directories("/opt/openrobots/lib/")
link_directories("/opt/install/pc/lib/")
include_directories(SYSTEM "/opt/openrobots/include/")
include_directories(SYSTEM "/opt/install/pc/include/")
include_directories(SYSTEM "/opt/install/pc/include/eigen3/")
endif()
list(APPEND CMAKE_PREFIX_PATH "/opt/openrobots/")

# Due to license considerations, we will only use the MPL2 parts of Eigen.
Expand Down
2 changes: 1 addition & 1 deletion build_tools/cmake/boostPythonDocstring.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function(pythonDocstingSubstitution)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${file_path}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build_tools/docs/python_docstring_substitution.py
COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build_tools/docs/python_docstring_substitution.py
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${file_path}
${CMAKE_CURRENT_BINARY_DIR}/${file_path}
Expand Down
4 changes: 2 additions & 2 deletions build_tools/cmake/buildPythonWheel.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ function(buildPythonWheel)
# COMMAND ${CMAKE_COMMAND} -E copy_directory \"${CMAKE_SOURCE_DIR}/${TARGET_PATH}\" \"${CMAKE_BINARY_DIR}/pypi\"
# )

install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py clean --all
install(CODE "execute_process(COMMAND ${Python_EXECUTABLE} setup.py clean --all
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/pypi/${TARGET_NAME})
execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py sdist bdist_wheel
execute_process(COMMAND ${Python_EXECUTABLE} setup.py sdist bdist_wheel
--dist-dir \"${OUTPUT_DIR}\"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/pypi/${TARGET_NAME})"
COMPONENT pypi
Expand Down
91 changes: 91 additions & 0 deletions build_tools/cmake/jiminyConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Enable link rpath to find shared library dependencies at runtime
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# Get Python executable
if(DEFINED PYTHON_EXECUTABLE)
get_filename_component(_PYTHON_PATH "${PYTHON_EXECUTABLE}" DIRECTORY)
get_filename_component(_PYTHON_NAME "${PYTHON_EXECUTABLE}" NAME)
find_program(Python_EXECUTABLE "${_PYTHON_NAME}" PATHS "${_PYTHON_PATH}" NO_DEFAULT_PATH)
else()
if(CMAKE_VERSION VERSION_LESS "3.12.4")
find_program(Python_EXECUTABLE "python${PYTHON_REQUIRED_VERSION}")
else()
if(PYTHON_REQUIRED_VERSION)
find_package(Python ${PYTHON_REQUIRED_VERSION} EXACT COMPONENTS Interpreter)
else()
find_package(Python COMPONENTS Interpreter)
endif()
endif()
endif()
if(NOT Python_EXECUTABLE)
if (jiminy_FIND_REQUIRED)
message(FATAL_ERROR "Python executable not found, CMake will exit.")
else()
return()
endif()
endif()

# Make sure jiminy Python module is available
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import importlib; print(int(importlib.util.find_spec('jiminy_py') is not None), end='')"
OUTPUT_VARIABLE jiminy_FOUND)
if (NOT jiminy_FOUND)
if (jiminy_FIND_REQUIRED)
message(FATAL_ERROR "`jiminy_py` Python module not found, CMake will exit.")
else()
return()
endif()
endif()

# Find jiminy library and headers.
# Note that jiminy is compiled under C++17 using either old or new CXX11 ABI.
# Make sure very project dependencies are compiled for the same CXX11 ABI
# otherwise segfaults may occur. It should be fine for the standard library,
# but not for precompiled boost libraries such as boost::filesystem.
# https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import jiminy_py; print(jiminy_py.__version__, end='')"
OUTPUT_VARIABLE jiminy_VERSION)
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import jiminy_py; print(jiminy_py.get_include(), end='')"
OUTPUT_VARIABLE jiminy_INCLUDE_DIRS)
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import jiminy_py; print(jiminy_py.get_libraries(), end='')"
OUTPUT_VARIABLE jiminy_LIBRARIES)

# Define compilation options and definitions
set(jiminy_DEFINITIONS EIGENPY_STATIC URDFDOM_STATIC HPP_FCL_STATIC PINOCCHIO_STATIC)
if(WIN32)
set(jiminy_DEFINITIONS ${jiminy_DEFINITIONS} _USE_MATH_DEFINES=1 NOMINMAX)
set(jiminy_OPTIONS /EHsc /bigobj /Zc:__cplusplus /permissive- /wd4996 /wd4554)
else()
execute_process(COMMAND readelf --version-info "${jiminy_LIBRARIES}"
COMMAND grep -c "Name: CXXABI_1.3.9\\\|Name: GLIBCXX_3.4.21"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE CHECK_NEW_CXX11_ABI)
set(jiminy_DEFINITIONS ${jiminy_DEFINITIONS} _GLIBCXX_USE_CXX11_ABI=$<BOOL:${CHECK_NEW_CXX11_ABI}>)
set(jiminy_OPTIONS -fPIC)
endif()

# Define imported target
add_library(jiminy::core SHARED IMPORTED GLOBAL)
set_target_properties(jiminy::core PROPERTIES
IMPORTED_LOCATION "${jiminy_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${jiminy_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS "${jiminy_DEFINITIONS}"
INTERFACE_COMPILE_OPTIONS "${jiminy_OPTIONS}"
INTERFACE_COMPILE_FEATURES cxx_std_17
CXX_STANDARD 17
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)
if(WIN32)
get_filename_component(jiminy_LIBDIR "${jiminy_LIBRARIES}" DIRECTORY)
get_filename_component(jiminy_LIBNAME "${jiminy_LIBRARIES}" NAME_WE)
set_target_properties(jiminy::core PROPERTIES
IMPORTED_IMPLIB "${jiminy_LIBDIR}/${jiminy_LIBNAME}.lib"
)
endif()

# Display import is success
message(STATUS "Found jiminy ('${jiminy_VERSION}'): ${jiminy_INCLUDE_DIRS} (${jiminy_LIBRARIES})")
Loading

0 comments on commit 499f842

Please sign in to comment.