File: FindPythonDev.cmake

package info (click to toggle)
capstats 0.31-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 488 kB
  • sloc: cpp: 498; sh: 165; makefile: 38
file content (139 lines) | stat: -rw-r--r-- 5,789 bytes parent folder | download | duplicates (3)
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
# - Try to find Python include dirs and libraries
#
# Usage of this module as follows:
#
#     find_package(PythonDev)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
#  PYTHON_EXECUTABLE         If this is set to a path to a Python interpreter
#                            then this module attempts to infer the path to
#                            python-config from it
#  PYTHON_CONFIG             Set this variable to the location of python-config
#                            if the module has problems finding the proper
#                            installation path.
#
# Variables defined by this module:
#
#  PYTHONDEV_FOUND           System has Python dev headers/libraries
#  PYTHON_INCLUDE_DIR        The Python include directories.
#  PYTHON_LIBRARIES          The Python libraries and linker flags.

include(FindPackageHandleStandardArgs)

if ( CMAKE_CROSSCOMPILING )
    find_package(PythonLibs)
    if (PYTHON_INCLUDE_PATH AND NOT PYTHON_INCLUDE_DIR)
        set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}")
    endif ()
    find_package_handle_standard_args(PythonDev DEFAULT_MSG
        PYTHON_INCLUDE_DIR
        PYTHON_LIBRARIES
    )

    return()
endif ()

if (PYTHON_EXECUTABLE)
    # Get the real path so that we can reliably find the correct python-config
    # (e.g. some systems may have a "python" symlink, but not a "python-config"
    # symlink).
    get_filename_component(PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}" REALPATH)
    get_filename_component(PYTHON_EXECUTABLE_DIR "${PYTHON_EXECUTABLE}" DIRECTORY)
    get_filename_component(PYTHON_EXECUTABLE_NAME "${PYTHON_EXECUTABLE}" NAME)

    if ( EXISTS ${PYTHON_EXECUTABLE}-config )
        set(PYTHON_CONFIG ${PYTHON_EXECUTABLE}-config CACHE PATH "" FORCE)
    # Avoid assumption that python-config is associated with python3 if
    # python3 co-exists in a directory that also contains python2 stuff
    elseif ( EXISTS ${PYTHON_EXECUTABLE_DIR}/python-config AND
             NOT EXISTS ${PYTHON_EXECUTABLE_DIR}/python2 AND
             NOT EXISTS ${PYTHON_EXECUTABLE_DIR}/python2.7 AND
             NOT EXISTS ${PYTHON_EXECUTABLE_DIR}/python2-config AND
             NOT EXISTS ${PYTHON_EXECUTABLE_DIR}/python2.7-config )
        set(PYTHON_CONFIG ${PYTHON_EXECUTABLE_DIR}/python-config CACHE PATH "" FORCE)
    endif ()
else ()
    find_program(PYTHON_CONFIG NAMES
                 python3-config
                 python3.9-config
                 python3.8-config
                 python3.7-config
                 python3.6-config
                 python3.5-config
                 python-config
                 )
endif ()

# The OpenBSD python packages have python-config's that don't reliably
# report linking flags that will work.
if (PYTHON_CONFIG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
    # Try `--ldflags --embed` first and fallback to `--ldflags` if it fails.
    # Python 3.8+ introduced the `--embed` flag in relation to this:
    # https://docs.python.org/3.8/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build
    # Note that even if this FindPythonDev script could technically apply to
    # either embedded or extension use cases, the `--embed` flag only adds
    # a `-lpython` and it's generally safe to link libpython in both cases.
    # The only downside to doing that against an extension when it's not
    # strictly necessary is losing the ability to mix-and-match debug/release
    # modes between Python and extensions and that's not a feature to typically
    # care about.
    execute_process(COMMAND "${PYTHON_CONFIG}" --ldflags --embed
                    RESULT_VARIABLE _python_config_result
                    OUTPUT_VARIABLE PYTHON_LIBRARIES
                    OUTPUT_STRIP_TRAILING_WHITESPACE
                    ERROR_QUIET)

    if ( NOT ${_python_config_result} EQUAL 0 )
      execute_process(COMMAND "${PYTHON_CONFIG}" --ldflags
                      RESULT_VARIABLE _python_config_result
                      OUTPUT_VARIABLE PYTHON_LIBRARIES
                      OUTPUT_STRIP_TRAILING_WHITESPACE
                      ERROR_QUIET)
    endif ()

    string(STRIP "${PYTHON_LIBRARIES}" PYTHON_LIBRARIES)

    execute_process(COMMAND "${PYTHON_CONFIG}" --includes
                    OUTPUT_VARIABLE PYTHON_INCLUDE_DIR
                    OUTPUT_STRIP_TRAILING_WHITESPACE
                    ERROR_QUIET)

    string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
    string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
    separate_arguments(PYTHON_INCLUDE_DIR)

    find_package_handle_standard_args(PythonDev DEFAULT_MSG
        PYTHON_CONFIG
        PYTHON_INCLUDE_DIR
        PYTHON_LIBRARIES
    )
else ()
    if ( ${CMAKE_VERSION} VERSION_LESS "3.12.0" )
        find_package(PythonLibs)

        if ( PYTHON_INCLUDE_PATH AND NOT PYTHON_INCLUDE_DIR )
            set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}")
        endif ()
    else ()
        # Expect this branch to be used mostly in macOS where the system
        # default Python 3 installation is not easily/consistently detected
        # by CMake.  CMake 3.12+ is required, but it's expected that macOS
        # users are getting a recent version from homebrew/etc anyway.
        find_package(Python3 COMPONENTS Development)

        if ( Python3_INCLUDE_DIRS AND NOT PYTHON_INCLUDE_DIR )
            set(PYTHON_INCLUDE_DIR "${Python3_INCLUDE_DIRS}")
        endif ()

        if ( Python3_LIBRARIES AND NOT PYTHON_LIBRARIES )
            set(PYTHON_LIBRARIES "${Python3_LIBRARIES}")
        endif ()
    endif ()

    find_package_handle_standard_args(PythonDev DEFAULT_MSG
        PYTHON_INCLUDE_DIR
        PYTHON_LIBRARIES
    )
endif ()