| # Specify the gcc executable you will use the dragonegg plugin with either here |
| # or on the command line, for example like this (replace gcc-4.7 with the gcc |
| # you want to load the plugin into): |
| # GCC=gcc-4.7 make ... |
| # If you don't specify anything, then by default the plugin targets the compiler |
| # used to build it. |
| GCC?=$(CC) |
| |
| # Specify the copy of LLVM you will build the plugin against by giving its |
| # llvm-config here or on the command line. To use an installed copy of LLVM, |
| # specify the installed llvm-config (just 'llvm-config' is enough if it is in |
| # your path). It is not necessary to install LLVM to build dragonegg against |
| # it. Instead you can do an LLVM build and point LLVM_CONFIG to the copy of |
| # llvm-config that was created during the build. |
| LLVM_CONFIG?=llvm-config |
| |
| # Location of this Makefile, useful if you want separate source and object |
| # directories. |
| TOP_DIR?=$(CURDIR) |
| |
| # Normally the plugin will refuse to load into a different gcc to the one it was |
| # built against. Uncomment this (or pass DISABLE_VERSION_CHECK=1 on the 'make' |
| # command line) to disable the check. |
| #DISABLE_VERSION_CHECK=1 |
| |
| # Where to find the lit.py script and modules, used for running tests. |
| LIT_DIR?=$(shell $(LLVM_CONFIG) --src-root)/utils/lit |
| # Where to find LLVM utils, used for running tests. |
| LLVM_TOOLS_DIR?=$(shell $(LLVM_CONFIG) --bindir) |
| |
| INCLUDE_DIR=$(TOP_DIR)/include |
| SRC_DIR=$(TOP_DIR)/src |
| |
| ifndef VERBOSE |
| QUIET:=@ |
| endif |
| |
| COMMON_FLAGS=-Wall -Wextra |
| ifdef ENABLE_LLVM_PLUGINS |
| COMMON_FLAGS+=-DENABLE_LLVM_PLUGINS |
| else |
| COMMON_FLAGS+=-fvisibility=hidden |
| endif |
| CFLAGS+=$(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cflags) |
| CXXFLAGS+=$(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cxxflags) |
| |
| ifeq ($(shell uname),Darwin) |
| LOADABLE_MODULE_OPTIONS=-bundle -undefined dynamic_lookup |
| else |
| LOADABLE_MODULE_OPTIONS=-shared -Wl,-O1 |
| ifndef ENABLE_LLVM_PLUGINS |
| LOADABLE_MODULE_OPTIONS+=-Wl,--version-script=$(TOP_DIR)/exports.map |
| endif |
| endif |
| |
| GCC_PLUGIN_DIR=$(shell $(GCC) -print-file-name=plugin) |
| GCC_VERSION=$(shell $(GCC) -dumpversion).0 |
| GCC_MAJOR=$(word 1, $(subst ., ,$(GCC_VERSION))) |
| GCC_MINOR=$(word 2, $(subst ., ,$(GCC_VERSION))) |
| GCC_MICRO=$(word 3, $(subst ., ,$(GCC_VERSION))) |
| TARGET_TRIPLE=$(shell $(GCC) -dumpmachine) |
| |
| LLVM_VERSION=$(shell $(LLVM_CONFIG) --version) |
| |
| PLUGIN=dragonegg.so |
| PLUGIN_OBJECTS=Aliasing.o Backend.o Cache.o ConstantConversion.o Convert.o \ |
| Debug.o DefaultABI.o Trees.o TypeConversion.o bits_and_bobs.o |
| |
| TARGET_OBJECT=Target.o |
| TARGET_SOURCE=$(SRC_DIR)/$(shell $(TARGET_UTIL) -p)/Target.cpp |
| |
| TARGET_UTIL_OBJECTS=TargetInfo.o |
| TARGET_UTIL=./TargetInfo |
| |
| ALL_OBJECTS=$(PLUGIN_OBJECTS) $(TARGET_OBJECT) $(TARGET_UTIL_OBJECTS) |
| |
| CPP_OPTIONS+=$(CPPFLAGS) $(shell $(LLVM_CONFIG) --cppflags) \ |
| -fno-rtti \ |
| -MD -MP \ |
| -DIN_GCC -DLLVM_VERSION=\"$(LLVM_VERSION)\" \ |
| -DTARGET_TRIPLE=\"$(TARGET_TRIPLE)\" \ |
| -DGCC_MAJOR=$(GCC_MAJOR) -DGCC_MINOR=$(GCC_MINOR) \ |
| -DGCC_MICRO=$(GCC_MICRO) \ |
| -I$(INCLUDE_DIR) -isystem$(GCC_PLUGIN_DIR)/include |
| ifdef DISABLE_VERSION_CHECK |
| CPP_OPTIONS+=-DDISABLE_VERSION_CHECK |
| endif |
| ifneq ($(GCC_MINOR), 5) |
| ifneq ($(GCC_MINOR), 6) |
| ifneq ($(GCC_MINOR), 7) |
| # gcc-4.8 and later are always built with C++. |
| CPP_OPTIONS+=-DENABLE_BUILD_WITH_CXX |
| endif |
| endif |
| endif |
| |
| LD_OPTIONS+=$(shell $(LLVM_CONFIG) --ldflags) $(LDFLAGS) |
| |
| LLVM_COMPONENTS=ipo scalaropts target |
| ifdef ENABLE_LLVM_PLUGINS |
| # The same components as the "opt" tool. |
| LLVM_COMPONENTS+=bitreader bitwriter asmparser instrumentation vectorize |
| endif |
| |
| # NOTE: The following flags can only be used after TARGET_UTIL has been built. |
| TARGET_HEADERS+=-I$(INCLUDE_DIR)/$(shell $(TARGET_UTIL) -p) \ |
| -I$(INCLUDE_DIR)/$(shell $(TARGET_UTIL) -o) |
| |
| ifdef VERBOSE |
| LIT_ARGS+=-v |
| else |
| LIT_ARGS+=-s -v |
| endif |
| |
| LIT_SITE_CONFIG=test/dragonegg-lit.site.cfg |
| TEST_SRC_DIR=$(TOP_DIR)/test |
| |
| default: gcc-sane llvm-config-sane $(PLUGIN) |
| |
| .PHONY: gcc-sane |
| gcc-sane: |
| $(QUIET)$(GCC) --version > /dev/null |
| |
| .PHONY: llvm-config-sane |
| llvm-config-sane: |
| $(QUIET)$(LLVM_CONFIG) --version > /dev/null |
| |
| $(TARGET_UTIL_OBJECTS): %.o : $(TOP_DIR)/utils/%.cpp |
| @echo Compiling utils/$*.cpp |
| $(QUIET)$(CXX) -c \ |
| $(CPP_OPTIONS) $(CXXFLAGS) $< |
| |
| $(TARGET_UTIL): $(TARGET_UTIL_OBJECTS) |
| @echo Linking $@ |
| $(QUIET)$(CXX) -o $@ $^ \ |
| $(shell $(LLVM_CONFIG) --libs support --system-libs) \ |
| $(LD_OPTIONS) |
| |
| %.o : $(SRC_DIR)/%.cpp $(TARGET_UTIL) |
| @echo Compiling $*.cpp |
| $(QUIET)$(CXX) -c $(TARGET_HEADERS) $(CPP_OPTIONS) $(CXXFLAGS) $< |
| |
| $(TARGET_OBJECT): $(TARGET_UTIL) |
| @echo Compiling $(shell $(TARGET_UTIL) -p)/Target.cpp |
| $(QUIET)$(CXX) -o $@ -c $(TARGET_HEADERS) $(CPP_OPTIONS) $(CXXFLAGS) \ |
| $(TARGET_SOURCE) |
| |
| $(PLUGIN): $(PLUGIN_OBJECTS) $(TARGET_OBJECT) $(TARGET_UTIL) |
| @echo Linking $@ |
| $(QUIET)$(CXX) -o $@ $(LOADABLE_MODULE_OPTIONS) $(CXXFLAGS) \ |
| $(PLUGIN_OBJECTS) $(TARGET_OBJECT) \ |
| $(shell $(LLVM_CONFIG) --libs $(LLVM_COMPONENTS) --system-libs \ |
| $(shell $(TARGET_UTIL) -p)) \ |
| $(LD_OPTIONS) |
| |
| $(LIT_SITE_CONFIG): $(TEST_SRC_DIR)/dragonegg-lit.site.cfg.in |
| @echo "Making DragonEgg '$@' file..." |
| $(QUIET)mkdir -p test |
| $(QUIET)echo s=@DRAGONEGG_PLUGIN@=$(CURDIR)/$(PLUGIN)=g > lit.tmp |
| $(QUIET)echo s=@GCC@=$(GCC)=g >> lit.tmp |
| $(QUIET)echo s=@LLVM_TOOLS_DIR@=$(LLVM_TOOLS_DIR)=g >> lit.tmp |
| $(QUIET)echo s=@TARGET_TRIPLE@=$(TARGET_TRIPLE)-gcc-$(GCC_MAJOR).$(GCC_MINOR)=g >> lit.tmp |
| $(QUIET)echo s=@TEST_OUTPUT_DIR@=$(CURDIR)/test/Output=g >> lit.tmp |
| $(QUIET)sed -f lit.tmp $< > $@ |
| $(QUIET)-rm -f lit.tmp |
| |
| .PHONY: check-compilator |
| check-compilator: $(PLUGIN) $(LIT_SITE_CONFIG) |
| @echo "Running test suite 'compilator'" |
| $(QUIET)$(LIT_DIR)/lit.py $(LIT_ARGS) --param site="$(LIT_SITE_CONFIG)" \ |
| --config-prefix=compilator-lit $(TEST_SRC_DIR)/compilator |
| |
| .PHONY: check-validator |
| check-validator: $(PLUGIN) $(LIT_SITE_CONFIG) |
| @echo "Running test suite 'validator'" |
| $(QUIET)$(LIT_DIR)/lit.py $(LIT_ARGS) --param site="$(LIT_SITE_CONFIG)" \ |
| --config-prefix=validator-lit $(TEST_SRC_DIR)/validator |
| |
| .PHONY: check |
| check: check-validator check-compilator |
| |
| .PHONY: clean |
| clean: |
| $(QUIET)rm -f *.o *.d $(PLUGIN) $(TARGET_UTIL) $(LIT_SITE_CONFIG) |
| |
| .DELETE_ON_ERROR: |
| |
| |
| -include $(ALL_OBJECTS:.o=.d) |
| |
| # The following target exists for the benefit of the dragonegg maintainers, and |
| # is not used in a normal build. You need to specify the path to the GCC build |
| # directory in GCC_BUILD_DIR. |
| GENGTYPE_INPUT=$(SRC_DIR)/Cache.cpp |
| GENGTYPE_OUTPUT=$(INCLUDE_DIR)/dragonegg/gt-cache-$(GCC_MAJOR).$(GCC_MINOR).inc |
| .PHONY: gt-cache.inc |
| gt-cache.inc: |
| $(QUIET)$(GCC_BUILD_DIR)/gcc/build/gengtype \ |
| -r $(GCC_BUILD_DIR)/gcc/gtype.state \ |
| -P $(GENGTYPE_OUTPUT) $(GENGTYPE_INPUT) |
| $(QUIET)sed -i "s/__.*gt/__gt/" $(GENGTYPE_OUTPUT) |
| $(QUIET)sed -i "s/_$(GCC_MAJOR)_$(GCC_MINOR)_/_/" $(GENGTYPE_OUTPUT) |