-
Notifications
You must be signed in to change notification settings - Fork 60
/
FindPythonDev.cmake
129 lines (114 loc) · 5.45 KB
/
FindPythonDev.cmake
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
# - 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.11-config
python3.10-config
python3.9-config
python3.8-config
python3.7-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 ()