diff options
author | Rohit Goswami <rog32@hi.is> | 2021-11-01 00:00:16 +0530 |
---|---|---|
committer | Rohit Goswami <rog32@hi.is> | 2021-11-15 03:49:21 +0000 |
commit | ee7989868a40767f717221ad32e6e50920857ac2 (patch) | |
tree | f4bb1855dade4757f06455de4753a16b8605fe56 | |
parent | 4def9d0c89398a026bf814a5f0f06d2ef6a3ea8e (diff) | |
download | numpy-ee7989868a40767f717221ad32e6e50920857ac2.tar.gz |
DOC: Add CMake with F2PY
-rw-r--r-- | doc/source/f2py/buildtools/cmake.rst | 35 | ||||
-rw-r--r-- | doc/source/f2py/buildtools/index.rst | 2 | ||||
-rw-r--r-- | doc/source/f2py/buildtools/meson.rst | 3 | ||||
-rw-r--r-- | doc/source/f2py/buildtools/skbuild.rst | 5 | ||||
-rw-r--r-- | doc/source/f2py/code/CMakeLists.txt | 74 |
5 files changed, 117 insertions, 2 deletions
diff --git a/doc/source/f2py/buildtools/cmake.rst b/doc/source/f2py/buildtools/cmake.rst index 52d8a37b4..68ef800c7 100644 --- a/doc/source/f2py/buildtools/cmake.rst +++ b/doc/source/f2py/buildtools/cmake.rst @@ -8,12 +8,45 @@ In terms of complexity, ``cmake`` falls between ``make`` and ``meson``. The learning curve is steeper since CMake syntax is not pythonic and is closer to ``make`` with environment variables. -However, the tradeoff is enhanced flexibility and support for most architectures +However, the trade-off is enhanced flexibility and support for most architectures and compilers. An introduction to the syntax is out of scope for this document, but the `official CMake Tutorials`_ are a fantastic resource. +.. note:: + + ``cmake`` is very popular for mixed-language systems, however support for + ``f2py`` is not particularly native or pleasant; and a more natural approach + is to consider :ref:`f2py-skbuild` + Fibonacci Walkthrough ======================= +Returning to the ``fib`` example from :ref:`f2py-getting-started` section. + +.. literalinclude:: ./../code/fib1.f + :language: fortran + +We do not need to explicitly generate the ``python -m numpy.f2py fib1.f`` +output, which is ``fib1module.c``, which is beneficial. With this; we can now +initialize a ``CMakeLists.txt`` file as follows: + +.. literalinclude:: ./../code/CMakeLists.txt + :language: cmake + +This then works in the same manner as the other modules, although the naming +conventions are different and the output library is not automatically prefixed +with the ``cython`` information. + +.. code:: bash + ls . + # CMakeLists.txt fib1.f + mkdir build && cd build + cmake .. + make + python -c "import numpy as np; import fibby; a = np.zeros(9); fibby.fib(a); print (a)" + # [ 0. 1. 1. 2. 3. 5. 8. 13. 21.] + +This is particularly useful where an existing toolchain already exists and +``scikit-build`` or other additional ``python`` dependencies are discouraged. .. _official CMake Tutorials: https://cmake.org/cmake/help/latest/guide/tutorial/index.html diff --git a/doc/source/f2py/buildtools/index.rst b/doc/source/f2py/buildtools/index.rst index e39128014..d8baf23e4 100644 --- a/doc/source/f2py/buildtools/index.rst +++ b/doc/source/f2py/buildtools/index.rst @@ -23,3 +23,5 @@ Build Systems distutils meson + cmake + skbuild diff --git a/doc/source/f2py/buildtools/meson.rst b/doc/source/f2py/buildtools/meson.rst index c43c694e2..9f1ac836e 100644 --- a/doc/source/f2py/buildtools/meson.rst +++ b/doc/source/f2py/buildtools/meson.rst @@ -6,7 +6,8 @@ Using via ``meson`` The key advantage gained by leveraging ``meson`` over the techniques described in :ref:`f2py-distutils` is that this feeds into existing systems and larger -projects with ease. +projects with ease. ``meson`` has a rather pythonic syntax which makes it more +comfortable and amenable to extension for ``python`` users. .. note:: diff --git a/doc/source/f2py/buildtools/skbuild.rst b/doc/source/f2py/buildtools/skbuild.rst new file mode 100644 index 000000000..d55a1725b --- /dev/null +++ b/doc/source/f2py/buildtools/skbuild.rst @@ -0,0 +1,5 @@ +.. _f2py-skbuild: + +============================ +Using via ``scikit-build`` +============================ diff --git a/doc/source/f2py/code/CMakeLists.txt b/doc/source/f2py/code/CMakeLists.txt new file mode 100644 index 000000000..90f8fbac1 --- /dev/null +++ b/doc/source/f2py/code/CMakeLists.txt @@ -0,0 +1,74 @@ +### setup project ### +cmake_minimum_required(VERSION 3.17.3) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +project(fibby + VERSION 1.0 + DESCRIPTION "FIB module" + LANGUAGES C Fortran + ) + +# Safety net +if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + message( + FATAL_ERROR + "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n" + ) +endif() + +# Grab Python +find_package(Python3 3.9 REQUIRED + COMPONENTS Interpreter Development NumPy) + +# Grab the variables from a local Python installation +# F2PY headers +execute_process( + COMMAND "${Python3_EXECUTABLE}" + -c "import numpy.f2py; print(numpy.f2py.get_include())" + OUTPUT_VARIABLE F2PY_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Project scope; consider using target_include_directories instead +include_directories( + BEFORE + ${Python3_INCLUDE_DIRS} + ${Python3_NumPy_INCLUDE_DIRS} + ${F2PY_INCLUDE_DIR} + ) + +message(STATUS ${Python3_INCLUDE_DIRS}) +message(STATUS ${F2PY_INCLUDE_DIR}) +message(STATUS ${Python3_NumPy_INCLUDE_DIRS}) + +# Generate sources +add_custom_target( + genpyf + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}module.c" + ) +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}module.c" + COMMAND ${Python3_EXECUTABLE} -m "numpy.f2py" + "${CMAKE_SOURCE_DIR}/fib1.f" + -m "fibby" + --lower # Important + DEPENDS fib1.f # Fortran source + ) + +# Set up target +add_library(${CMAKE_PROJECT_NAME} SHARED + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}module.c" # Generated + "${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy + fib1.f # Fortran source(s) + ) + +# Depend on sources +add_dependencies(${CMAKE_PROJECT_NAME} genpyf) + +set_target_properties( + ${CMAKE_PROJECT_NAME} + PROPERTIES + PREFIX "" + OUTPUT_NAME "${CMAKE_PROJECT_NAME}" + LINKER_LANGUAGE C + ) |