File: Makefile.common.header

package info (click to toggle)
python-numpysane 0.31-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 508 kB
  • sloc: python: 4,835; ansic: 610; makefile: 60
file content (136 lines) | stat: -rw-r--r-- 5,786 bytes parent folder | download
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
# -*- Makefile -*-

# This is a part of the mrbuild project: https://github.com/dkogan/mrbuild
#
# Released under an MIT-style license. Modify and distribute as you like:
#
# Copyright 2016-2019 California Institute of Technology
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# This stuff defines variables (PY_EXT_SUFFIX) that could be used by the user
# Makefile at parsing time. So this must be included BEFORE the rest of the user
# Makefile

PYTHON_VERSION_FOR_EXTENSIONS ?= 3 # 2 or 3
# Flags for python extension modules. See
# http://notes.secretsauce.net/notes/2017/11/14_python-extension-modules-without-setuptools-or-distutils.html
#
# I build the python extension module without any setuptools or anything.
# Instead I ask python about the build flags it likes, and build the DSO
# normally using those flags.
#
# There's some sillyness in Make I need to work around. First, I produce a
# python script to query the various build flags, but replacing all whitespace
# with __whitespace__. The string I get when running this script will then have
# a number of whitespace-separated tokens, each setting ONE variable
#
# I set up a number of variables:
#
#   These come from Python queries. I ask Python about XXX and store the result
#   into PY_XXX
#
#     PY_CC
#     PY_CFLAGS
#     PY_CCSHARED
#     PY_INCLUDEPY
#     PY_BLDSHARED
#     PY_LDFLAGS
#     PY_EXT_SUFFIX
#     PY_MULTIARCH
#
#  These process the above into a single set of CFLAGS:
#
#    PY_MRBUILD_CFLAGS
#
#  These process the above into a single set of LDFLAGS:
#
#    PY_MRBUILD_LDFLAGS
#
#  These process the above into a DSO-building linker command
#
#    PY_MRBUILD_LINKER
#
# When the user Makefile evaluates ANY of these variables I query python, and
# memoize the results. So the python is invoked at MOST one time. Any Makefiles
# that don't touch the PY_... variables will not end up invoking the python
# thing at all
#
# Variables to ask Python about
_PYVARS_LIST := CC CFLAGS CCSHARED INCLUDEPY BLDSHARED BLDLIBRARY LDFLAGS EXT_SUFFIX MULTIARCH

# Python script to query those variables
define _PYVARS_SCRIPT
from __future__ import print_function
import sysconfig
import re
conf = sysconfig.get_config_vars()
for v in ($(foreach v,$(_PYVARS_LIST),"$v",)):
    if v in conf:
        print(re.sub("[\t ]+", "__whitespace__", "_PY_{}:={}".format(v, conf[v])))
endef

# I eval this to actually invoke the Python and to ingest its results. I only
# eval this ONLY when necessary.
define query_python_extension_building_flags
_PYVARS := $$(shell python$(PYTHON_VERSION_FOR_EXTENSIONS) -c '$$(_PYVARS_SCRIPT)')
# I then $(eval) these tokens one at a time, restoring the whitespace
$$(foreach setvarcmd,$$(_PYVARS),$$(eval $$(subst __whitespace__, ,$$(setvarcmd))))
# pull out flags from CC, throw out the compiler itself, since I know better
_FLAGS_FROM_PYCC    := $$(wordlist 2,$$(words $$(_PY_CC)),$$(_PY_CC))
_PY_MRBUILD_CFLAGS  := $$(filter-out -O%,$$(_FLAGS_FROM_PYCC) $$(_PY_CFLAGS) $$(_PY_CCSHARED) -I$$(_PY_INCLUDEPY))
# I add an RPATH to the python extension DSO so that it runs in-tree. Will pull
# it out at install time
_PY_MRBUILD_LDFLAGS := $$(_PY_LDFLAGS) -L$$(abspath .) -Wl,-rpath=$$(abspath .)
_PY_MRBUILD_LINKER  := $$(_PY_BLDSHARED) $$(_PY_BLDLIBRARY)
endef

# List of variables a user Makefile could touch
_PYVARS_API := $(foreach v,$(_PYVARS_LIST),PY_$v) PY_MRBUILD_CFLAGS PY_MRBUILD_LDFLAGS PY_MRBUILD_LINKER

# The first time the user touches these variables, ask Python. Each subsequent
# time, use the previously-returned value. So we query Python at most once. If a
# project isn't using the Python extension modules, we will not query Python at
# all
#
# I handle all the Python API variables identically, except for PY_EXT_SUFFIX.
# If Python gives me a suffix, Iuse it (this is available in python3; it has
# ABI, architecture details). Otherwise, I try the multiarch suffix, or if even
# THAT isn't available, just do .so. I need to handle it specially to make the
# self-referential logic work with the memoization logic
define _PY_DEFINE_API_VAR
$1 = $$(or $$(_$1),$$(eval $$(query_python_extension_building_flags))$$(_$1))
endef
define _PY_DEFINE_API_VAR_EXTSUFFIX
$1 = $$(or $$(_$1),$$(eval $$(query_python_extension_building_flags))$$(or $$(_$1),$$(if $$(PY_MULTIARCH),.$$(PY_MULTIARCH)).so))
endef

$(foreach v,$(filter-out PY_EXT_SUFFIX,$(_PYVARS_API)),$(eval $(call _PY_DEFINE_API_VAR,$v)))
$(eval $(call _PY_DEFINE_API_VAR_EXTSUFFIX,PY_EXT_SUFFIX))



# Useful to pull in a local build of some library. Sets the compiler and linker
# (runtime and build-time) flags. Invoke like this:
#   $(eval $(call add_local_library_path,/home/user/library))
define add_local_library_path
CFLAGS   += -I$1
CXXFLAGS += -I$1
LDFLAGS += -L$1 -Wl,-rpath=$1
endef