######################################## ########## HOW TO USE ######################################## ######### Clean build # make clean ######### Build evth: both interface to G4 and its tests: # make # (or make all) # (obviously, you can also do: make -j8) ######### Build test executables only # make test ######### Build interface to G4 only # make interface ######### Create environment scripts # make env # (creates env_FLUKA.sh and env_FLUKA_G4_interface.sh) ######### Create env_FLUKA_G4_interface.sh only # make env_FLUKA_G4_interface # (env_FLUKA_G4_interface.sh needs to be sourced before compiling / running any test or G4 application using the FLUKA-G4 interface). ######################################## ########## EXTERNAL DEPENDENCIES ######################################## ######### FLUKA FLUKA_PATH := $(realpath $(shell dirname $(shell which fluka))/..) ifeq ($(wildcard $(FLUKA_PATH)/.*),) $(error "fluka executables not found. FLUKA_REPO=$(FLUKA_PATH). Add your fluka_repo/bin to the PATH." ) endif FLUKA_INCLUDE_DIR := $(FLUKA_PATH)/include ifeq ($(wildcard $(FLUKA_INCLUDE_DIR)/.*),) $(error "FLUKA_INCLUDE_DIR=$(FLUKA_INCLUDE_DIR)/ does not contain any file. Add your fluka_repo/bin to the PATH." ) endif FLUKA_LIB_DIR := $(FLUKA_PATH)/lib ifeq ($(wildcard $(FLUKA_LIB_DIR)/$(FLUKA_LIB)),) $(error "FLUKA_LIB_DIR=$(FLUKA_LIB_DIR)/ does not contain $(FLUKA_LIB). Add your fluka_repo/bin to the PATH." ) endif FLUKA_LIB_NAME := fluka FLUKA_LIB := lib$(FLUKA_LIB_NAME).a FLUKA_NO_RANDOM_LIB_NAME := fluka_no_random FLUKA_NO_RANDOM_LIB := lib$(FLUKA_NO_RANDOM_LIB_NAME).a FLUKA_OBJ_REMOVE := flrm64.o flrndm.o flrnlp.o flrnoc.o FLUKA_RELEASE_LIB_LINK := -L$(FLUKA_LIB_DIR) -l$(FLUKA_LIB_NAME) FLUKA_LIB_LINK := -L$(FLUKA_LIB_DIR) -l$(FLUKA_NO_RANDOM_LIB_NAME) ######### G4 G4_PATH := $(realpath $(shell geant4-config --prefix)) G4_INCLUDE_DIR := $(G4_PATH)/include/Geant4 G4_INCLUDE := -I$(G4_INCLUDE_DIR) G4_CXX_FLAGS := $(shell geant4-config --cflags) G4_LIBRARIES := $(shell geant4-config --libs) ######################################## ########## COMPILER & FLAGS ######################################## ######### C++ compiler and flags CXX_COMP := g++ CXX_FLAGS := $(shell fluka-config --cppflags) ######### Fortran compiler and flags F_COMP := gfortran F_FLAGS := $(shell fluka-config --fflags) ######### Linker flag LD_FLAGS := -lgfortran ######### Check compilers collection version IS_CXX_COMP_GT_7 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 7) ifneq "$(IS_CXX_COMP_GT_7)" "1" $(error "gcc suite version = $(shell gcc -dumpversion). Only versions >= 7 are supported!") endif ######################################## ########## PROJECT DIRECTORIES ######################################## # Base dir BASE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) # Source code SRC_DIR := $(BASE_DIR)/source # Directory where to put object and dependency files OBJ_DIR := $(BASE_DIR)/obj INTERFACE_OBJ_DIR := $(OBJ_DIR)/interface TEST_INTERFACE_TO_G4_OBJ_DIR := $(OBJ_DIR)/test_interface_to_G4 # Directory where to put executables BIN_DIR := $(BASE_DIR)/bin CLEAN_DIR := $(OBJ_DIR) $(BIN_DIR) ######################################## ########## PROJECT FILES ######################################## ######### FORTRAN SOURCE F_SRC_DIR := $(SRC_DIR)/fluka4_wrapper/fortran/procedures \ $(SRC_DIR)/cpp_fortran_bridges/fortran F_INCLUDE := -I$(FLUKA_INCLUDE_DIR) -J$(FLUKA_INCLUDE_DIR) F_SRC := $(foreach src_dir, $(F_SRC_DIR), $(wildcard $(src_dir)/*.f)) F_OBJ := $(addprefix $(OBJ_DIR)/, $(notdir $(F_SRC:.f=.o))) ######### C++ SOURCE CXX_SRC_DIR := $(SRC_DIR)/fluka4_wrapper/cpp/procedures \ $(SRC_DIR)/cpp_fortran_bridges/cpp \ $(SRC_DIR)/cpp_utils CXX_INCLUDE_DIR := $(CXX_SRC_DIR) $(FLUKA_INCLUDE_DIR) CXX_INCLUDE := $(addprefix -I, $(CXX_INCLUDE_DIR)) CXX_SRC := $(foreach src_dir, $(CXX_SRC_DIR), $(wildcard $(src_dir)/*.cc)) CXX_OBJ := $(addprefix $(OBJ_DIR)/, $(notdir $(CXX_SRC:.cc=.o))) ######### INTERFACE TO G4 INTERFACE_SRC_DIR := $(SRC_DIR)/fluka5/hadronic_interactions/interface_to_G4 \ $(SRC_DIR)/fluka_G4_bridges \ $(SRC_DIR)/fluka_G4_physics_list INTERFACE_INCLUDE_DIR := $(INTERFACE_SRC_DIR) INTERFACE_INCLUDE := $(addprefix -I, $(INTERFACE_INCLUDE_DIR)) INTERFACE_SRC := $(foreach src_dir, $(INTERFACE_SRC_DIR), $(wildcard $(src_dir)/*.cc)) INTERFACE_OBJ := $(addprefix $(INTERFACE_OBJ_DIR)/, $(notdir $(INTERFACE_SRC:.cc=.o))) ######### TEST INTERFACE TO G4 (EXECUTABLE) TEST_INTERFACE_TO_G4_SRC_DIR := $(SRC_DIR)/fluka5/hadronic_interactions/test/interface_to_G4 TEST_INTERFACE_TO_G4_SRC := $(foreach src_dir, $(TEST_INTERFACE_TO_G4_SRC_DIR), $(wildcard $(src_dir)/*.cc)) TEST_INTERFACE_TO_G4_INCLUDE_DIR := $(TEST_INTERFACE_TO_G4_SRC_DIR) TEST_INTERFACE_TO_G4_INCLUDE := $(addprefix -I, $(TEST_INTERFACE_TO_G4_INCLUDE_DIR)) TEST_INTERFACE_TO_G4_OBJ := $(addprefix $(TEST_INTERFACE_TO_G4_OBJ_DIR)/, $(notdir $(TEST_INTERFACE_TO_G4_SRC:.cc=.o))) TEST_INTERFACE_TO_G4_EXE := $(BIN_DIR)/test_interface ######################################## ########## TARGETS RULES ######################################## .PHONY: all all: interface test @echo @echo "Full build successfull." .PHONY: test test: test_interface_to_g4 @echo @echo "Full tests build successfull." .PHONY: interface interface: check_G4 $(INTERFACE_OBJ) fluka_no_random_lib @echo @echo "Full FLUKA-G4 interface build successfull." .PHONY: check_G4 check_G4: @[ -d $(G4_PATH) ] || { echo "!!! G4 repo not found. Please source geant4.sh, or G4 setup.sh (need to have G4 already installed). !!!"; exit 1; } @[ -d $(G4_INCLUDE_DIR) ] || { echo "!!! G4_INCLUDE_DIR=$(G4_INCLUDE_DIR)/ does not exist. !!! "; exit 1; } .PHONY: env env: env_FLUKA env_FLUKA_G4_interface @echo @echo "Full env scripts creation successfull." .PHONY: env_FLUKA env_FLUKA: env_FLUKA.sh env_FLUKA.sh: GNUmakefile @echo '#! /bin/bash' > $@ @echo >> $@ @echo 'export FLUKA_PATH=$$(realpath $$(dirname $$(which fluka))/..)' >> $@ @echo 'if [ ! -d "$$FLUKA_PATH" ]; then' >> $@ @echo ' echo "!!! fluka not found. FLUKA_REPO=$$FLUKA_PATH. Add your fluka_repo/bin to the PATH. !!!";' >> $@ @echo 'fi' >> $@ @echo >> $@ @echo 'export FLUKADATA=$$FLUKA_PATH/data' >> $@ @echo 'if [ ! -d "$$FLUKADATA" ]; then' >> $@ @echo ' echo "!!! fluka data repo not found. FLUKADATA=$$FLUKADATA. Add your fluka_repo/bin to the PATH. !!!";' >> $@ @echo 'fi' >> $@ @echo >> $@ @echo 'export FLUKA_LIB_DIR=$$FLUKA_PATH/lib' >> $@ @echo 'if [ ! -d "$$FLUKA_LIB_DIR" ]; then' >> $@ @echo ' echo "!!! fluka lib repo not found. FLUKA_LIB_DIR=$$FLUKA_LIB_DIR. Add your fluka_repo/bin to the PATH. !!!";' >> $@ @echo 'fi' >> $@ @echo @echo "Created file: env_FLUKA.sh" .PHONY: env_FLUKA_G4_interface env_FLUKA_G4_interface: env_FLUKA_G4_interface.sh env_FLUKA_G4_interface.sh: GNUmakefile @echo '#! /bin/bash' > $@ @echo 'echo "source $(BASE_DIR)/env_FLUKA.sh"' >> $@ @echo 'if [ ! -e "$(BASE_DIR)/env_FLUKA.sh" ]; then' >> $@ @echo ' echo "env_FLUKA.sh does not exist. Please create it: go to $(BASE_DIR), and do make env. Then, source again this script."' >> $@ @echo 'else' >> $@ @echo ' source $(BASE_DIR)/env_FLUKA.sh' >> $@ @echo ' echo ""' >> $@ @echo ' echo "Setting FLUKAInterface_INCLUDE_DIR:"' >> $@ @echo ' export FLUKAInterface_INCLUDE_DIR="$(SRC_DIR)/cpp_utils $(INTERFACE_INCLUDE_DIR)"' >> $@ @echo ' echo "export FLUKAInterface_INCLUDE_DIR=$$FLUKAInterface_INCLUDE_DIR"' >> $@ @echo ' echo "FLUKAInterface_INCLUDE_DIR successfully set."' >> $@ @echo ' echo ""' >> $@ @echo ' echo "Setting FLUKAInterface_LIBRARIES:"' >> $@ @echo ' export FLUKAInterface_LIBRARIES="$(INTERFACE_OBJ) $(CXX_OBJ) $(F_OBJ)"' >> $@ @echo ' missing_obj=false;' >> $@ @echo ' for obj in $$FLUKAInterface_LIBRARIES; do' >> $@ @echo ' if [ ! -e "$$obj" ]; then' >> $@ @echo ' echo "$$obj does not exist."' >> $@ @echo ' missing_obj=true' >> $@ @echo ' fi' >> $@ @echo ' done' >> $@ @echo ' if [ "$$missing_obj" = true ]; then' >> $@ @echo ' echo "!!! Object file(s) in FLUKAInterface_LIBRARIES is/are missing. Please (re)compile the G4 interface (make or make interface)!";' >> $@ @echo ' else' >> $@ @echo ' export FLUKAInterface_LIBRARIES="$$FLUKAInterface_LIBRARIES $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB)"' >> $@ @echo ' export FLUKAInterface_LIBRARIES="$$FLUKAInterface_LIBRARIES $(LD_FLAGS)"' >> $@ @echo ' echo "export FLUKAInterface_LIBRARIES=$$FLUKAInterface_LIBRARIES"' >> $@ @echo ' echo "FLUKAInterface_LIBRARIES successfully set."' >> $@ @echo ' fi' >> $@ @echo 'fi' >> $@ @echo 'echo ""' >> $@ @echo "Created file: env_FLUKA_G4_interface.sh" .PHONY: clean clean: rm -fr $(CLEAN_DIR) env_FLUKA_G4_interface.sh ######################################## ########## COMPILE & LINK ######################################## # BUILD TEST INTERFACE TO G4 (EXECUTABLE) .PHONY: test_interface_to_g4 test_interface_to_g4: fluka_no_random_lib $(TEST_INTERFACE_TO_G4_EXE) $(TEST_INTERFACE_TO_G4_EXE): $(TEST_INTERFACE_TO_G4_OBJ) $(INTERFACE_OBJ) $(CXX_OBJ) $(F_OBJ) @[ -d $(@D) ] || mkdir -p $(@D) @echo @echo "Building $(notdir $@) executable to test FLUKA-G4 interface:" $(CXX_COMP) $^ $(FLUKA_LIB_LINK) $(LD_FLAGS) $(G4_LIBRARIES) -o $@ @echo "Built $(notdir $@) successfully." # COMPILE TEST INTERFACE TO G4 SOURCES define TEST_INTERFACE_TO_G4_BUILD_template $(TEST_INTERFACE_TO_G4_OBJ_DIR)/%.o: $(1)/%.cc @echo @echo "Building $$(notdir $$@) to test FLUKA-G4 interface:" @[ -d $$(@D) ] || mkdir -p $$(@D) $(CXX_COMP) -DG4_USE_FLUKA $(G4_CXX_FLAGS) $(CXX_INCLUDE) $(TEST_INTERFACE_TO_G4_INCLUDE) $(INTERFACE_INCLUDE) -c $$< -o $$@ @echo "Built $$(notdir $$@) successfully." endef $(foreach src_dir, $(TEST_INTERFACE_TO_G4_SRC_DIR), $(eval $(call TEST_INTERFACE_TO_G4_BUILD_template, $(src_dir)))) # COMPILE INTERFACE SOURCES define INTERFACE_BUILD_template $(INTERFACE_OBJ_DIR)/%.o: $(1)/%.cc $(CXX_OBJ) $(F_OBJ) @echo @echo "Building $$(notdir $$@) for FLUKA-G4 interface:" @[ -d $$(@D) ] || mkdir -p $$(@D) $(CXX_COMP) -DG4_USE_FLUKA $(G4_CXX_FLAGS) $(CXX_INCLUDE) $(INTERFACE_INCLUDE) -c $$< -o $$@ @echo "Built $$(notdir $$@) successfully." endef $(foreach src_dir, $(INTERFACE_SRC_DIR), $(eval $(call INTERFACE_BUILD_template, $(src_dir)))) # COMPILE CPP SOURCE define CXX_BUILD_template $(OBJ_DIR)/%.o: $(1)/%.cc @echo @echo "Building $$(notdir $$@) for core FLUKA5 C++ source:" @[ -d $$(@D) ] || mkdir -p $$(@D) $(CXX_COMP) -DG4_USE_FLUKA $(CXX_FLAGS) -c $$< -o $$@ @echo "Built $$(notdir $$@) successfully." endef $(foreach src_dir, $(CXX_SRC_DIR), $(eval $(call CXX_BUILD_template, $(src_dir)))) # COMPILE FORTRAN SOURCE define F_BUILD_template $(OBJ_DIR)/%.o: $(1)/%.f @echo @echo "Building $$(notdir $$@) for core FLUKA5 FORTRAN source:" @[ -d $$(@D) ] || mkdir -p $$(@D) $(F_COMP) -DG4_USE_FLUKA $(F_FLAGS) $(F_INCLUDE) -c $$< -o $$@ @echo "Built $$(notdir $$@) successfully." endef $(foreach src_dir, $(F_SRC_DIR), $(eval $(call F_BUILD_template, $(src_dir)))) ######################################## ########## FLUKA4 WAS UPDATED ######################################## .PHONY: fluka fluka: fluka_no_random_lib .PHONY: fluka_no_random_lib fluka_no_random_lib: $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB) $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB): $(FLUKA_LIB_DIR)/$(FLUKA_LIB) @echo @cp $(FLUKA_LIB_DIR)/$(FLUKA_LIB) $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB) @echo "cp $(FLUKA_LIB_DIR)/$(FLUKA_LIB) $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB)" $(foreach obj,$(FLUKA_OBJ_REMOVE),ar d $(FLUKA_LIB_DIR)/$(FLUKA_NO_RANDOM_LIB) $(obj);) @echo "$(FLUKA_NO_RANDOM_LIB) creation / update successfull."