Spec-Zone.ru › NumPy 2.0

Использование через cmake

По сложности, cmake находится между make и meson. Кривая обучения круче, так как синтаксис CMake не является питоническим и ближе к make с переменными окружения.

Однако, это компенсируется повышенной гибкостью и поддержкой большинства архитектур и компиляторов. Введение в синтаксис выходит за рамки этого документа, но это обширная коллекция ресурсов по CMake отлично подходит.

Примечание

cmake очень популярен для систем смешанных языков, однако поддержка f2py не является особенно естественной или приятной; и более естественный подход заключается в рассмотрении Использование через scikit-build

Прохождение по Фибоначчи (F77)

Возвращаясь к примеру fib из раздела Три способа обертывания - начало работы.

C FILE: FIB1.F
      SUBROUTINE FIB(A,N)
C
C     CALCULATE FIRST N FIBONACCI NUMBERS
C
      INTEGER N
      REAL*8 A(N)
      DO I=1,N
         IF (I.EQ.1) THEN
            A(I) = 0.0D0
         ELSEIF (I.EQ.2) THEN
            A(I) = 1.0D0
         ELSE 
            A(I) = A(I-1) + A(I-2)
         ENDIF
      ENDDO
      END
C END FILE FIB1.F

Нам не нужно явно генерировать выходной файл python -m numpy.f2py fib1.f, который является fib1module.c, что выгодно. С этим мы можем теперь инициализировать файл CMakeLists.txt следующим образом:

cmake_minimum_required(VERSION 3.18) # Needed to avoid requiring embedded Python libs too

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, 3.8 or newer
find_package(Python 3.8 REQUIRED
  COMPONENTS Interpreter Development.Module NumPy)

# Grab the variables from a local Python installation
# F2PY headers
execute_process(
  COMMAND "${Python_EXECUTABLE}"
  -c "import numpy.f2py; print(numpy.f2py.get_include())"
  OUTPUT_VARIABLE F2PY_INCLUDE_DIR
  OUTPUT_STRIP_TRAILING_WHITESPACE
)

# Print out the discovered paths
include(CMakePrintHelpers)
cmake_print_variables(Python_INCLUDE_DIRS)
cmake_print_variables(F2PY_INCLUDE_DIR)
cmake_print_variables(Python_NumPy_INCLUDE_DIRS)

# Common variables
set(f2py_module_name "fibby")
set(fortran_src_file "${CMAKE_SOURCE_DIR}/fib1.f")
set(f2py_module_c "${f2py_module_name}module.c")

# Generate sources
add_custom_target(
  genpyf
  DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}"
)
add_custom_command(
  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}"
  COMMAND ${Python_EXECUTABLE}  -m "numpy.f2py"
                   "${fortran_src_file}"
                   -m "fibby"
                   --lower # Important
  DEPENDS fib1.f # Fortran source
)

# Set up target
Python_add_library(${CMAKE_PROJECT_NAME} MODULE WITH_SOABI
  "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}" # Generated
  "${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
  "${fortran_src_file}" # Fortran source(s)
)

# Depend on sources
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Python::NumPy)
add_dependencies(${CMAKE_PROJECT_NAME} genpyf)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE "${F2PY_INCLUDE_DIR}")

Ключевым элементом файла CMakeLists.txt выше является то, что add_custom_command используется для генерации файлов обёртки C и затем добавляется в качестве зависимости от фактического целевого файла общей библиотеки через директиву add_custom_target, что предотвращает выполнение команды каждый раз. Кроме того, метод получения файла fortranobject.c также может использоваться для получения заголовков numpy в старых версиях cmake.

Затем это работает так же, как и другие модули, хотя соглашения об именах отличаются, и выходная библиотека не снабжается автоматически префиксом cython информации.

ls .
# CMakeLists.txt fib1.f
cmake -S . -B build
cmake --build build
cd build
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.]

Это особенно полезно в тех случаях, где уже существует существующая цепочка инструментов и scikit-build или другие дополнительные python зависимости нежелательны.

© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/f2py/buildtools/cmake.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API