Skip to content

Commit 1477a95

Browse files
authored
Merge pull request #259 from jcarpent/devel
Add generation of Python stubs
2 parents 4972b13 + a5e7230 commit 1477a95

File tree

8 files changed

+70
-55
lines changed

8 files changed

+70
-55
lines changed

.github/workflows/macos-linux-conda.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ on: [push,pull_request]
44

55
jobs:
66
eigenpy-conda:
7-
name: CI - EigenPy on ${{ matrix.os }} via Conda
7+
name: CI on ${{ matrix.os }} via Conda
88
runs-on: ${{ matrix.os }}
9+
env:
10+
CCACHE_DIR: /github/home/.ccache # Enable ccache
911

1012
strategy:
1113
fail-fast: false
@@ -14,10 +16,8 @@ jobs:
1416

1517
steps:
1618
- uses: actions/checkout@v2
17-
18-
- name: Checkout submodules
19-
run: |
20-
git submodule update --init
19+
with:
20+
submodules: recursive
2121

2222
- uses: conda-incubator/setup-miniconda@v2
2323
with:
@@ -26,22 +26,27 @@ jobs:
2626
environment-file: .github/workflows/conda/environment.yml
2727
python-version: 3.8
2828

29+
- uses: actions/cache@v2
30+
with:
31+
path: ${{ env.CCACHE_DIR }}
32+
key: ccache-${{ matrix.os }}
33+
2934
- name: Install cmake and update conda
3035
shell: bash -l {0}
3136
run: |
3237
conda activate eigenpy
3338
conda install cmake -c main
34-
39+
3540
- name: Build EigenPy
3641
shell: bash -l {0}
3742
run: |
3843
conda activate eigenpy
3944
echo $CONDA_PREFIX
40-
45+
4146
mkdir build
4247
cd build
4348
44-
cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3)
49+
cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3) -DGENERATE_PYTHON_STUBS=ON
4550
make
4651
make build_tests
4752
export CTEST_OUTPUT_ON_FAILURE=1

.github/workflows/windows-conda.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
-G "NMake Makefiles" ^
4040
-DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^
4141
-DCMAKE_BUILD_TYPE=Release ^
42+
-DGENERATE_PYTHON_STUBS=ON ^
4243
-DPYTHON_SITELIB=%CONDA_PREFIX%\Lib\site-packages ^
4344
-DPYTHON_EXECUTABLE=%CONDA_PREFIX%\python.exe ^
4445
..

CMakeLists.txt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ INCLUDE(cmake/python.cmake)
4444
INCLUDE(cmake/ide.cmake)
4545
INCLUDE(cmake/apple.cmake)
4646

47+
OPTION(GENERATE_PYTHON_STUBS "Generate the Python stubs associated to the Python library" OFF)
48+
4749
STRING(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
4850

4951
# If needed, fix CMake policy for APPLE systems
@@ -60,6 +62,16 @@ FIND_NUMPY()
6062

6163
IF(WIN32)
6264
LINK_DIRECTORIES(${PYTHON_LIBRARY_DIRS})
65+
# Set default Windows build paths
66+
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY
67+
${PROJECT_BINARY_DIR}/Bin
68+
CACHE PATH "Single directory for all libraries")
69+
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
70+
${PROJECT_BINARY_DIR}/Bin
71+
CACHE PATH "Single directory for all executables")
72+
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
73+
${PROJECT_BINARY_DIR}/Bin
74+
CACHE PATH "Sing$le directory for all archives")
6375
ENDIF(WIN32)
6476

6577
# ----------------------------------------------------
@@ -150,7 +162,7 @@ SET(${PROJECT_NAME}_SOLVERS_SOURCES
150162
SET(${PROJECT_NAME}_DECOMPOSITIONS_SOURCES
151163
src/decompositions/decompositions.cpp
152164
)
153-
165+
154166
SET(${PROJECT_NAME}_SOURCES
155167
${${PROJECT_NAME}_SOLVERS_SOURCES}
156168
${${PROJECT_NAME}_DECOMPOSITIONS_SOURCES}
@@ -175,11 +187,11 @@ SET(${PROJECT_NAME}_SOURCES
175187
)
176188

177189
ADD_LIBRARY(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS})
178-
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
179-
SYSTEM PUBLIC
180-
${Boost_INCLUDE_DIRS}
190+
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
191+
SYSTEM PUBLIC
192+
${Boost_INCLUDE_DIRS}
181193
${EIGEN3_INCLUDE_DIR}
182-
${PYTHON_INCLUDE_DIRS}
194+
${PYTHON_INCLUDE_DIRS}
183195
${NUMPY_INCLUDE_DIRS}
184196
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
185197
$<INSTALL_INTERFACE:include>)

cmake

python/CMakeLists.txt

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,34 @@
33
#
44

55
# --- LIBRARY --- #
6-
SET(PYWRAP ${PROJECT_NAME}_pywrap)
6+
SET(PYWRAP ${PROJECT_NAME}_pywrap)
77
SET(PYWRAP ${PYWRAP} PARENT_SCOPE)
88

99
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}")
10+
include(${PROJECT_SOURCE_DIR}/cmake/stubs.cmake)
1011

1112
ADD_CUSTOM_TARGET(python)
1213
SET_TARGET_PROPERTIES(python PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD True)
1314

1415
ADD_LIBRARY(${PYWRAP} SHARED main.cpp)
1516
ADD_DEPENDENCIES(python ${PYWRAP})
16-
TARGET_LINK_LIBRARIES(${PYWRAP} PUBLIC ${PROJECT_NAME})
17+
TARGET_LINK_LIBRARIES(${PYWRAP} PUBLIC ${PROJECT_NAME})
1718
# BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS spews conversion warnings from int to long unsigned int.
1819
# Unfortunately, using literals does not work in a macro. As such, this turns them off for the entire wrapper:
1920
IF(NOT WIN32)
2021
TARGET_COMPILE_OPTIONS(${PYWRAP} PRIVATE "-Wno-conversion")
2122
ENDIF()
2223
IF(IS_ABSOLUTE ${PYTHON_SITELIB})
23-
SET(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME})
24+
SET(ABSOLUTE_PYTHON_SITELIB ${PYTHON_SITELIB})
2425
ELSE()
25-
SET(${PYWRAP}_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME})
26+
SET(ABSOLUTE_PYTHON_SITELIB ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB})
2627
ENDIF()
28+
SET(${PYWRAP}_INSTALL_DIR ${ABSOLUTE_PYTHON_SITELIB}/${PROJECT_NAME})
2729

2830
SET_TARGET_PROPERTIES(${PYWRAP}
29-
PROPERTIES
31+
PROPERTIES
3032
PREFIX ""
3133
SUFFIX ${PYTHON_EXT_SUFFIX}
32-
OUTPUT_NAME "${PROJECT_NAME}"
3334
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}"
3435
)
3536

@@ -39,12 +40,20 @@ ENDIF()
3940

4041
INSTALL(TARGETS ${PYWRAP} DESTINATION ${${PYWRAP}_INSTALL_DIR})
4142

42-
# --- INSTALL SCRIPTS
43+
# --- GENERATE STUBS
44+
IF(GENERATE_PYTHON_STUBS)
45+
LOAD_STUBGEN()
46+
47+
GENERATE_STUBS(${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_NAME} ${ABSOLUTE_PYTHON_SITELIB})
48+
ENDIF(GENERATE_PYTHON_STUBS)
49+
50+
# --- INSTALL SCRIPTS
4351
SET(PYTHON_FILES
4452
__init__.py
4553
)
4654

4755
FOREACH(python ${PYTHON_FILES})
56+
PYTHON_BUILD(${PROJECT_NAME} ${python})
4857
INSTALL(FILES
4958
"${CMAKE_CURRENT_SOURCE_DIR}/eigenpy/${python}"
5059
DESTINATION ${${PYWRAP}_INSTALL_DIR})

python/eigenpy/__init__.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
#
2-
# Copyright (c) 2017-2019 CNRS INRIA
2+
# Copyright (c) 2017-2021 CNRS INRIA
33
#
4-
# This file is part of eigenpy
5-
# eigenpy is free software: you can redistribute it
6-
# and/or modify it under the terms of the GNU Lesser General Public
7-
# License as published by the Free Software Foundation, either version
8-
# 3 of the License, or (at your option) any later version.
9-
# Pinocchio is distributed in the hope that it will be
10-
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11-
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12-
# General Lesser Public License for more details. You should have
13-
# received a copy of the GNU Lesser General Public License along with
14-
# eigenpy If not, see
15-
# <http://www.gnu.org/licenses/>.
164

17-
from .eigenpy import *
18-
from .eigenpy import __version__, __raw_version__
5+
from .eigenpy_pywrap import *
6+
from .eigenpy_pywrap import __version__, __raw_version__

python/main.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2014-2019, CNRS
3-
* Copyright 2018-2020, INRIA
3+
* Copyright 2018-2021, INRIA
44
*/
55

66
#include "eigenpy/eigenpy.hpp"
@@ -19,42 +19,42 @@
1919

2020
using namespace eigenpy;
2121

22-
BOOST_PYTHON_MODULE(eigenpy)
22+
BOOST_PYTHON_MODULE(eigenpy_pywrap)
2323
{
2424
namespace bp = boost::python;
2525
enableEigenPy();
26-
26+
2727
bp::scope().attr("__version__") = eigenpy::printVersion();
2828
bp::scope().attr("__raw_version__") = bp::str(EIGENPY_VERSION);
2929
bp::def("checkVersionAtLeast",&eigenpy::checkVersionAtLeast,
3030
bp::args("major_version","minor_version","patch_version"),
3131
"Checks if the current version of EigenPy is at least the version provided by the input arguments.");
32-
32+
3333
exposeAngleAxis();
3434
exposeQuaternion();
3535
exposeGeometryConversion();
36-
36+
3737
exposeComputationInfo();
38-
38+
3939
{
4040
bp::scope solvers = boost::python::class_<SolversScope>("solvers");
4141
exposeSolvers();
4242
exposePreconditioners();
43-
43+
4444
register_symbolic_link_to_registered_type<Eigen::ComputationInfo>();
4545
}
46-
46+
4747
{
4848
using namespace Eigen;
49-
49+
5050
bp::def("is_approx",(bool (*)(const Eigen::MatrixBase<MatrixXd> &, const Eigen::MatrixBase<MatrixXd> &, const double &))&is_approx<MatrixXd,MatrixXd>,
5151
bp::args("A","B","prec"),
5252
"Returns True if A is approximately equal to B, within the precision determined by prec.");
53-
53+
5454
bp::def("is_approx",(bool (*)(const Eigen::MatrixBase<MatrixXd> &, const Eigen::MatrixBase<MatrixXd> &))&is_approx<MatrixXd,MatrixXd>,
5555
bp::args("A","B"),
5656
"Returns True if A is approximately equal to B.");
5757
}
58-
58+
5959
exposeDecompositions();
6060
}

unittest/CMakeLists.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,26 @@ ADD_PYTHON_UNIT_TEST("py-return-by-ref" "unittest/python/test_return_by_ref.py"
4242
ADD_PYTHON_UNIT_TEST("py-eigen-ref" "unittest/python/test_eigen_ref.py" "unittest")
4343
ADD_PYTHON_UNIT_TEST("py-user-type" "unittest/python/test_user_type.py" "unittest")
4444

45-
ADD_PYTHON_UNIT_TEST("py-switch" "unittest/python/test_switch.py" "python/eigenpy;unittest")
45+
ADD_PYTHON_UNIT_TEST("py-switch" "unittest/python/test_switch.py" "python;unittest")
4646
SET_TESTS_PROPERTIES("py-switch" PROPERTIES DEPENDS ${PYWRAP})
4747

48-
ADD_PYTHON_UNIT_TEST("py-dimensions" "unittest/python/test_dimensions.py" "python/eigenpy;unittest")
48+
ADD_PYTHON_UNIT_TEST("py-dimensions" "unittest/python/test_dimensions.py" "python;unittest")
4949
SET_TESTS_PROPERTIES("py-dimensions" PROPERTIES DEPENDS ${PYWRAP})
5050

51-
ADD_PYTHON_UNIT_TEST("py-version" "unittest/python/test_version.py" "python/eigenpy;unittest")
51+
ADD_PYTHON_UNIT_TEST("py-version" "unittest/python/test_version.py" "python;unittest")
5252
SET_TESTS_PROPERTIES("py-version" PROPERTIES DEPENDS ${PYWRAP})
5353

54-
ADD_PYTHON_UNIT_TEST("py-eigen-solver" "unittest/python/test_eigen_solver.py" "python/eigenpy;unittest")
54+
ADD_PYTHON_UNIT_TEST("py-eigen-solver" "unittest/python/test_eigen_solver.py" "python;unittest")
5555
SET_TESTS_PROPERTIES("py-eigen-solver" PROPERTIES DEPENDS ${PYWRAP})
5656

57-
ADD_PYTHON_UNIT_TEST("py-self-adjoint-eigen-solver" "unittest/python/test_self_adjoint_eigen_solver.py" "python/eigenpy;unittest")
57+
ADD_PYTHON_UNIT_TEST("py-self-adjoint-eigen-solver" "unittest/python/test_self_adjoint_eigen_solver.py" "python;unittest")
5858
SET_TESTS_PROPERTIES("py-self-adjoint-eigen-solver" PROPERTIES DEPENDS ${PYWRAP})
5959

60-
ADD_PYTHON_UNIT_TEST("py-LLT" "unittest/python/test_LLT.py" "python/eigenpy;unittest")
60+
ADD_PYTHON_UNIT_TEST("py-LLT" "unittest/python/test_LLT.py" "python;unittest")
6161
SET_TESTS_PROPERTIES("py-LLT" PROPERTIES DEPENDS ${PYWRAP})
6262

63-
ADD_PYTHON_UNIT_TEST("py-LDLT" "unittest/python/test_LDLT.py" "python/eigenpy;unittest")
63+
ADD_PYTHON_UNIT_TEST("py-LDLT" "unittest/python/test_LDLT.py" "python;unittest")
6464
SET_TESTS_PROPERTIES("py-LDLT" PROPERTIES DEPENDS ${PYWRAP})
6565

66-
ADD_PYTHON_UNIT_TEST("py-MINRES" "unittest/python/test_MINRES.py" "python/eigenpy;unittest")
66+
ADD_PYTHON_UNIT_TEST("py-MINRES" "unittest/python/test_MINRES.py" "python;unittest")
6767
SET_TESTS_PROPERTIES("py-MINRES" PROPERTIES DEPENDS ${PYWRAP})

0 commit comments

Comments
 (0)