Skip to content

Please pull build improvements (and one code fix) from master #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ gcc-c-api/gcc-tree.h
gcc-c-api/gcc-type.h
gcc-c-api/gcc-variable.h
gcc-with-python.1.gz
print-gcc-version

# Generated by Sphinx
docs/_build
Expand Down
120 changes: 71 additions & 49 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.PHONY: all clean debug dump_gimple plugin show-ssa tarball \
test-suite testcpychecker testcpybuilder \
man
man install

PLUGIN_SOURCE_FILES= \
gcc-python.c \
Expand Down Expand Up @@ -55,12 +55,14 @@ PLUGIN_GENERATED_SOURCE_FILES:= \
autogenerated-tree.c \
autogenerated-variable.c

TARGET_GCC:=$(CC)

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)
GCCPLUGINS_DIR:= $(shell $(TARGET_GCC) --print-file-name=plugin)

GENERATOR_DEPS=cpybuilder.py wrapperbuilder.py print-gcc-version
GENERATOR_DEPS=cpybuilder.py wrapperbuilder.py autogenerated-gcc-version

# The plugin supports both Python 2 and Python 3
#
Expand Down Expand Up @@ -102,7 +104,7 @@ PYTHON_LIBS=$(shell $(PYTHON_CONFIG) --libs)

# Support having multiple named plugins
# e.g. "python2.7" "python3.2mu" "python 3.2dmu" etc:
PLUGIN_NAME := python
PLUGIN_NAME := $(PYTHON)
PLUGIN_DSO := $(PLUGIN_NAME).so
PLUGIN_DIR := $(PLUGIN_NAME)

Expand All @@ -114,8 +116,10 @@ CPPFLAGS+= -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -I.
# Allow user to pick optimization, choose whether warnings are fatal,
# and choose debugging information level.
CFLAGS?=-O2 -Werror -g
CXXFLAGS?=-O2 -Werror -g
# Force these settings
CFLAGS+= -fPIC -fno-strict-aliasing -Wall
CXXFLAGS+= -fPIC -fno-strict-aliasing -Wall
LIBS+= $(PYTHON_LIBS)
ifneq "$(PLUGIN_PYTHONPATH)" ""
CPPFLAGS+= -DPLUGIN_PYTHONPATH='"$(PLUGIN_PYTHONPATH)"'
Expand All @@ -132,49 +136,70 @@ plugin: autogenerated-config.h $(PLUGIN_DSO)
# When running the plugin from a working copy, use LD_LIBARY_PATH=gcc-c-api
# so that the plugin can find its libgcc-c-api.so there
#
INVOCATION_ENV_VARS := LD_LIBRARY_PATH=gcc-c-api CC=$(CC)
INVOCATION_ENV_VARS := LD_LIBRARY_PATH=gcc-c-api CC="$(TARGET_GCC)"

, := ,

define run-cc
set -- $1; \
read gcc_cxx < "autogenerated-EXTRA_CFLAGS.txt"; \
if [ "$$gcc_cxx" = '-x c' ]; then \
$(if $2,$2,$(CC) $(CFLAGS)) "$$@"; \
elif [ "$$gcc_cxx" = '-x c++' ]; then \
$(if $3,$3,$(CXX) $(CXXFLAGS)) "$$@"; \
else \
false; \
fi
endef

# When installing, both the plugin and libgcc-c-api.so will be installed to
# $(GCCPLUGINS_DIR), so we give the plugin an RPATH of $(GCCPLUGINS_DIR)
# so that it finds the libgcc-c-api.so there (to support the case of having
# multiple GCCs installed)
#
$(PLUGIN_DSO): $(PLUGIN_OBJECT_FILES) $(LIBGCC_C_API_SO)
$(CC) \
$(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
$(call run-cc, \
-shared \
$(PLUGIN_OBJECT_FILES) \
-o $@ \
$(LIBS) \
-lgcc-c-api -Lgcc-c-api -Wl,-rpath=$(GCCPLUGINS_DIR)
$(OUTPUT_OPTION) \
-lgcc-c-api -Lgcc-c-api -Wl$(,)-rpath=$(GCCPLUGINS_DIR), \
$(LINK.c), \
$(LINK.cpp) \
)

.PHONY: gcc-c-api/phony-stamp-gcc-api
gcc-c-api/phony-stamp-gcc-api: autogenerated-EXTRA_CFLAGS.txt autogenerated-gcc-version
$(MAKE) -C gcc-c-api libgcc-c-api.so CC="$(CC)" CXX="$(CXX)" TARGET_GCC="$(TARGET_GCC)"

$(LIBGCC_C_API_SO):
cd gcc-c-api && make libgcc-c-api.so CC=$(CC)
$(LIBGCC_C_API_SO): gcc-c-api/phony-stamp-gcc-api

$(PLUGIN_OBJECT_GENERATED_FILES): CPPFLAGS+= $(if $(srcdir),-I$(srcdir))

# 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) $(PLUGIN_OBJECT_GENERATED_FILES): %.o: $(srcdir)%.c autogenerated-config.h $(srcdir)gcc-python.h $(LIBGCC_C_API_SO) autogenerated-EXTRA_CFLAGS.txt
$(COMPILE.c) $(shell cat autogenerated-EXTRA_CFLAGS.txt) $(OUTPUT_OPTION) $<

print-gcc-version: print-gcc-version.c autogenerated-EXTRA_CFLAGS.txt
$(CC) \
$(CPPFLAGS) $(CFLAGS) \
$(shell cat autogenerated-EXTRA_CFLAGS.txt) \
-o $@ \
$<
$(PLUGIN_OBJECT_SOURCE_FILES) $(PLUGIN_OBJECT_GENERATED_FILES): %.o: $(srcdir)%.c autogenerated-config.h $(srcdir)gcc-python.h $(LIBGCC_C_API_SO) autogenerated-EXTRA_CFLAGS.txt autogenerated-gcc-version
read gcc_version < autogenerated-gcc-version || exit 1; $(call run-cc,-DTARGET_GCC_VERSION="$$gcc_version" $< $(OUTPUT_OPTION),$(COMPILE.c),$(COMPILE.cpp))

# Use a long variable name to avoid unwanted matches. Add an explicit
# -x c since gcc requires a language specifier when processing stdin.
# C and C++ print the same version, so skip
# autogenerated-EXTRA_CFLAGS.txt.
autogenerated-gcc-version:
echo gcc_version_major_minor= __GNUC__ __GNUC_MINOR__ | \
$(TARGET_GCC) -x c -E - | \
{ awk '/^gcc_version_major_minor=/ { print ($$2*1000)+$$3; exit 0; }' > "[email protected]" && test -s "[email protected]" && mv -f "[email protected]" "$@"; } || { rc=$$?; $(RM) "[email protected]"; exit $$rc; }

clean:
$(RM) *.so *.o gcc-c-api/*.o autogenerated*
$(RM) -r docs/_build
$(RM) -f gcc-with-$(PLUGIN_NAME).1 gcc-with-$(PLUGIN_NAME).1.gz
$(RM) -f print-gcc-version
cd gcc-c-api && make clean
$(RM) -f autogenerated-gcc-version
$(MAKE) -C gcc-c-api clean CC="$(CC)" TARGET_GCC="$(TARGET_GCC)"
find tests -name "*.o" -delete

autogenerated-config.h: $(addprefix $(srcdir),generate-config-h.py configbuilder.py)
$(PYTHON) $< -o $@ --gcc="$(CC)" --plugindir="$(GCCPLUGINS_DIR)"
$(PYTHON) $< -o $@ --gcc="$(TARGET_GCC)" --plugindir="$(GCCPLUGINS_DIR)"

autogenerated-%.txt: $(srcdir)%.txt.in
$(CPP) $(CPPFLAGS) -x c-header $^ -o $@
Expand All @@ -186,11 +211,16 @@ autogenerated-EXTRA_CFLAGS.txt: autogenerated-config.h
# autogenerated-casts.h is a byproduct of making autogenerated-casts.c
autogenerated-casts.h: autogenerated-casts.c

$(PLUGIN_GENERATED_SOURCE_FILES): autogenerated-%.c: $(addprefix $(srcdir),generate-%-c.py $(GENERATOR_DEPS))
$(PYTHON) $< > $@
# Generate to a temporary name, so that a failure in the script does not
# leave behind an up-to-date incomplete file.
$(filter-out autogenerated-casts.c,$(PLUGIN_GENERATED_SOURCE_FILES)): autogenerated-%.c: $(addprefix $(srcdir),generate-%-c.py $(GENERATOR_DEPS))
$(PYTHON) $< > "[email protected]" || { rc=$$?; $(RM) "[email protected]"; exit $$rc; }
mv -f "[email protected]" "$@"

autogenerated-casts.c: autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt $(srcdir)generate-casts-c.py
$(PYTHON) $(srcdir)generate-casts-c.py autogenerated-casts.c autogenerated-casts.h
autogenerated-casts.c: GENERATED_FILES:=autogenerated-casts.c autogenerated-casts.h
autogenerated-casts.c: $(srcdir)generate-casts-c.py autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt
$(PYTHON) $< $(addsuffix .part,$(GENERATED_FILES)) || { rc=$$?; $(RM) $(addsuffix .part,$(GENERATED_FILES)); exit $$rc; }
: $(foreach f,$(GENERATED_FILES),&& mv -f "$f.part" "$f")

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
Expand All @@ -203,19 +233,15 @@ mandir=/usr/share/man
UpperPluginName = $(shell $(PYTHON) -c"print('$(PLUGIN_NAME)'.upper())")

docs/_build/man/gcc-with-python.1: docs/gcc-with-python.rst
cd docs && $(MAKE) man
$(MAKE) -C docs man

gcc-with-$(PLUGIN_NAME).1: docs/_build/man/gcc-with-python.1
# Fixup the generic manpage for this build:
cp docs/_build/man/gcc-with-python.1 gcc-with-$(PLUGIN_NAME).1
sed \
-i \
-e"s|gcc-with-python|gcc-with-$(PLUGIN_NAME)|g" \
gcc-with-$(PLUGIN_NAME).1
sed \
-i \
-e"s|GCC-WITH-PYTHON|GCC-WITH-$(UpperPluginName)|g" \
gcc-with-$(PLUGIN_NAME).1
< $< \
> $@

gcc-with-$(PLUGIN_NAME).1.gz: gcc-with-$(PLUGIN_NAME).1
rm -f gcc-with-$(PLUGIN_NAME).1.gz
Expand All @@ -226,7 +252,7 @@ man: gcc-with-$(PLUGIN_NAME).1.gz
install: $(PLUGIN_DSO) gcc-with-$(PLUGIN_NAME).1.gz
mkdir -p $(DESTDIR)$(GCCPLUGINS_DIR)

cd gcc-c-api && $(MAKE) install
$(MAKE) -C gcc-c-api install

cp $(PLUGIN_DSO) $(DESTDIR)$(GCCPLUGINS_DIR)

Expand All @@ -236,21 +262,17 @@ install: $(PLUGIN_DSO) gcc-with-$(PLUGIN_NAME).1.gz

# Create "gcc-with-" support script:
mkdir -p $(DESTDIR)$(bindir)
install -m 755 gcc-with-python $(DESTDIR)/$(bindir)/gcc-with-$(PLUGIN_NAME)
# Fixup the reference to the plugin in that script, from being expressed as
# a DSO filename with a path (for a working copy) to a name of an installed
# plugin within GCC's search directory:
sed \
-i \
-e"s|-fplugin=[^ ]*|-fplugin=$(PLUGIN_NAME)|" \
$(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME)

# Fixup the plugin name within -fplugin-arg-PLUGIN_NAME-script to match the
# Fixup the plugin name within -fplugin-arg-PLUGIN_NAME-script to match the
# name for this specific build:
sed \
-i \
-e"s|-fplugin=[^ ]*|-fplugin=$(PLUGIN_NAME)|" \
-e"s|-fplugin-arg-python-script|-fplugin-arg-$(PLUGIN_NAME)-script|" \
$(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME)
< gcc-with-python \
> $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME)
chmod 755 $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME)

mkdir -p $(DESTDIR)$(mandir)/man1
cp gcc-with-$(PLUGIN_NAME).1.gz $(DESTDIR)$(mandir)/man1
Expand All @@ -266,7 +288,7 @@ TEST_CFLAGS= \

# A catch-all test for quick experimentation with the API:
test: plugin
$(INVOCATION_ENV_VARS) $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c
$(INVOCATION_ENV_VARS) $(TARGET_GCC) -v $(TEST_CFLAGS) $(CURDIR)/test.c

# Selftest for the cpychecker.py code:
testcpychecker: plugin
Expand All @@ -277,10 +299,10 @@ testcpybuilder:
$(PYTHON) testcpybuilder.py -v

dump_gimple:
$(CC) -fdump-tree-gimple $(CURDIR)/test.c
$(TARGET_GCC) -fdump-tree-gimple $(CURDIR)/test.c

debug: plugin
$(INVOCATION_ENV_VARS) $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c
$(INVOCATION_ENV_VARS) $(TARGET_GCC) -v $(TEST_CFLAGS) $(CURDIR)/test.c

# A simple demo, to make it easy to demonstrate the cpychecker:
demo: plugin
Expand All @@ -289,14 +311,14 @@ demo: plugin
json-examples: plugin
$(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-cpychecker -I/usr/include/python2.7 -c libcpychecker_html/test/example1/bug.c

test-suite: plugin print-gcc-version
test-suite: plugin autogenerated-gcc-version
$(INVOCATION_ENV_VARS) $(PYTHON) run-test-suite.py

show-ssa: plugin
$(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-python examples/show-ssa.py test.c

html: docs/tables-of-passes.rst docs/passes.svg
cd docs && $(MAKE) html
$(MAKE) -C docs $@

# We commit this generated file to SCM to allow the docs to be built without
# needing to build the plugin:
Expand Down
8 changes: 7 additions & 1 deletion cpybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ def nullable_ptr(ptr):
else:
return 'NULL'

def nullable_strptr(s,caststr='char*'):
if s:
return '(%s)"%s"' % (caststr,s)
else:
return 'NULL'

def simple_unaryfunc(identifier, typename, c_expression):
"""Define a simple unaryfunc, using a specifc PyObject subclass"""
self.add_defn("static PyObject *\n" +
Expand Down Expand Up @@ -97,7 +103,7 @@ def c_defn(self):
result = ' {(char*)"%s",\n' % self.name
result += ' (getter)%s,\n' % nullable_ptr(self.get)
result += ' (setter)%s,\n' % nullable_ptr(self.set)
result += ' (char*)"%s",\n' % nullable_ptr(self.doc)
result += ' %s,\n' % nullable_strptr(self.doc)
result += ' %s},\n' % nullable_ptr(self.closure)
return result

Expand Down
39 changes: 33 additions & 6 deletions gcc-c-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.

.PHONY: all clean check-api
.PHONY: all clean check-api install

HANDWRITTEN_C_FILES = \
gcc-callgraph.c \
Expand Down Expand Up @@ -70,26 +70,42 @@ GENERATED_HEADERS:= \
gcc-type.h \
gcc-variable.h

GCCPLUGINS_DIR:= $(shell $(CC) --print-file-name=plugin)
TARGET_GCC:=$(CC)

GCCPLUGINS_DIR:= $(shell $(TARGET_GCC) --print-file-name=plugin)

LIBGCC_C_API_SO := libgcc-c-api.so

CPPFLAGS+= -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -I.
# Allow user to pick optimization, choose whether warnings are fatal,
# and choose debugging information level.
CFLAGS?=-O2 -Werror -g
CXXFLAGS?=-O2 -Werror -g
# Force these settings
CFLAGS+= -fPIC -fno-strict-aliasing -Wall
CXXFLAGS+= -fPIC -fno-strict-aliasing -Wall

define run-cc
set -- $1; \
read gcc_cxx < "../autogenerated-EXTRA_CFLAGS.txt"; \
if [ "$$gcc_cxx" = '-x c' ]; then \
$(if $2,$2,$(CC) $(CFLAGS)) "$$@"; \
elif [ "$$gcc_cxx" = '-x c++' ]; then \
$(if $3,$3,$(CXX) $(CXXFLAGS)) "$$@"; \
else \
false; \
fi
endef

all: $(LIBGCC_C_API_SO)

$(LIBGCC_C_API_SO): $(OBJECT_FILES)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $^ -o $@ $(LIBS)
$(call run-cc,-shared $^ $(OUTPUT_OPTION) $(LIBS),$(LINK.c),$(LINK.cpp))

# This is the standard .c->.o recipe, but it needs to be stated
# explicitly to support the case that $(srcdir) is not blank.
$(OBJECT_FILES): %.o: $(srcdir)%.c $(GENERATED_HEADERS) ../autogenerated-EXTRA_CFLAGS.txt
$(COMPILE.c) $(shell cat ../autogenerated-EXTRA_CFLAGS.txt) $(OUTPUT_OPTION) $<
$(OBJECT_FILES): %.o: $(srcdir)%.c $(GENERATED_HEADERS) ../autogenerated-EXTRA_CFLAGS.txt ../autogenerated-gcc-version
read gcc_version < ../autogenerated-gcc-version || exit 1; $(call run-cc,-DTARGET_GCC_VERSION="$$gcc_version" $< $(OUTPUT_OPTION),$(COMPILE.c),$(COMPILE.cpp))

autogenerated-casts.c: $(SOURCE_XML) xmltypes.py generate-casts-c.py
$(PYTHON) generate-casts-c.py $@
Expand All @@ -104,8 +120,19 @@ install: $(LIBGCC_C_API_SO)
# The python interpreter to use:
PYTHON=python

$(GENERATED_HEADERS): $(SOURCE_XML) xml-to-h.py xmltypes.py
# Describe how to build the first generated header
$(firstword $(GENERATED_HEADERS)):
$(PYTHON) xml-to-h.py

# Make all generated headers depend on the true inputs
$(GENERATED_HEADERS): xml-to-h.py xmltypes.py $(SOURCE_XML)

# Add a fake dependency so that all headers other than the first will
# depend on the first. This allows the first generated header to do
# double duty as a flag file. This indirection ensures that Make will
# only run one instance of the generation rule, rather than one per
# required header file.
$(wordlist 2, $(words $(GENERATED_HEADERS)), $(GENERATED_HEADERS)): $(firstword $(GENERATED_HEADERS))

check-api:
xmllint --noout --relaxng api.rng *.xml
8 changes: 4 additions & 4 deletions gcc-c-api/gcc-callgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ GCC_PUBLIC_API (void) gcc_cgraph_node_mark_in_use (gcc_cgraph_node node)
/* As of gcc 4.9, a cgraph_node inherits from symtab node and uses that
struct's marking routine.
*/
#if (GCC_VERSION >= 4009)
#if (TARGET_GCC_VERSION >= 4009)
gt_ggc_mx_symtab_node (node.inner);
#else
gt_ggc_mx_cgraph_node (node.inner);
Expand All @@ -58,11 +58,11 @@ gcc_cgraph_node_get_decl (gcc_cgraph_node node)
*/
tree decl;

#if (GCC_VERSION >= 4009)
#if (TARGET_GCC_VERSION >= 4009)
/* Access decl field of parent class, symtab_node */
decl = node.inner->decl;
#else
# if (GCC_VERSION >= 4008)
# if (TARGET_GCC_VERSION >= 4008)
decl = node.inner->symbol.decl;
# else
decl = node.inner->decl;
Expand Down Expand Up @@ -153,7 +153,7 @@ gcc_for_each_cgraph_node (bool (*cb) (gcc_cgraph_node node, void *user_data),
gcc 4.8 eliminated: extern GTY(()) struct cgraph_node *cgraph_nodes;
FIXME: does this only visit *defined* functions then?
*/
#if (GCC_VERSION >= 4008)
#if (TARGET_GCC_VERSION >= 4008)
FOR_EACH_DEFINED_FUNCTION(node)
#else
for (node = cgraph_nodes; node; node = node->next)
Expand Down
Loading