| |
| .PHONY: all tidy clean distclean confclean |
| .SECONDARY: |
| .SUFFIXES: |
| #.SUFFIXES: .c .cpp .cxx .cc .h .hpp .o .a .bc .ll .jar $(SHLIBEXT) $(EXEEXT) |
| |
| all:: |
| |
| ############################################################################### |
| # Main options |
| ############################################################################### |
| BUILD_NAME=$(VMKIT_BUILD_NAME) |
| |
| ifneq ($(ASSERT),1) |
| COMMON_CFLAGS+=-DNDEBUG |
| endif |
| |
| ifeq ($(DEBUG),1) |
| COMMON_CFLAGS+=-g3 -fno-limit-debug-info |
| endif |
| |
| ifeq ($(OPTIMIZED),1) |
| LLC_FLAGS+= -O=3 |
| OPT_FLAGS+= -disable-opt |
| CPPGEN_FLAGS+=-strip-debug |
| COMMON_CFLAGS+= -O3 |
| else |
| LLC_FLAGS+=-O=0 -asm-verbose |
| OPT_FLAGS+=-disable-opt -inline |
| CPPGEN_FLAGS+=-disable-opt |
| COMMON_CFLAGS+=-O0 |
| PRECOMPILER_OPT+=-disable-opt |
| endif |
| |
| LLC_FLAGS+=-disable-cfi -disable-fp-elim -relocation-model=pic |
| OPT_FLAGS+=-disable-cfi -disable-fp-elim |
| |
| INCLUDES+=-I$(PROJ_SRC_CWD) -I$(PROJ_SRC_ROOT)/include -I$(PROJ_SRC_ROOT)/lib/vmkit/MMTk -I$(BUILD_DIR) \ |
| -I$(shell $(LLVM_CONFIG) --includedir) -I$(shell $(LLVM_CONFIG) --src-root) |
| |
| WARN_CFLAGS= -Wall -Wno-long-long -Wno-variadic-macros -Wno-unused-private-field -Wno-unused-variable |
| COMMON_CFLAGS+= $(INCLUDES) -ansi -pedantic $(WARN_CFLAGS) -fPIC \ |
| -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \ |
| -fno-strict-aliasing -fno-omit-frame-pointer -fvisibility-inlines-hidden |
| |
| CFLAGS+=$(COMMON_CFLAGS) |
| CXXFLAGS+=$(COMMON_CFLAGS) -Woverloaded-virtual -Wcast-qual -fno-exceptions $(LLVM_RTTI) |
| LDFLAGS+=$(COMMON_CFLAGS) $(shell $(LLVM_CONFIG) --ldflags) $(LDOPT) |
| SHOPT+=$(COMMON_CFLAGS) |
| LIBS+=$(shell $(LLVM_CONFIG) --libs) -lz |
| |
| DEPEND_OPTIONS=-MMD -MP -MF "$(BUILD_DIR)/$$*.d.tmp" -MT "$(BUILD_DIR)/$$*.bc" -MT "$(BUILD_DIR)/$$*.d" |
| DOM=then mv -f "$(BUILD_DIR)/$$*.d.tmp" "$(BUILD_DIR)/$$*.d"; else rm -f "$(BUILD_DIR)/$$*.d.tmp"; exit 1; fi |
| |
| ############################################################################### |
| # Nice printing |
| ############################################################################### |
| ifndef PROF |
| PROF=. |
| all:: |
| $(Echo) "Entering compilation process" |
| endif |
| |
| EchoMsg="[$(PROJECT_NAME) $(PROF)]:" |
| Echo=@echo $(EchoMsg) |
| |
| ifndef VERBOSE |
| SUB_OPT=--no-print-directory |
| Verb:=@ |
| endif |
| |
| ############################################################################### |
| # Recursive target managment |
| ############################################################################### |
| RECURSIVE_TARGETS=all clean distclean |
| |
| $(RECURSIVE_TARGETS):: |
| $(Verb) for f in $(DIRS); do \ |
| $(MAKE) $(SUB_OPT) -C $$f $@ PROF=$(PROF)/$$f; \ |
| if [ $$? != 0 ]; then echo "$(EchoMsg) abort with error in $(PROF)/$$f"; exit 1; fi \ |
| done; exit 0; |
| |
| tidy: |
| $(Echo) Cleaning temporary files |
| $(Verb) find $(PROJ_OBJ_ROOT) -iname "*~" -exec rm -f {} \; |
| |
| clean:: |
| $(Echo) "Cleaning compilation files" |
| $(Verb) rm -Rf $(BUILD_NAME) |
| |
| distclean:: |
| $(Echo) "Cleaning all compilation files" |
| $(Verb) rm -Rf Release* Debug* Unoptimized* |
| |
| confclean: clean |
| $(Echo) Cleaning configuration |
| $(Verb) rm -Rf $(PROJ_OBJ_ROOT)/Makefile.common |
| $(Verb) rm -Rf $(PROJ_OBJ_ROOT)/config.status $(PROJ_OBJ_ROOT)/config.log |
| $(Verb) rm -Rf $(PROJ_OBJ_ROOT)/autoconf/autom4te.cache $(PROJ_OBJ_ROOT)/autoconf/configure.bak |
| |
| %/.dir: |
| $(Verb) $(MKDIR) $(dir $@) && $(TOUCH) $@ |
| |
| ############################################################################### |
| # Build system managment |
| ############################################################################### |
| #SELF=$(PROJ_SRC_ROOT)/Makefile.rules $(PROJ_OBJ_ROOT)/Makefile.common Makefile |
| |
| $(LEVEL)/Makefile.common: $(PROJ_OBJ_ROOT)/Makefile.common |
| |
| define define_config_rule |
| $$(PROJ_OBJ_ROOT)/$1: $$(PROJ_SRC_ROOT)/$1.in $$(PROJ_SRC_ROOT)/configure |
| $(Echo) "Regenerating project files $$1" |
| $(Verb) cd $(PROJ_OBJ_ROOT) && ./config.status -q --$2=$1 |
| $(Verb) touch $$@ |
| endef |
| |
| $(foreach cur,$(CONFIG_FILES),$(eval $(call define_config_rule,$(cur),file))) |
| $(foreach cur,$(CONFIG_HEADERS),$(eval $(call define_config_rule,$(cur),header))) |
| |
| $(PROJ_OBJ_ROOT)/configure: $(PROJ_SRC_ROOT)/autoconf/configure.ac $(PROJ_SRC_ROOT)/autoconf/AutoRegen.sh |
| $(Echo) "Rebootstraping project" |
| $(Verb) cd $(PROJ_SRC_ROOT)/autoconf && ./AutoRegen.sh |
| $(Verb) cd $(PROJ_OBJ_ROOT) && ./config.status --recheck |
| |
| ############################################################################### |
| # Build directories and generated binaries |
| ############################################################################### |
| BIN_DIR=$(PROJ_OBJ_ROOT)/$(BUILD_NAME)/bin |
| LIB_DIR=$(PROJ_OBJ_ROOT)/$(BUILD_NAME)/lib |
| BUILD_DIR=$(PROJ_OBJ_CWD)/$(BUILD_NAME) |
| |
| STATIC_GC_PASS_LIB=$(LIB_DIR)/static-gc-pass$(SHLIBEXT) |
| STATIC_GC_PRINTER_LIB=$(LIB_DIR)/static-gc-printer$(SHLIBEXT) |
| VMJC=$(BIN_DIR)/vmjc$(EXEEXT) |
| PRECOMPILER=$(BIN_DIR)/precompiler |
| |
| ############################################################################### |
| # Main targets |
| ############################################################################### |
| ifdef TOOL |
| MODULE=$(TOOL) |
| |
| all:: $(BIN_DIR)/$(TOOL)$(EXEEXT) |
| endif |
| |
| ifdef LIBRARY |
| MODULE=$(LIBRARY) |
| |
| all:: $(LIB_DIR)/$(LIBRARY)$(SHLIBEXT) |
| endif |
| |
| ifdef MODULE_WITH_GC |
| MODULE=$(MODULE_WITH_GC) |
| NEED_GC=1 |
| endif |
| |
| ############################################################################### |
| # GC passes |
| ############################################################################### |
| ifdef NEED_GC |
| LLC_GC_FLAGS+=-load=$(STATIC_GC_PRINTER_LIB) |
| GC_ID=-gc |
| |
| %$(GC_ID).bc: %.bc |
| $(Echo) "Preparing GC '$(notdir $<)'" |
| $(Verb) $(LOPT) -load=$(STATIC_GC_PASS_LIB) $(OPT_FLAGS) -StaticGCPass $< -o $@ |
| |
| endif |
| |
| ############################################################################### |
| # Module |
| ############################################################################### |
| ifdef MODULE |
| |
| MODULE_A=$(LIB_DIR)/lib$(MODULE).a |
| |
| all:: $(MODULE_A) |
| |
| ifdef EXTRACT_FUNCTIONS |
| all:: $(LIB_DIR)/$(MODULE)-inliner.o |
| MODULE_A_DEP=$(LIB_DIR)/$(MODULE)-inliner.o |
| NEED_BC=1 |
| endif |
| |
| define all-suffixes |
| $(wildcard *$1) $(filter %$1, $(GEN)) |
| endef |
| |
| CLANG_FILES=$(patsubst %.c,$(BUILD_DIR)/%,$(call all-suffixes,.c)) \ |
| $(patsubst %.cc,$(BUILD_DIR)/%,$(call all-suffixes,.cc)) \ |
| $(patsubst %.cpp,$(BUILD_DIR)/%,$(call all-suffixes,.cpp)) |
| |
| BC_FILES=$(addsuffix .bc,$(CLANG_FILES)) $(addprefix $(BUILD_DIR)/,$(filter %.bc, $(GEN))) |
| |
| ifdef NEED_BC |
| # if we need bytecode, we link a module with all the bc in the build_dir directory, optimize this module |
| # assemble this module and finally create the archive |
| all:: $(LIB_DIR)/$(MODULE).bc |
| |
| $(LIB_DIR)/$(MODULE).bc $(LIB_DIR)/$(MODULE)-inliner.bc: $(LIB_DIR)/%.bc: $(BUILD_DIR)/%$(GC_ID).bc $(LIB_DIR)/.dir |
| $(Verb) $(CP) $< $@ |
| |
| $(BUILD_DIR)/$(MODULE).bc: $(BC_FILES) $(patsubst %, $(LIB_DIR)/%.bc,$(MODULE_USE)) |
| $(Echo) "Linking module '$(notdir $@)'" |
| $(Verb) $(LLVMLINK) $^ -o $@ |
| |
| MODULE_A_DEP+=$(BUILD_DIR)/$(MODULE)$(GC_ID).o |
| else |
| # for most of the module, we avoid a full module creation, mainly because I have bugs in llc |
| # in this case, we build a set of .o files and archive them together |
| # each .o is optimized and assembled |
| MODULE_A_DEP=$(patsubst %.bc,%$(GC_ID).o,$(BC_FILES)) $(patsubst %, $(LIB_DIR)/lib%.a,$(MODULE_USE)) |
| endif |
| |
| ############################################################################### |
| # OpenJDK definitions |
| ############################################################################### |
| ifeq ($(MODULE), Classpath) |
| ifeq ($(CLASSPATH_IMPL), openjdk) |
| VMKIT_OPENJDK_ZIP=$(BUILD_DIR)/vmkit-openjdk.zip |
| CLASSES_DIR=$(PROJ_SRC_CWD)/classes |
| MODULE_A_DEP+=$(VMKIT_OPENJDK_ZIP) |
| OPENJDK_JAVA_SOURCES=$(PROJ_SRC_CWD)/java/lang/VMString.java |
| endif |
| endif |
| |
| $(MODULE_A): $(MODULE_A_DEP) $(LIB_DIR)/.dir |
| $(Echo) "Building archive '$(notdir $@)'" |
| -$(Verb) $(RM) -f $@ |
| $(Verb) $(Archive) $@ $(MODULE_A_DEP) |
| $(Verb) $(Ranlib) $@ |
| |
| endif |
| |
| ############################################################################### |
| # Inliner |
| ############################################################################### |
| $(BUILD_DIR)/$(MODULE)-inliner.cc: $(BUILD_DIR)/$(MODULE)$(GC_ID).bc $(SELF) |
| $(Echo) "Generating inliner $(notdir $@)" |
| $(Verb) doit() { \ |
| echo '#include "vmkit/InlineCommon.h"'; \ |
| echo 'using namespace llvm;'; \ |
| echo 'namespace vmkit {'; \ |
| for F in $(EXTRACT_FUNCTIONS); do \ |
| $(LOPT) $(CPPGEN_FLAGS) $< -o - | $(LLC) $(LLC_FLAGS) -march=cpp -cppgen=function -cppfor=$$F -o - \ |
| | sed -e "s/makeLLVMFunction/makeLLVMFunction_$(MODULE)_$$F/"; [ $$? -ne 0 ] && exit 1; \ |
| done; \ |
| echo "void makeLLVMFunctions_$(MODULE)(Module *mod) {"; \ |
| for F in $(EXTRACT_FUNCTIONS); do \ |
| echo " vmkit::makeLLVMFunction_$(MODULE)_$$F(mod);"; \ |
| done; \ |
| echo "}"; \ |
| echo "}"; \ |
| exit 0; \ |
| }; doit > $@ |
| |
| ############################################################################### |
| # Linking |
| ############################################################################### |
| DEP_LIBS=$(patsubst %,$(LIB_DIR)/lib%.a,$(LINK_USE)) |
| |
| $(BIN_DIR)/$(TOOL)$(EXEEXT): $(MODULE_A) $(DEP_LIBS) $(BUILD_DIR)/frametables.o $(SELF) $(BIN_DIR)/.dir |
| $(Echo) "Linking executable '$(notdir $@)'" |
| $(Verb) $(CLANGXX) -o $@ $(LDFLAGS) $(MODULE_A) $(BUILD_DIR)/frametables.o $(DEP_LIBS) $(DEP_LIBS) $(LIBS) |
| |
| $(LIB_DIR)/$(LIBRARY)$(SHLIBEXT): $(MODULE_A) $(DEP_LIBS) $(SELF) $(LIB_DIR)/.dir |
| $(Echo) "Linking shared library '$(notdir $@)'" |
| $(Verb) $(CLANGXX) -o $@ $(SHOPT) -shared -Wl,--whole-archive $(MODULE_A) -Wl,--no-whole-archive $(DEP_LIBS) |
| |
| ############################################################################### |
| # Frametables |
| ############################################################################### |
| $(BUILD_DIR)/frametables.cc: $(MODULE_A) $(DEP_LIBS) $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Generating frametables of $(notdir $(TOOL))" #$(notdir $(DEP_LIBS))" |
| $(Verb) doit() { \ |
| F="$(MODULE_A) $(DEP_LIBS)"; \ |
| echo '#include "vmkit/MethodInfo.h"'; \ |
| echo 'using namespace vmkit;'; \ |
| $(NM) $$F | grep __frametable | sed 's/\([a-f0-9]*\) \([a-zA-Z]*\) _*\([a-zA-Z0-9_]*\)/extern "C" CompiledFrames \3;/'; \ |
| echo 'CompiledFrames* vmkit::initialFrametables[] = {'; \ |
| $(NM) $$F | grep __frametable | sed 's/\([a-f0-9]*\) \([a-zA-Z]*\) _*\([a-zA-Z0-9_]*\)/\&\3,/'; \ |
| echo "0"; \ |
| echo "};"; \ |
| }; doit > $@ |
| |
| ############################################################################### |
| # vmkit runtime generated files |
| ############################################################################### |
| ifdef VMKIT_RUNTIME_OUT |
| all:: $(BUILD_DIR)/$(VMKIT_RUNTIME_OUT) |
| |
| BUILT_INC+=$(BUILD_DIR)/$(VMKIT_RUNTIME_OUT) |
| |
| $(BUILD_DIR)/$(VMKIT_RUNTIME_OUT): $(VMKIT_RUNTIME_IN) $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Generating '$(notdir $@)'" |
| $(Verb) cat $(VMKIT_RUNTIME_IN) | $(LLVMAS) -o - | $(LLC) $(LLC_FLAGS) -march=cpp -cppgen=contents -o $@ |
| |
| endif |
| |
| ############################################################################### |
| # object rules |
| ############################################################################### |
| %.o: %.bc |
| $(Echo) "Assembling '$(notdir $<)'" |
| $(Verb) $(LLC) $(LLC_FLAGS) $(LLC_GC_FLAGS) -filetype=obj $< -o $@ |
| |
| define define_compile_rule |
| $(BUILD_DIR)/%.bc: %$1 $(BUILT_INC) $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Compiling '$$(notdir $$<)'" |
| $(Verb) if $2 $3 $(DEPEND_OPTIONS) -emit-llvm -c "$$<" -o $$@; $(DOM) |
| |
| $(BUILD_DIR)/%.bc: $(BUILD_DIR)/%$1 $(BUILT_INC) $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Compiling '$$(notdir $$<)'" |
| $(Verb) if $2 $3 $(DEPEND_OPTIONS) -emit-llvm -c "$$<" -o $$@; $(DOM) |
| endef |
| |
| $(eval $(call define_compile_rule,.cpp,$(CLANGXX),$(CXXFLAGS))) |
| $(eval $(call define_compile_rule,.cc,$(CLANGXX),$(CXXFLAGS))) |
| $(eval $(call define_compile_rule,.c,$(CLANG),$(CFLAGS))) |
| |
| ifneq ($(MAKECMDGOALS),tidy) |
| ifneq ($(MAKECMDGOALS),clean) |
| ifneq ($(MAKECMDGOALS),distclean) |
| -include $(addsuffix .d,$(CLANG_FILES)) |
| endif |
| endif |
| endif |