Skip to content

Commit 33fca0e

Browse files
committed
Documenting CMake pitfall
1 parent b013cee commit 33fca0e

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed

.azure-pipelines/unix-build.yml

+8-2
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,22 @@ steps:
3636
3737
- script: |
3838
source activate xtensor-python
39-
cmake . -DPYTHON_EXECUTABLE=`which python`
39+
cmake -Bbuild -DPython_EXECUTABLE=`which python`
40+
cd build
4041
cmake --build .
42+
cp ../example.py .
4143
python example.py
44+
cd ..
4245
displayName: Example - readme 1
4346
workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1
4447
4548
- script: |
4649
source activate xtensor-python
47-
cmake . -DPYTHON_EXECUTABLE=`which python`
50+
cmake -Bbuild -DPython_EXECUTABLE=`which python`
51+
cd build
4852
cmake --build .
53+
cp ../example.py .
4954
python example.py
55+
cd ..
5056
displayName: Example - SFINAE
5157
workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/sfinae

docs/source/examples.rst

+51-4
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,57 @@ Consider the following C++ code:
1414
:language: cpp
1515

1616
There are several options to build the module,
17-
whereby we will CMake here with the following ``CMakeLists.txt``:
17+
whereby we will use *CMake* here with the following ``CMakeLists.txt``:
1818

1919
:download:`CMakeLists.txt <examples/readme_example_1/CMakeLists.txt>`
2020

2121
.. literalinclude:: examples/readme_example_1/CMakeLists.txt
2222
:language: cmake
2323

24+
.. tip::
25+
26+
There is a potential pitfall here, centered around the fact that *CMake*
27+
has a 'new' *FindPython* and a 'classic' *FindPythonLibs*.
28+
We here use *FindPython* because of its ability to find the NumPy headers,
29+
that we need for *xtensor-python*.
30+
31+
This has the consequence that when we want to force *CMake*
32+
to use a specific *Python* executable, we have to use something like
33+
34+
.. code-block:: none
35+
36+
cmake -Bbuild -DPython_EXECUTABLE=`which python`
37+
38+
whereby it is crucial that one uses the correct case ``Python_EXECUTABLE``, as:
39+
40+
.. code-block:: none
41+
42+
Python_EXECUTABLE <-> FindPython
43+
PYTHON_EXECUTABLE <-> FindPythonLibs
44+
45+
(remember that *CMake* is **case-sensitive**!).
46+
47+
Now, since we use *FindPython* because of *xtensor-python* we also want *pybind11*
48+
to use *FindPython*
49+
(and not the classic *FindPythonLibs*,
50+
since we want to specify the *Python* executable only once).
51+
To this end we have to make sure to do things in the correct order, which is
52+
53+
.. code-block:: cmake
54+
55+
find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy)
56+
find_package(pybind11 REQUIRED CONFIG)
57+
58+
(i.e. one finds *Python* **before** *pybind11*).
59+
See the `pybind11 documentation <https://pybind11.readthedocs.io/en/latest/cmake/index.html#new-findpython-mode>`_.
60+
61+
In addition, be sure to use a quite recent *CMake* version,
62+
by starting your ``CMakeLists.txt`` for example with
63+
64+
.. code-block:: cmake
65+
66+
cmake_minimum_required(VERSION 3.18..3.20)
67+
2468
Then we can test the module:
2569

2670
:download:`example.py <examples/readme_example_1/example.py>`
@@ -33,7 +77,7 @@ Then we can test the module:
3377
Since we did not install the module,
3478
we should compile and run the example from the same folder.
3579
To install, please consult
36-
`this pybind11 / CMake example <https://github.com/pybind/cmake_example>`_.
80+
`this *pybind11* / *CMake* example <https://github.com/pybind/cmake_example>`_.
3781

3882

3983
Type restriction with SFINAE
@@ -78,13 +122,15 @@ For the Python module we just have to specify the template to be
78122
.. literalinclude:: examples/sfinae/python.cpp
79123
:language: cpp
80124

81-
We will again use CMake to compile, with the following ``CMakeLists.txt``:
125+
We will again use *CMake* to compile, with the following ``CMakeLists.txt``:
82126

83127
:download:`CMakeLists.txt <examples/sfinae/CMakeLists.txt>`
84128

85129
.. literalinclude:: examples/sfinae/CMakeLists.txt
86130
:language: cmake
87131

132+
(see *CMake* tip above).
133+
88134
Then we can test the module:
89135

90136
:download:`example.py <examples/readme_example_1/example.py>`
@@ -97,4 +143,5 @@ Then we can test the module:
97143
Since we did not install the module,
98144
we should compile and run the example from the same folder.
99145
To install, please consult
100-
`this pybind11 / CMake example <https://github.com/pybind/cmake_example>`_.
146+
`this *pybind11* / *CMake* example <https://github.com/pybind/cmake_example>`_.
147+
**Tip**: take care to modify that example with the correct *CMake* case ``Python_EXECUTABLE``.

docs/source/examples/readme_example_1/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
cmake_minimum_required(VERSION 3.1..3.19)
1+
cmake_minimum_required(VERSION 3.18..3.20)
22

33
project(mymodule)
44

5-
find_package(pybind11 CONFIG REQUIRED)
5+
find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy)
6+
find_package(pybind11 REQUIRED CONFIG)
67
find_package(xtensor REQUIRED)
78
find_package(xtensor-python REQUIRED)
8-
find_package(Python REQUIRED COMPONENTS NumPy)
99

1010
pybind11_add_module(mymodule main.cpp)
1111
target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy)

docs/source/examples/sfinae/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
cmake_minimum_required(VERSION 3.1..3.19)
1+
cmake_minimum_required(VERSION 3.18..3.20)
22

33
project(mymodule)
44

5-
find_package(pybind11 CONFIG REQUIRED)
5+
find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy)
6+
find_package(pybind11 REQUIRED CONFIG)
67
find_package(xtensor REQUIRED)
78
find_package(xtensor-python REQUIRED)
8-
find_package(Python REQUIRED COMPONENTS NumPy)
99

1010
pybind11_add_module(mymodule python.cpp)
1111
target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy)

0 commit comments

Comments
 (0)