diff --git a/Makefile b/Makefile index 8efad812..cd177ced 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ # along with this program. If not, see # . -GCC=gcc +.PHONY: all clean debug dump_gimple plugin show-ssa tarball test-suite testcpychecker testcpybuilder PLUGIN_SOURCE_FILES= \ gcc-python.c \ @@ -37,6 +37,8 @@ PLUGIN_SOURCE_FILES= \ gcc-python-variable.c \ gcc-python-version.c \ gcc-python-wrapper.c \ + +PLUGIN_GENERATED_SOURCE_FILES:= \ autogenerated-callgraph.c \ autogenerated-cfg.c \ autogenerated-option.c \ @@ -50,8 +52,10 @@ PLUGIN_SOURCE_FILES= \ autogenerated-tree.c \ autogenerated-variable.c -PLUGIN_OBJECT_FILES= $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES)) -GCCPLUGINS_DIR:= $(shell $(GCC) --print-file-name=plugin) +PLUGIN_OBJECT_SOURCE_FILES:= $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES)) +PLUGIN_OBJECT_GENERATED_FILES:= $(patsubst %.c,%.o,$(PLUGIN_GENERATED_SOURCE_FILES)) +PLUGIN_OBJECT_FILES:= $(PLUGIN_OBJECT_SOURCE_FILES) $(PLUGIN_OBJECT_GENERATED_FILES) +GCCPLUGINS_DIR:= $(shell $(CC) --print-file-name=plugin) GENERATOR_DEPS=cpybuilder.py wrapperbuilder.py @@ -90,85 +94,65 @@ PYTHON_CONFIG=python-config #PYTHON=python3-debug #PYTHON_CONFIG=python3.2dmu-config -PYTHON_CFLAGS=$(shell $(PYTHON_CONFIG) --cflags) -PYTHON_LDFLAGS=$(shell $(PYTHON_CONFIG) --ldflags) +PYTHON_INCLUDES=$(shell $(PYTHON_CONFIG) --includes) +PYTHON_LIBS=$(shell $(PYTHON_CONFIG) --libs) + +GCC_PYTHON_PLUGIN_SO := python.so -CFLAGS+= -I$(GCCPLUGINS_DIR)/include -fPIC -fno-strict-aliasing -O2 -Wall -Werror -g $(PYTHON_CFLAGS) $(PYTHON_LDFLAGS) +CPPFLAGS+= -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -I. $(PYTHON_INCLUDES) +# Allow user to pick optimization, choose whether warnings are fatal, +# and choose debugging information level. +CFLAGS?=-O2 -Werror -g +# Force these settings +CFLAGS+= -fPIC -fno-strict-aliasing -Wall +LIBS+= $(PYTHON_LIBS) ifneq "$(PLUGIN_PYTHONPATH)" "" - CFLAGS+= -DPLUGIN_PYTHONPATH='"$(PLUGIN_PYTHONPATH)"' + CPPFLAGS+= -DPLUGIN_PYTHONPATH='"$(PLUGIN_PYTHONPATH)"' endif all: autogenerated-config.h testcpybuilder test-suite testcpychecker -plugin: autogenerated-config.h python.so - -python.so: $(PLUGIN_OBJECT_FILES) - $(GCC) $(CFLAGS) -shared $^ -o $@ - -clean: - rm -f *.so *.o - rm -f autogenerated* - rm -rf docs/_build - -autogenerated-config.h: configbuilder.py generate-config-h.py - $(PYTHON) generate-config-h.py -o $@ --gcc=$(GCC) - -autogenerated-gimple-types.txt: gimple-types.txt.in - cpp $(CFLAGS) $^ -o $@ - -autogenerated-rtl-types.txt: rtl-types.txt.in - cpp $(CFLAGS) $^ -o $@ +plugin: autogenerated-config.h $(GCC_PYTHON_PLUGIN_SO) -autogenerated-tree-types.txt: tree-types.txt.in - cpp $(CFLAGS) $^ -o $@ +$(GCC_PYTHON_PLUGIN_SO): $(PLUGIN_OBJECT_FILES) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $^ -o $@ $(LIBS) -autogenerated-callgraph.c: $(GENERATOR_DEPS) generate-callgraph-c.py - $(PYTHON) generate-callgraph-c.py > $@ +$(PLUGIN_OBJECT_GENERATED_FILES): CPPFLAGS+= $(if $(srcdir),-I$(srcdir)) -autogenerated-cfg.c: $(GENERATOR_DEPS) generate-cfg-c.py - $(PYTHON) generate-cfg-c.py > $@ +# This is the standard .c->.o recipe, but it needs to be stated +# explicitly to support the case that $(srcdir) is not blank. +$(PLUGIN_OBJECT_SOURCE_FILES): %.o: $(srcdir)%.c autogenerated-config.h $(srcdir)gcc-python.h + $(COMPILE.c) $(OUTPUT_OPTION) $< -autogenerated-function.c: $(GENERATOR_DEPS) generate-function-c.py - $(PYTHON) generate-function-c.py > $@ - -autogenerated-gimple.c: $(GENERATOR_DEPS) generate-gimple-c.py autogenerated-gimple-types.txt maketreetypes.py - $(PYTHON) generate-gimple-c.py > $@ - -autogenerated-location.c: $(GENERATOR_DEPS) generate-location-c.py - $(PYTHON) generate-location-c.py > $@ - -autogenerated-option.c: $(GENERATOR_DEPS) generate-option-c.py - $(PYTHON) generate-option-c.py > $@ - -autogenerated-parameter.c: $(GENERATOR_DEPS) generate-parameter-c.py - $(PYTHON) generate-parameter-c.py > $@ - -autogenerated-pass.c: $(GENERATOR_DEPS) generate-pass-c.py - $(PYTHON) generate-pass-c.py > $@ +clean: + $(RM) *.so *.o autogenerated* + $(RM) -r docs/_build -autogenerated-pretty-printer.c: $(GENERATOR_DEPS) generate-pretty-printer-c.py - $(PYTHON) generate-pretty-printer-c.py > $@ +autogenerated-config.h: $(addprefix $(srcdir),generate-config-h.py configbuilder.py) + $(PYTHON) $< -o $@ --gcc=$(CC) -autogenerated-tree.c: $(GENERATOR_DEPS) generate-tree-c.py autogenerated-tree-types.txt maketreetypes.py - $(PYTHON) generate-tree-c.py > $@ +autogenerated-%.txt: $(srcdir)%.txt.in + $(CPP) $(CPPFLAGS) -x c-header $^ -o $@ -autogenerated-rtl.c: $(GENERATOR_DEPS) generate-rtl-c.py autogenerated-rtl-types.txt maketreetypes.py - $(PYTHON) generate-rtl-c.py > $@ +$(PLUGIN_GENERATED_SOURCE_FILES): autogenerated-%.c: $(addprefix $(srcdir),generate-%-c.py $(GENERATOR_DEPS)) + $(PYTHON) $< > $@ -autogenerated-variable.c: $(GENERATOR_DEPS) generate-variable-c.py autogenerated-gimple-types.txt maketreetypes.py - $(PYTHON) generate-variable-c.py > $@ +autogenerated-gimple.c: autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt $(srcdir)maketreetypes.py +autogenerated-tree.c: autogenerated-tree-types.txt $(srcdir)maketreetypes.py +autogenerated-rtl.c: autogenerated-rtl-types.txt $(srcdir)maketreetypes.py +autogenerated-variable.c: autogenerated-gimple-types.txt $(srcdir)maketreetypes.py # Hint for debugging: add -v to the gcc options # to get a command line for invoking individual subprocesses # Doing so seems to require that paths be absolute, rather than relative # to this directory TEST_CFLAGS= \ - -fplugin=$(shell pwd)/python.so \ + -fplugin=$(CURDIR)/$(GCC_PYTHON_PLUGIN_SO) \ -fplugin-arg-python-script=test.py # A catch-all test for quick experimentation with the API: test: plugin - $(GCC) -v $(TEST_CFLAGS) $(shell pwd)/test.c + $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c # Selftest for the cpychecker.py code: testcpychecker: plugin @@ -179,23 +163,23 @@ testcpybuilder: $(PYTHON) testcpybuilder.py -v dump_gimple: - $(GCC) -fdump-tree-gimple $(shell pwd)/test.c + $(CC) -fdump-tree-gimple $(CURDIR)/test.c debug: plugin - $(GCC) -v $(TEST_CFLAGS) $(shell pwd)/test.c + $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c # A simple demo, to make it easy to demonstrate the cpychecker: demo: plugin - ./gcc-with-cpychecker $(shell $(PYTHON_CONFIG) --cflags) demo.c + $(srcdir)./gcc-with-cpychecker $(PYTHON_CFLAGS) demo.c json-examples: plugin - ./gcc-with-cpychecker -I/usr/include/python2.7 libcpychecker/html/test/example1/bug.c + $(srcdir)./gcc-with-cpychecker -I/usr/include/python2.7 libcpychecker/html/test/example1/bug.c test-suite: plugin $(PYTHON) run-test-suite.py show-ssa: plugin - ./gcc-with-python examples/show-ssa.py test.c + $(srcdir)./gcc-with-python examples/show-ssa.py test.c html: docs/tables-of-passes.rst docs/passes.svg cd docs && $(MAKE) html @@ -203,11 +187,11 @@ html: docs/tables-of-passes.rst docs/passes.svg # We commit this generated file to SCM to allow the docs to be built without # needing to build the plugin: docs/tables-of-passes.rst: plugin generate-tables-of-passes-rst.py - ./gcc-with-python generate-tables-of-passes-rst.py test.c > $@ + $(srcdir)./gcc-with-python generate-tables-of-passes-rst.py test.c > $@ # Likewise for this generated file: docs/passes.svg: plugin generate-passes-svg.py - ./gcc-with-python generate-passes-svg.py test.c + $(srcdir)./gcc-with-python generate-passes-svg.py test.c # Utility target, to help me to make releases # - creates a tag in git, and pushes it @@ -216,12 +200,15 @@ docs/passes.svg: plugin generate-passes-svg.py # The following assumes that VERSION has been set e.g. # $ make tarball VERSION=0.4 -tarball: +$(HOME)/rpmbuild/SOURCES/%.tar.gz: + test -n "$(VERSION)" -git tag -d v$(VERSION) git tag -a v$(VERSION) -m"$(VERSION)" - git archive --format=tar --prefix=gcc-python-plugin-$(VERSION)/ v$(VERSION) | gzip > gcc-python-plugin-$(VERSION).tar.gz - sha256sum gcc-python-plugin-$(VERSION).tar.gz - cp gcc-python-plugin-$(VERSION).tar.gz ~/rpmbuild/SOURCES/ + git archive --format=tar --prefix=$*/ v$(VERSION) | gzip > $*.tar.gz + sha256sum $*.tar.gz + cp $*.tar.gz $@ + +tarball: $(HOME)/rpmbuild/SOURCES/gcc-python-plugin-$(VERSION).tar.gz # Notes to self on making a release # --------------------------------- diff --git a/configbuilder.py b/configbuilder.py index 0bebfef7..3a420bbb 100644 --- a/configbuilder.py +++ b/configbuilder.py @@ -134,7 +134,7 @@ def compile(self, test, src, extraargs): with open(srcpath, 'w') as f: f.write(src) outpath = os.path.join(dirpath, 'feature-test.o') - args= [os.environ.get('GCC', 'gcc'), + args= [os.environ.get('CC', 'gcc'), '-c', # don't run the linker (no main) '-o', outpath, srcpath] + extraargs diff --git a/cpybuilder.py b/cpybuilder.py index 41f613da..3dc36fbd 100644 --- a/cpybuilder.py +++ b/cpybuilder.py @@ -17,7 +17,6 @@ from subprocess import Popen, PIPE import re -import six # For the purpose of the GCC plugin, it's OK to assume that we're compiling # with GCC itself, and thus we can use GCC extensions diff --git a/gcc-python-option.c b/gcc-python-option.c index 04835f59..14131379 100644 --- a/gcc-python-option.c +++ b/gcc-python-option.c @@ -20,7 +20,7 @@ #include #include "gcc-python.h" #include "gcc-python-wrappers.h" -#include "c-family/c-common.h" /* for warn_format */ +#include "c-common.h" /* for warn_format */ #include "diagnostic.h" diff --git a/gcc-python.c b/gcc-python.c index 6204bd4c..f037988f 100644 --- a/gcc-python.c +++ b/gcc-python.c @@ -34,7 +34,12 @@ int plugin_is_GPL_compatible; #include "cgraph.h" #include "opts.h" -#include "c-family/c-pragma.h" /* for parse_in */ +/* + * Use an unqualified name here and rely on dual search paths to let the + * compiler find it. This deals with c-pragma.h moving to a + * subdirectory in newer versions of gcc. + */ +#include "c-pragma.h" /* for parse_in */ #if 0 #define LOG(msg) \ diff --git a/run-test-suite.py b/run-test-suite.py index 47d3a95d..d277b3f3 100644 --- a/run-test-suite.py +++ b/run-test-suite.py @@ -253,7 +253,7 @@ def run_test(testdir): env['LC_ALL'] = 'C' # Generate the command-line for invoking gcc: - args = [os.environ.get('GCC', 'gcc')] + args = [os.environ.get('CC', 'gcc')] args += ['-c'] # (don't run the linker) args += ['-o', outfile] args += ['-fplugin=%s' % os.path.abspath('python.so'), diff --git a/test-builder.py b/test-builder.py index 9a0b1ed9..4540fe6f 100644 --- a/test-builder.py +++ b/test-builder.py @@ -47,7 +47,7 @@ from subprocess import Popen, PIPE, check_call -GCCPLUGINS_DIR = Popen([os.environ.get('GCC', 'gcc'), +GCCPLUGINS_DIR = Popen([os.environ.get('CC', 'gcc'), '--print-file-name=plugin'], stdout=PIPE).communicate()[0].strip() @@ -58,7 +58,7 @@ for pyconfig in pyconfigs: cflags = Popen([pyconfig, '--cflags', '--ldflags'], stdout=PIPE).communicate()[0] - args = [os.environ.get('GCC', 'gcc')] + args = [os.environ.get('CC', 'gcc')] args += ['-x', 'c'] # specify that it's C args += ['-o', 'test.so'] args += cflags.split() diff --git a/testcpybuilder.py b/testcpybuilder.py index 2c766cd4..424bb713 100644 --- a/testcpybuilder.py +++ b/testcpybuilder.py @@ -69,7 +69,7 @@ def write_src(self, modname, extra_cflags = None): def compile_src(self, extra_cflags = None): - self.args = [os.environ.get('GCC', 'gcc')] + self.args = [os.environ.get('CC', 'gcc')] self.args += ['-o', self.modfile] self.args += ['-I' + sc.get_python_inc(), '-I' + sc.get_python_inc(plat_specific=True)]