| |
| -include $(LEVEL)/Makefile.config |
| |
| ############################################################################### |
| # Configuration |
| ############################################################################### |
| PROJ_OBJ_CWD:= $(call realpath, .) |
| PROJ_SRC_CWD:= $(call realpath, $(patsubst $(PROJ_OBJ_ROOT)%,$(PROJ_SRC_ROOT)%,$(PROJ_OBJ_CWD))) |
| |
| ifndef BUILD_NAME |
| BUILD_NAME=fake |
| endif |
| |
| BUILD_DIR=$(PROJ_OBJ_CWD)/$(BUILD_NAME) |
| BIN_DIR=$(PROJ_OBJ_ROOT)/$(BUILD_NAME)/bin |
| LIB_DIR=$(PROJ_OBJ_ROOT)/$(BUILD_NAME)/lib |
| |
| ############################################################################### |
| # Nice printing |
| ############################################################################### |
| ifndef PROF |
| PROF=. |
| endif |
| |
| EchoMsg="[$(MAKECMDGOALS) $(PROF)]:" |
| Echo=@echo $(EchoMsg) |
| |
| ifndef VERBOSE |
| SUB_OPT=--no-print-directory -s |
| Verb:=@ |
| endif |
| |
| ############################################################################### |
| # Compilation flags |
| ############################################################################### |
| COMMON_FLAGS:=-Wall -Wno-return-type-c-linkage -Wno-varargs -Wno-unused-private-field -Werror -Wno-unused-variable \ |
| -I$(PROJ_SRC_ROOT)/include -I$(OPENJDK_HOME)/include -I$(OPENJDK_HOME)/include/$(OS) $(COMMON_FLAGS) |
| |
| ifeq ($(OPTIMIZED),1) |
| COMMON_FLAGS+=-O3 |
| LLCFLAGS+=-O=3 |
| else |
| COMMON_FLAGS+=-O0 |
| LLCFLAGS+=-O=0 |
| endif |
| |
| ifneq ($(DEBUG),0) |
| COMMON_FLAGS+=-g |
| endif |
| |
| #LLCFLAGS+=-disable-cfi -disable-fp-elim -relocation-model=pic |
| #OPTFLAGS+=-disable-cfi -disable-fp-elim -disable-opt |
| |
| LLCFLAGS+=-relocation-model=pic |
| OPTFLAGS+=-disable-opt |
| |
| CXXFLAGS=$(LLVM_CXXFLAGS) $(COMMON_FLAGS) -std=gnu++98 -fPIC |
| SHFLAGS=-lpthread -ldl -lz -lncurses -framework CoreFoundation -fno-common -Wl,-flat_namespace -Wl,-undefined,suppress |
| |
| ############################################################################### |
| # Targets |
| ############################################################################### |
| .PHONY: all all-parallel-recursive clean clean-parallel-recursive clean-local tidy confclean check |
| .SECONDARY: |
| .SUFFIXES: |
| |
| ############################################################################### |
| # Recursive target managment |
| ############################################################################### |
| RECURSIVE_TARGETS=all clean |
| |
| define do_parallel_subdirs |
| $1-parallel-recursive:: |
| #$(Echo) "Entering directory $$(PROF)/$2" |
| $(Verb) +$(MAKE) $(SUB_OPT) -C $2 $1 PROF=$(PROF)/$2 VERBOSE=$(VERBOSE); \ |
| if [ $$$$? != 0 ]; then echo "$$(EchoMsg) abort with errors in $$(PROF)/$2"; exit 1; fi |
| endef |
| |
| define do_recursive_target |
| $1: |
| $(Verb) for f in $$(DIRS); do \ |
| $(MAKE) $(SUB_OPT) -C $$$$f $1 PROF=$(PROF)/$$$$f VERBOSE=$(VERBOSE); \ |
| if [ $$$$? != 0 ]; then echo "$$(EchoMsg) abort with errors in $$(PROF)/$$$$f"; exit 1; fi; \ |
| done |
| $(Verb) +$(MAKE) $(SUB_OPT) $1-parallel-recursive VERBOSE=$(VERBOSE) |
| |
| $1-parallel-recursive:: |
| $(Verb) +$(MAKE) $(SUB_OPT) $1-local VERBOSE=$(VERBOSE) |
| |
| $1-local:: |
| |
| $$(foreach dir,$$(PARALLEL_DIRS),$$(eval $$(call do_parallel_subdirs,$1,$$(dir)))) |
| endef |
| |
| $(foreach target,$(RECURSIVE_TARGETS),$(eval $(call do_recursive_target,$(target)))) |
| |
| tidy: |
| $(Echo) "Cleaning temporary files" |
| $(Verb) find $(PROJ_OBJ_ROOT) \( -iname "*~" -o -iname "\#*" \) -exec rm -f {} \; |
| |
| clean-local:: |
| $(Echo) "Cleaning compilation files" |
| $(Verb) rm -Rf $(BUILD_DIR) |
| |
| confclean: clean |
| $(Echo) "Cleaning configuration" |
| $(Verb) rm -Rf $(patsubst $(PROJ_OBJ_ROOT)/%,%,$(CONFIG_FILES)) |
| $(Verb) rm -Rf $(patsubst $(PROJ_OBJ_ROOT)/%,%,$(CONFIG_HEADERS)) |
| $(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 |
| |
| check:: |
| $(Echo) "---- building with: " |
| $(Echo) " PROJ_SRC_ROOT: $(PROJ_SRC_ROOT)" |
| $(Echo) " PROJ_OBJ_ROOT: $(PROJ_OBJ_ROOT)" |
| $(Echo) " SHFLAGS: $(SHFLAGS)" |
| $(Echo) " EXEEXT: $(EXEEXT)" |
| $(Echo) " SHLIBEXT: $(SHLIBEXT)" |
| $(Echo) " OPTIMIZED: $(OPTIMIZED)" |
| $(Echo) " DEBUG: $(DEBUG)" |
| $(Echo) " ASSERT: $(ASSERT)" |
| $(Echo) " CONFIG_FILES: $(CONFIG_FILES)" |
| $(Echo) " CONFIG_HEADERS: $(CONFIG_HEADERS)" |
| $(Echo) " BUILD_NAME: $(BUILD_NAME)" |
| $(Echo) " CLANG: $(CLANG)" |
| $(Echo) " CLANGXX: $(CLANGXX)" |
| $(Echo) " LLC: $(LLC)" |
| $(Echo) " LOPT: $(LOPT)" |
| |
| ############################################################################### |
| # Build system managment |
| ############################################################################### |
| SELF=$(PROJ_SRC_ROOT)/Makefile.rules $(PROJ_OBJ_ROOT)/Makefile.config $(PROJ_SRC_CWD)/Makefile |
| |
| $(PROJ_SRC_ROOT)/configure: $(PROJ_SRC_ROOT)/autoconf/configure.ac |
| $(Echo) "Rebootstraping project" |
| $(Verb) cd $(PROJ_SRC_ROOT)/autoconf && autoconf -o $@ $< && touch $@ |
| $(Verb) cd $(PROJ_OBJ_ROOT) && ./config.status --recheck |
| |
| define define_config_rule |
| $$(LEVEL)/$1 $$(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 && touch $$@ |
| endef |
| |
| $(foreach cur,$(CONFIG_FILES),$(eval $(call define_config_rule,$(cur),file))) |
| $(foreach cur,$(CONFIG_HEADERS),$(eval $(call define_config_rule,$(cur),header))) |
| |
| |
| ############################################################################### |
| # Find sources |
| ############################################################################### |
| define find-sources |
| $(basename $(notdir $(wildcard $(PROJ_SRC_CWD)/*$1))) |
| endef |
| |
| ifndef BASE_OBJ_FILES |
| BASE_OBJ_FILES=$(call find-sources,.cc) |
| endif |
| BC_FILES+=$(addsuffix .bc,$(addprefix $(BUILD_DIR)/,$(BASE_OBJ_FILES))) |
| OBJ_FILES+=$(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(BASE_OBJ_FILES) $(basename $(notdir $(wildcard $(PROJ_SRC_CWD)/*.s))))) |
| DEP_FILES=$(addsuffix .d,$(addprefix $(BUILD_DIR)/,$(BASE_OBJ_FILES))) |
| |
| check:: |
| $(Echo) " BC_FILES: $(BC_FILES)" |
| $(Echo) " DEP_FILES: $(DEP_FILES)" |
| |
| ############################################################################### |
| # Module |
| ############################################################################### |
| ifdef MODULE |
| |
| GEN_MODULE=$(LIB_DIR)/$(MODULE) |
| |
| all-local:: $(LIB_DIR)/.dir $(GEN_MODULE).a $(GEN_MODULE).bc |
| |
| # not used for the moment |
| ifdef __EXTRACT__ |
| |
| EXTRACT_NAME=$(BUILD_DIR)/$(MODULE)-llvm-functions |
| TABLE_NAME=$(BUILD_DIR)/$(MODULE).table |
| STRIP_NAME=$(BUILD_DIR)/$(MODULE).strip |
| |
| OBJ_FILES+=$(EXTRACT_NAME).o |
| |
| $(EXTRACT_NAME).cc: $(STRIP_NAME).bc $(TABLE_NAME) $(SELF) |
| $(Echo) "Extracting llvm runtime functions into '$(notdir $@)'" |
| $(Verb) doit() { \ |
| echo '#include "llvm/IR/Module.h"'; \ |
| echo '#include "llvm/IR/Constants.h"'; \ |
| echo '#include "llvm/IR/Instructions.h"'; \ |
| echo '#include "j3/j3classloader.h"'; \ |
| echo 'using namespace llvm;'; \ |
| set -o pipefail; \ |
| for f in $(EXTRACT); do \ |
| mangled=`cat $(TABLE_NAME) | grep -F "$$f" | gawk -F'@' '{ print $$2 }' | tail -n 1`; \ |
| $(LLC) $< -march=cpp -cppgen=function -cppfor="$$mangled" -o - \ |
| | sed -e "s/makeLLVMFunction/makeLLVMFunction_$(MODULE)_$$mangled/" \ |
| | sed -e "s/\\x22//"; \ |
| if [ "$$?" != 0 ]; then \ |
| echo "Unable to find: $$f" >&2; \ |
| exit 1; \ |
| fi; \ |
| done; \ |
| for f in $(EXTRACT_TYPE); do \ |
| $(LLC) $< -march=cpp -cppgen=type -cppfor="$$f" -o - \ |
| | sed -e "s/makeLLVMType/makeLLVMType_$(MODULE)_`echo $$f | sed -e 's/\./_/' | sed -e 's/::/_/'`/" \ |
| | sed -e "s/\\x22//" \ |
| ; \ |
| done; \ |
| echo "void j3::J3InitialClassLoader::makeLLVMFunctions_$(MODULE)() {"; \ |
| for f in $(EXTRACT); do \ |
| mangled=`cat $(TABLE_NAME) | grep -F "$$f" | gawk -F'@' '{ print $$2 }' | tail -n 1`; \ |
| unmangled=`cat $(TABLE_NAME) | grep -F "$$f" | gawk -F'@' '{ print $$1 }' | tail -n 1`; \ |
| echo " makeLLVMFunction_$(MODULE)_$$mangled(module());"; \ |
| echo " registerCMangling(\"$$mangled\", \"$$unmangled\");"; \ |
| done; \ |
| for f in $(EXTRACT_TYPE); do \ |
| echo " makeLLVMType_$(MODULE)_`echo $$f | sed -e 's/\./_/' | sed -e 's/::/_/'`(module());"; \ |
| done; \ |
| echo "}"; \ |
| }; doit > $@ |
| |
| $(STRIP_NAME).bc: $(GEN_MODULE).bc |
| $(Echo) "Strip debug info from '$(notdir $<)'" |
| $(Verb) $(LLOPT) -strip-debug $< -o $@ |
| |
| $(TABLE_NAME): $(GEN_MODULE).bc |
| $(Echo) "Demangling '$(notdir $<)' in '$(notdir $@)'" |
| $(Verb) $(LLNM) --defined-only $< | tr -s ' ' | $(GAWK) -F' ' '{ print $$2 }' | \ |
| tee $(TABLE_NAME).mangled | c++filt -n > $(TABLE_NAME).demangled |
| $(Verb) $(GAWK) '{ d=$$0; getline < "'"$(TABLE_NAME).mangled"'"; m=$$0; printf("%s@%s\n", d, m); }' \ |
| < $(TABLE_NAME).demangled > $@ |
| |
| endif |
| |
| endif |
| |
| ############################################################################### |
| # Tool |
| ############################################################################### |
| ifdef TOOL |
| TOOL_OUT=$(BIN_DIR)/$(TOOL)$(EXEEXT) |
| |
| FINAL_MODULE=$(LIB_DIR)/libjvm |
| STRIP_MODULE=$(BUILD_DIR)/libjvm |
| GEN_MODULE=$(BUILD_DIR)/libjvm-no-strip |
| SONAME=$(FINAL_MODULE) |
| |
| BC_FILES+=$(addsuffix .bc,$(addprefix $(LIB_DIR)/,$(LIBS))) |
| SO_FILES=$(addsuffix .a,$(addprefix $(LIB_DIR)/,$(LIBS))) |
| SO_LIBS=$(LLVM_LIBS) |
| |
| TOOL_ALL=$(BIN_DIR)/.dir $(TOOL_OUT) |
| TOOL_DEP=$(OBJ_FILES) |
| |
| ifdef WITH_DYLIB |
| TOOL_ALL+=$(FINAL_MODULE).bc |
| TOOL_DEP+=$(SONAME)$(SHLIBEXT) |
| else |
| TOOL_DEP+=$(SO_FILES) |
| TOOL_FLAGS=$(LLVM_LDFLAGS) $(SHFLAGS) |
| LDFLAGS=$(SO_LIBS) |
| endif |
| |
| all-local:: $(TOOL_ALL) |
| |
| $(TOOL_OUT): $(TOOL_DEP) |
| $(Echo) "Linking '$(notdir $@)'" |
| $(Verb) $(CLANGXX) $(TOOL_FLAGS) -o $@ -Wl,-rpath,$(LIB_DIR) $(LDFLAGS) $^ |
| |
| $(FINAL_MODULE).bc: $(STRIP_MODULE).bc $(BIN_DIR)/vmkit-extract $(PROJ_SRC_ROOT)/$(EXTRACTOR) |
| $(Echo) "Extracting runtime function to '$(notdir $@)'" |
| $(Verb) $(BIN_DIR)/vmkit-extract $< $(PROJ_SRC_ROOT)/$(EXTRACTOR) > $@ |
| |
| $(STRIP_MODULE).bc: $(GEN_MODULE).bc |
| $(Echo) "Strip debug info from '$(notdir $<)'" |
| $(Verb) $(LLOPT) -strip-debug $< -o $@ |
| |
| endif |
| |
| ############################################################################### |
| # Library |
| ############################################################################### |
| ifdef LIBRARY |
| SONAME=$(LIB_DIR)/$(LIBRARY) |
| all-local:: $(LIB_DIR)/.dir $(SONAME)$(SHLIBEXT) |
| |
| SO_FILES=$(OBJ_FILES) |
| |
| endif |
| |
| ############################################################################### |
| # Prepare the code |
| ############################################################################### |
| ifndef NO_PREPARE_CODE |
| DO_PREPARE_CODE_LIB=$(LIB_DIR)/vmkit-prepare-code$(SHLIBEXT) |
| DO_PREPARE_CODE=-load=$(DO_PREPARE_CODE_LIB) -VMKitAdaptLinkage |
| RAW=-raw |
| |
| %.bc: %$(RAW).bc $(DO_PREPARE_CODE_LIB) |
| $(Echo) "Prepare code for vmkit '$(notdir $@)'" |
| $(Verb) $(LLOPT) $(DO_PREPARE_CODE) $(OPTFLAGS) $< -o $@ |
| |
| endif |
| |
| ############################################################################### |
| # Compilation |
| ############################################################################### |
| DEPEND_OPTIONS=-MMD -MP -MF "$(BUILD_DIR)/$$*.d.tmp" -MT "$(BUILD_DIR)/$$*$(RAW).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 |
| |
| $(SONAME)$(SHLIBEXT): $(SO_FILES) |
| $(Echo) "Linking shared library '$(notdir $@)'" |
| $(Verb) $(CLANGXX) -shared $(LLVM_LDFLAGS) $(SHFLAGS) -o $@ $(SHALL) $^ $(SHNOALL) $(SO_LIBS) |
| |
| $(GEN_MODULE).bc: $(BC_FILES) |
| $(Echo) "Linking bc module '$(notdir $@)'" |
| $(Verb) $(LLLINK) $^ -o $@ |
| |
| $(GEN_MODULE).a: $(OBJ_FILES) |
| $(Echo) "Linking module '$(notdir $@)'" |
| $(Verb) ar cru $@ $^ && ranlib $@ |
| |
| %.o: %.bc |
| $(Echo) "Assembling '$(notdir $<)'" |
| $(Verb) $(LLC) $(LLCFLAGS) -filetype=obj -o $@ $< |
| |
| $(BUILD_DIR)/%.o: %.s $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Assembling '$(notdir $<)'" |
| $(Verb) if $(CLANGXX) $(CXXFLAGS) $(DEPEND_OPTIONS) -c "$<" -o $@; $(DOM) |
| |
| define define_compile_rule |
| $(BUILD_DIR)/%$(RAW).bc: $4%$1 $(SELF) $(BUILD_DIR)/.dir |
| $(Echo) "Compiling '$$(notdir $$<)'" |
| $(Verb) if $2 $3 $(DEPEND_OPTIONS) -emit-llvm -c "$$<" -o $$@; $(DOM) |
| endef |
| |
| $(eval $(call define_compile_rule,.cc,$(CLANGXX),$(CXXFLAGS),)) |
| $(eval $(call define_compile_rule,.cc,$(CLANGXX),$(CXXFLAGS),$(BUILD_DIR)/)) |
| |
| %/.dir: |
| $(Verb) mkdir -p $(dir $@) && touch $@ |
| |
| ifneq ($(MAKECMDGOALS),tidy) |
| ifneq ($(MAKECMDGOALS),clean) |
| ifneq ($(MAKECMDGOALS),confclean) |
| -include $(DEP_FILES) |
| endif |
| endif |
| endif |