aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Witten <mfwitten@gmail.com>2011-04-02 17:46:09 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-04-19 07:18:36 -0400
commitced465c400b23656ef2c4fbfb4add0e5b92e3d97 (patch)
tree58df4aa0275a03260a1773d418610a22fecf4957
parent3643b133f2cb8023e8cedcbef43215a99d7df561 (diff)
perf tools: Makefile: PYTHON{,_CONFIG} to bandage Python 3 incompatibility
Currently, Python 3 is not supported by perf's code; this can cause the build to fail for systems that have Python 3 installed as the default python: python{,-config} The Correct Solution is to write compatibility code so that Python 3 works out-of-the-box. However, users often have an ancillary Python 2 installed: python2{,-config} Therefore, a quick fix is to allow the user to specify those ancillary paths as the python binaries that Makefile should use, thereby avoiding Python 3 altogether; as an added benefit, the Python binaries may be installed in non-standard locations without the need for updating any PATH variable. This commit adds the ability to set PYTHON and/or PYTHON_CONFIG either as environment variables or as make variables on the command line; the paths may be relative, and usually only PYTHON is necessary in order for PYTHON_CONFIG to be defined implicitly. Some rudimentary error checking is performed when the user explicitly specifies a value for any of these variables. In addition, this commit introduces significantly robust makefile infrastructure for working with paths and communicating with the shell; it's currently only used for handling Python, but I hope it will prove useful in refactoring the makefiles. Thanks to: Raghavendra D Prabhu <rprabhu@wnohang.net> for motivating this patch. Acked-by: Raghavendra D Prabhu <rprabhu@wnohang.net> Link: http://lkml.kernel.org/r/e987828e-87ec-4973-95e7-47f10f5d9bab-mfwitten@gmail.com Signed-off-by: Michael Witten <mfwitten@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/Makefile97
-rw-r--r--tools/perf/config/utilities.mak180
-rw-r--r--tools/perf/feature-tests.mak8
3 files changed, 264 insertions, 21 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index aaf4dd3fd80..b5276c7e9be 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -5,6 +5,8 @@ endif
5# The default target of this Makefile is... 5# The default target of this Makefile is...
6all: 6all:
7 7
8include config/utilities.mak
9
8ifneq ($(OUTPUT),) 10ifneq ($(OUTPUT),)
9# check that the output directory actually exists 11# check that the output directory actually exists
10OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) 12OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
@@ -13,6 +15,12 @@ endif
13 15
14# Define V to have a more verbose compile. 16# Define V to have a more verbose compile.
15# 17#
18# Define PYTHON to point to the python binary if the default
19# `python' is not correct; for example: PYTHON=python2
20#
21# Define PYTHON_CONFIG to point to the python-config binary if
22# the default `$(PYTHON)-config' is not correct.
23#
16# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 24# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
17# 25#
18# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. 26# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
@@ -165,7 +173,7 @@ grep-libs = $(filter -l%,$(1))
165strip-libs = $(filter-out -l%,$(1)) 173strip-libs = $(filter-out -l%,$(1))
166 174
167$(OUTPUT)python/perf.so: $(PYRF_OBJS) 175$(OUTPUT)python/perf.so: $(PYRF_OBJS)
168 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' python util/setup.py \ 176 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
169 --quiet build_ext \ 177 --quiet build_ext \
170 --build-lib='$(OUTPUT)python' \ 178 --build-lib='$(OUTPUT)python' \
171 --build-temp='$(OUTPUT)python/temp' 179 --build-temp='$(OUTPUT)python/temp'
@@ -473,24 +481,74 @@ else
473 endif 481 endif
474endif 482endif
475 483
476ifdef NO_LIBPYTHON 484disable-python = $(eval $(disable-python_code))
477 BASIC_CFLAGS += -DNO_LIBPYTHON 485define disable-python_code
486 BASIC_CFLAGS += -DNO_LIBPYTHON
487 $(if $(1),$(warning No $(1) was found))
488 $(warning Python support won't be built)
489endef
490
491override PYTHON := \
492 $(call get-executable-or-default,PYTHON,python)
493
494ifndef PYTHON
495 $(call disable-python,python interpreter)
496 python-clean :=
478else 497else
479 PYTHON_EMBED_LDOPTS = $(shell python-config --ldflags 2>/dev/null) 498
480 PYTHON_EMBED_LDFLAGS = $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 499 PYTHON_WORD := $(call shell-wordify,$(PYTHON))
481 PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) 500
482 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` 501 python-clean := $(PYTHON_WORD) util/setup.py clean \
483 FLAGS_PYTHON_EMBED=$(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 502 --build-lib='$(OUTPUT)python' \
484 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) 503 --build-temp='$(OUTPUT)python/temp'
485 msg := $(warning No Python.h found, install python-dev[el] to have python support in 'perf script' and to build the python bindings) 504
486 BASIC_CFLAGS += -DNO_LIBPYTHON 505 ifdef NO_LIBPYTHON
487 else 506 $(call disable-python)
488 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS) 507 else
489 EXTLIBS += $(PYTHON_EMBED_LIBADD) 508
490 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o 509 override PYTHON_CONFIG := \
491 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o 510 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
492 LANG_BINDINGS += $(OUTPUT)python/perf.so 511
493 endif 512 ifndef PYTHON_CONFIG
513 $(call disable-python,python-config tool)
514 else
515
516 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
517
518 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
519 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
520 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
521 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
522 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
523
524 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y)
525 $(call disable-python,Python.h (for Python 2.x))
526 else
527
528 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y)
529 $(warning Python 3 is not yet supported; please set)
530 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
531 $(warning If you also have Python 2 installed, then)
532 $(warning try something like:)
533 $(warning $(and ,))
534 $(warning $(and ,) make PYTHON=python2)
535 $(warning $(and ,))
536 $(warning Otherwise, disable Python support entirely:)
537 $(warning $(and ,))
538 $(warning $(and ,) make NO_LIBPYTHON=1)
539 $(warning $(and ,))
540 $(error $(and ,))
541 else
542 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
543 EXTLIBS += $(PYTHON_EMBED_LIBADD)
544 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
545 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
546 LANG_BINDINGS += $(OUTPUT)python/perf.so
547 endif
548
549 endif
550 endif
551 endif
494endif 552endif
495 553
496ifdef NO_DEMANGLE 554ifdef NO_DEMANGLE
@@ -831,8 +889,7 @@ clean:
831 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* 889 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
832 $(MAKE) -C Documentation/ clean 890 $(MAKE) -C Documentation/ clean
833 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS 891 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
834 @python util/setup.py clean --build-lib='$(OUTPUT)python' \ 892 $(python-clean)
835 --build-temp='$(OUTPUT)python/temp'
836 893
837.PHONY: all install clean strip 894.PHONY: all install clean strip
838.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 895.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
new file mode 100644
index 00000000000..6d8ff887840
--- /dev/null
+++ b/tools/perf/config/utilities.mak
@@ -0,0 +1,180 @@
1# This allows us to work with the newline character:
2define newline
3
4
5endef
6newline := $(newline)
7
8# nl-escape
9#
10# Usage: escape = $(call nl-escape[,escape])
11#
12# This is used as the common way to specify
13# what should replace a newline when escaping
14# newlines; the default is a bizarre string.
15#
16nl-escape = $(or $(1),m822df3020w6a44id34bt574ctac44eb9f4n)
17
18# escape-nl
19#
20# Usage: escaped-text = $(call escape-nl,text[,escape])
21#
22# GNU make's $(shell ...) function converts to a
23# single space each newline character in the output
24# produced during the expansion; this may not be
25# desirable.
26#
27# The only solution is to change each newline into
28# something that won't be converted, so that the
29# information can be recovered later with
30# $(call unescape-nl...)
31#
32escape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
33
34# unescape-nl
35#
36# Usage: text = $(call unescape-nl,escaped-text[,escape])
37#
38# See escape-nl.
39#
40unescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
41
42# shell-escape-nl
43#
44# Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
45#
46# Use this to escape newlines from within a shell call;
47# the default escape is a bizarre string.
48#
49# NOTE: The escape is used directly as a string constant
50# in an `awk' program that is delimited by shell
51# single-quotes, so be wary of the characters
52# that are chosen.
53#
54define shell-escape-nl
55awk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
56endef
57
58# shell-unescape-nl
59#
60# Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
61#
62# Use this to unescape newlines from within a shell call;
63# the default escape is a bizarre string.
64#
65# NOTE: The escape is used directly as an extended regular
66# expression constant in an `awk' program that is
67# delimited by shell single-quotes, so be wary
68# of the characters that are chosen.
69#
70# (The bash shell has a bug where `{gsub(...),...}' is
71# misinterpreted as a brace expansion; this can be
72# overcome by putting a space between `{' and `gsub').
73#
74define shell-unescape-nl
75awk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
76endef
77
78# escape-for-shell-sq
79#
80# Usage: embeddable-text = $(call escape-for-shell-sq,text)
81#
82# This function produces text that is suitable for
83# embedding in a shell string that is delimited by
84# single-quotes.
85#
86escape-for-shell-sq = $(subst ','\'',$(1))
87
88# shell-sq
89#
90# Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
91#
92shell-sq = '$(escape-for-shell-sq)'
93
94# shell-wordify
95#
96# Usage: wordified-text = $(call shell-wordify,text)
97#
98# For instance:
99#
100# |define text
101# |hello
102# |world
103# |endef
104# |
105# |target:
106# | echo $(call shell-wordify,$(text))
107#
108# At least GNU make gets confused by expanding a newline
109# within the context of a command line of a makefile rule
110# (this is in constrast to a `$(shell ...)' function call,
111# which can handle it just fine).
112#
113# This function avoids the problem by producing a string
114# that works as a shell word, regardless of whether or
115# not it contains a newline.
116#
117# If the text to be wordified contains a newline, then
118# an intrictate shell command substitution is constructed
119# to render the text as a single line; when the shell
120# processes the resulting escaped text, it transforms
121# it into the original unescaped text.
122#
123# If the text does not contain a newline, then this function
124# produces the same results as the `$(shell-sq)' function.
125#
126shell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
127define _sw-esc-nl
128"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
129endef
130
131# is-absolute
132#
133# Usage: bool-value = $(call is-absolute,path)
134#
135is-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y)
136
137# lookup
138#
139# Usage: absolute-executable-path-or-empty = $(call lookup,path)
140#
141# (It's necessary to use `sh -c' because GNU make messes up by
142# trying too hard and getting things wrong).
143#
144lookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
145_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
146
147# is-executable
148#
149# Usage: bool-value = $(call is-executable,path)
150#
151# (It's necessary to use `sh -c' because GNU make messes up by
152# trying too hard and getting things wrong).
153#
154is-executable = $(call _is-executable-helper,$(shell-sq))
155_is-executable-helper = $(shell sh -c $(_is-executable-sh))
156_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
157
158# get-executable
159#
160# Usage: absolute-executable-path-or-empty = $(call get-executable,path)
161#
162# The goal is to get an absolute path for an executable;
163# the `command -v' is defined by POSIX, but it's not
164# necessarily very portable, so it's only used if
165# relative path resolution is requested, as determined
166# by the presence of a leading `/'.
167#
168get-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
169_ge-abspath = $(if $(is-executable),$(1))
170
171# get-supplied-or-default-executable
172#
173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
174#
175define get-executable-or-default
176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
177endef
178_ge_attempt = $(or $(get-executable),$(_gea_warn),$(call _gea_err,$(2)))
179_gea_warn = $(warning The path '$(1)' is not executable.)
180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
diff --git a/tools/perf/feature-tests.mak b/tools/perf/feature-tests.mak
index b041ca67a2c..1b3342001e1 100644
--- a/tools/perf/feature-tests.mak
+++ b/tools/perf/feature-tests.mak
@@ -79,9 +79,15 @@ endef
79endif 79endif
80 80
81ifndef NO_LIBPYTHON 81ifndef NO_LIBPYTHON
82define SOURCE_PYTHON_VERSION
83#include <Python.h>
84#if PY_VERSION_HEX >= 0x03000000
85 #error
86#endif
87int main(void){}
88endef
82define SOURCE_PYTHON_EMBED 89define SOURCE_PYTHON_EMBED
83#include <Python.h> 90#include <Python.h>
84
85int main(void) 91int main(void)
86{ 92{
87 Py_Initialize(); 93 Py_Initialize();