File: FindPythonModule.cmake

package info (click to toggle)
adios2 2.10.2%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 33,764 kB
  • sloc: cpp: 175,964; ansic: 160,510; f90: 14,630; yacc: 12,668; python: 7,275; perl: 7,126; sh: 2,825; lisp: 1,106; xml: 1,049; makefile: 579; lex: 557
file content (149 lines) | stat: -rw-r--r-- 5,349 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#------------------------------------------------------------------------------#
# Distributed under the OSI-approved Apache License, Version 2.0.  See
# accompanying file Copyright.txt for details.
#------------------------------------------------------------------------------#
#
# PythonModule
# -----------
#
# Try to find the path to a python module
#
# This module defines the following variables:
#
#   PythonModule_${module_NAME}_FOUND - System has the module in question
#
# and the following imported targets:
#   Python::${module_NAME}
#
# This is intented to be called by specifying components for the module name
# and any additional header files and libraries that may be needed to interface
# with it.
#
# For example, say you want to search for mpi4py but you also need it's header
# files to use for interfacing with your own python bindings that use MPI.
# You would call:
#
# find_package(PythonModule REQUIRED COMPONENTS mpi4py mpi4py/mpi4py.h)
#
# If found, this will generate an interface target with the appropriate usage
# requirements.
#
function(__get_filename_label fname var)
  get_filename_component(fname_dir "${fname}" DIRECTORY)
  get_filename_component(fname_nam "${fname}" NAME_WE)
  set(fname_label "${fname_dir}_${fname_nam}")
  string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" fname_label "${fname_label}")
  set(${var} ${fname_label} PARENT_SCOPE)
endfunction()

# Parse out the components
set(module_INCLUDES)
set(module_LIBRARIES)
foreach(comp IN LISTS PythonModule_FIND_COMPONENTS)
  if(comp MATCHES "^[a-zA-Z0-9_]*$")
    set(module_NAME ${comp})
  elseif(comp MATCHES "\\.h$")
    list(APPEND module_INCLUDES "${comp}")
  elseif(comp MATCHES "\\${CMAKE_SHARED_LIBRARY_SUFFIX}")
    list(APPEND module_LIBRARIES "${comp}")
  else()
    message(FATAL_ERROR "${comp}: Unknown python module component")
  endif()
endforeach()
if(NOT module_NAME)
  message(FATAL_ERROR "Unspecified Python module name")
endif()

if(NOT PythonModule_${module_NAME}_FOUND)
  set(PythonModule_${module_NAME}_PATH "" CACHE PATH "Python module ${module_NAME}")
  mark_as_advanced(PythonModule_${module_NAME}_PATH)

  # Try to handle the cross compiling case
  if(NOT PythonModule_${module_NAME}_PATH)
    if(CMAKE_CROSS_COMPILING)
      message(ERROR "find_python_module() invoked in cross-compiling mode, please set the following cache variables appropriately:")
      message("   PythonModule_${module_NAME}_PATH (advanced)")
      message("For details see ${CMAKE_BINARY_DIR}/TryRunResults.cmake")
      file(APPEND "${CMAKE_BINARY_DIR}/TryRunResults.cmake" "
set( PythonModule_${module_NAME}_PATH
  \"PLEASE_FILL_OUT\"
  CACHE PATH \"Python module ${module_NAME}\" FORCE)
")
    else()
      if(NOT Python_Interpreter_FOUND)
        include(CMakeFindDependencyMacro)
        find_dependency(Python COMPONENTS Interpreter)
      endif()
      if(Python_Interpreter_FOUND)
        execute_process(
          COMMAND
            ${Python_EXECUTABLE}
              -c "import ${module_NAME}; print(${module_NAME}.__path__[0])"
          RESULT_VARIABLE result
          OUTPUT_VARIABLE output
          ERROR_VARIABLE error
        )
        if(result EQUAL 0)
          string(STRIP "${output}" output)
          set(PythonModule_${module_NAME}_PATH "${output}"
           CACHE PATH "Python module ${module_NAME}" FORCE)
        endif()
      endif()
    endif()
  endif()

  set(required_vars PythonModule_${module_NAME}_PATH)
  set(include_vars)
  set(library_vars)
  if(PythonModule_${module_NAME}_PATH)
    # Locate interface includes
    foreach(inc IN LISTS module_INCLUDES)
      __get_filename_label("${inc}" inc_label)
      set(inc_var PythonModule_${module_NAME}_${inc_label}_INCLUDE_DIR)
      list(APPEND include_vars ${inc_var})
      find_path(${inc_var} ${inc}
        HINTS ${PythonModule_${module_NAME}_PATH}/include
        NO_CMAKE_FIND_ROOT_PATH NO_DEFAULT_PATH
      )
    endforeach()

    # Locate interface libraries
    foreach(lib IN LISTS module_LIBRARY)
      __get_filename_label("${lib}" lib_label)
      set(lib_var PythonModule_${module_NAME}_${lib_label}_LIBRARY)
      list(APPEND library_vars ${lib_var})
      find_file(${lib_var} ${lib}
        HINTS ${PythonModule_${module_NAME}_PATH}
        NO_CMAKE_FIND_ROOT_PATH NO_DEFAULT_PATH
      )
    endforeach()
    list(APPEND required_vars ${include_vars} ${library_vars})
  endif()

  include(FindPackageHandleStandardArgs)
  set(CMAKE_FIND_PACKAGE_NAME PythonModule_${module_NAME})
  foreach(VAR IN ITEMS REQUIRED QUIETLY VERSION COMPONENTS)
    if(DEFINED PythonModule_FIND_${VAR})
      set(PythonModule_${module_NAME}_FIND_${VAR} "${PythonModule_FIND_${VAR}}")
    else()
      unset(PythonModule_${module_NAME}_FIND_${VAR})
    endif()
  endforeach()

  find_package_handle_standard_args(PythonModule_${module_NAME}
    FOUND_VAR PythonModule_${module_NAME}_FOUND
    REQUIRED_VARS ${required_vars}
  )
endif()

if(PythonModule_${module_NAME}_FOUND AND
  NOT TARGET ${module_NAME})
  add_library(${module_NAME} INTERFACE)
  add_library(Python::${module_NAME} ALIAS ${module_NAME})
  foreach(inc_var IN LISTS include_vars)
    target_include_directories(${module_NAME} SYSTEM INTERFACE ${${inc_var}})
  endforeach()
  foreach(lib_var IN LISTS library_vars)
    target_link_libraries(${module_NAME} INTERFACE ${${lib_var}})
  endforeach()
endif()