MPICHDIR     = /usr
MPICHARMDIR  = /home/pi/prg/MPICH.32
LIBDIR       = ../lib
INCDIR       = ../include
##########################################################
# DEFINES and INCLUDES can be brought in from the environment
# if desired
DEFINES      ?=
INCLUDES     ?=
MK_DEFINES   = $(DEFINES)
DEFAULT_INCLUDES = -I $(INCDIR)
MK_INCLUDES  = $(DEFAULT_INCLUDES) $(INCLUDES)

##########################################################
# CFLAGS and CPPFLAGS are set if not brought in from the environment
# using ?= conditional variable definition

CC          = $(MPICHDIR)/bin/mpicc
ARMCC       = $(MPICHARMDIR)/bin/mpicc
CCC         = $(MPICHDIR)/bin/mpic++
ARMCCC      = $(MPICHARMDIR)/bin/mpic++
CFLAGS      ?= -std=c11 -Wall
ARMCFLAGS   = -march=armv8-a -mtune=cortex-a53
IA64CFLAGS  = -march=native -m64
#CPPFLAGS    ?= -pipe -O2 -ffast-math -D_REENTRANT \
               -Wall -Wno-long-long -Wno-non-template-friend \
	       -fexceptions -fno-strict-aliasing \
	       -fomit-frame-pointer -fPIC \

CFGPARSEFLAGS = -D _MAIN_
COMPILE     = $(CC) -c $(MK_DEFINES) $(MK_INCLUDES) $(CPPFLAGS) $(CFLAGS)
COMPILE_ARM = $(ARMCC) -c $(MK_DEFINES) $(MK_INCLUDES) $(CPPFLAGS) $(CFLAGS) $(ARMCFLAGS)
COMPILE_IA64 = $(COMPILE) $(IA64CFLAGS)
LDFLAGS     = -L$(LIBDIR)

LIBS        = -lmpi

LINK        = $(CC) $(CFLAGS) $(LDFLAGS)
LINK_ARM    = $(ARMCC) $(CFLAGS) $(LDFLAGS)
##########################################################

MPI_EX_MONO = MPI_Example_1
MPI_EX_DISTR = MPI_Example_2
MPI_EX_SPAWN = MPI_Example_3
MPI_EX_CFGPARSE = MPIexec_Config_Parse

MPI_EX_MONO_SOURCES = MPI_Ex_Monolithic.c
MPI_EX_SPAWN_SOURCES = MPI_Ex_Spawn.c
MPI_EX_SPAWN_DISTR_M_SRCS = MPI_Ex_0.c
MPI_EX_SPAWN_DISTR_S_SRCS = MPI_Ex_1.c MPI_Ex_2.c
MPI_EX_DISTR_SOURCES = $(MPI_EX_SPAWN_DISTR_M_SRCS) $(MPI_EX_SPAWN_DISTR_S_SRCS) MPI_Common.c
# MPI_EX_SPAWN_DISTR_SOURCES = MPI_Ex_0.c MPI_Ex_1.c MPI_Ex_2.c MPI_Common.c
MPI_EX_COMMON_SOURCES = MPI_Common.c
MPI_EX_CFGPARSE_SOURCES = MPIexec_Config_Parse.c
MPI_EX_IA64_SOURCES = $(MPI_EX_CFGPARSE_SOURCES) $(MPI_EX_SPAWN_DISTR_M_SRCS)
MPI_EX_ARM_SOURCES = $(MPI_EX_SPAWN_DISTR_S_SRCS)
MPI_EX_SPAWN_DISTR_SOURCES = $(MPI_EX_ARM_SOURCES) $(MPI_EX_IA64_SOURCES)

MPI_EX_MONO_OBJECTS = $(MPI_EX_MONO_SOURCES:.c=.o)
MPI_EX_DISTR_OBJECTS = $(MPI_EX_DISTR_SOURCES:.c=.o)
MPI_EX_SPAWN_OBJECTS = $(MPI_EX_SPAWN_SOURCES:.c=.o)
MPI_EX_COM_ARM_OBJS = $(MPI_EX_COMMON_SOURCES:.c=_a.o)
MPI_EX_COM_IA64_OBJS = $(MPI_EX_COMMON_SOURCES:.c=_i.o)
MPI_EX_SPAWN_DISTR_OBJECTS = $(MPI_EX_SPAWN_DISTR_SOURCES:.c=.o) $(MPI_EX_COM_IA64_OBJS) $(MPI_EX_COM_ARM_OBJS)
MPI_EX_CFGPARSE_OBJECTS = $(MPI_EX_CFGPARSE_SOURCES:.c=.o)
MPI_EX_ARM_OBJECTS = $(MPI_EX_ARM_SOURCES:.c=.o) 
MPI_EX_IA64_OBJECTS = $(MPI_EX_IA64_SOURCES:.c=.o) 

IA64_RANKS = _0
ARM_RANKS = _1 _2
RANKS = $(IA64_RANKS) $(ARM_RANKS)
MPI_EX_DISTR_TARGETS =  $(foreach RANK, $(RANKS), $(MPI_EX_DISTR)$(RANK))
MPI_EX_SPAWN_IA64_TARGETS = $(foreach RANK, $(IA64_RANKS), $(MPI_EX_SPAWN)$(RANK))
MPI_EX_SPAWN_ARM_TARGETS = $(foreach RANK, $(ARM_RANKS), $(MPI_EX_SPAWN)$(RANK))
MPI_EX_SPAWN_DISTR_TARGETS =  $(MPI_EX_SPAWN_IA64_TARGETS) $(MPI_EX_SPAWN_ARM_TARGETS)
MPI_EX_SPAWN_TGT = MPI_ex_spawn_distr

##########################################################
# stupid make does not know .cpp suffix by default
.SUFFIXES: .cpp
.cpp.o: %.cpp
	$(CCC) $(CPPFLAGS) $(OUTPUT_OPTION) -c $<
##########################################################

# the next 2 replace the more general pattern rule
%.o: %.c
	$(COMPILE) $<

$(MPI_EX_ARM_OBJECTS): %.o: %.c
	$(COMPILE_ARM) $<

$(MPI_EX_IA64_OBJECTS): %.o: %.c
	$(COMPILE_IA64) $<

$(MPI_EX_COM_ARM_OBJS): %_a.o: %.c
	$(COMPILE_ARM) -o $@ $<

$(MPI_EX_COM_IA64_OBJS): %_i.o: %.c
	$(COMPILE_IA64) -o $@ $<

cfg_parse_flags: 
#APPFLAGS = $(CFGPARSEFLAGS)

# build test application (MPI)

all: MPI_ex_mono MPI_ex_distr MPI_ex_spawn

MPI_ex_mono_objects: $(MPI_EX_MONO_OBJECTS)

MPI_ex_distr_objects: $(MPI_EX_DISTR_OBJECTS)

MPI_ex_spawn_objects: $(MPI_EX_SPAWN_OBJECTS)

MPI_ex_spawn_distr_objs: $(MPI_EX_SPAWN_DISTR_OBJECTS)

MPI_ex_cfgparse_objects: $(MPI_EX_CFGPARSE_OBJECTS)

MPI_ex_mono: MPI_ex_mono_objects
	$(LINK) -o $(MPI_EX_MONO) $(MPI_EX_MONO_OBJECTS) $(LIBS)

MPI_ex_distr: $(MPI_EX_DISTR_TARGETS)

$(MPI_EX_DISTR)_% : MPI_Ex_%.o MPI_Common.o 
	$(LINK) -o $@ $^ $(LIBS)

MPI_ex_spawn: $(MPI_EX_SPAWN_TGT)

MPI_ex_spawn_mono: MPI_ex_spawn_objects
	$(LINK) -o $(MPI_EX_SPAWN) $(MPI_EX_SPAWN_OBJECTS) $(LIBS)

MPI_ex_spawn_distr: $(MPI_EX_SPAWN_DISTR_TARGETS)

$(MPI_EX_SPAWN_IA64_TARGETS): $(MPI_EX_SPAWN)_%: MPI_Ex_%.o MPI_Common_i.o MPIexec_Config_Parse.o
	$(LINK) $(IA64CFLAGS) -o $@ $^ $(LIBS)

$(MPI_EX_SPAWN_ARM_TARGETS): $(MPI_EX_SPAWN)_%: MPI_Ex_%.o MPI_Common_a.o 
	$(LINK_ARM) $(ARMCFLAGS) -o $@ $^ $(LIBS)

$(MPI_EX_SPAWN)_% : MPI_Ex_%.o MPI_Common.o MPIexec_Config_Parse.o
	$(LINK) -o $@ $^ $(LIBS)

MPI_ex_cfgparse: cfg_parse_flags MPI_ex_cfgparse_objects
	$(LINK) -o $(MPI_EX_CFGPARSE) $(MPI_EX_CFGPARSE_OBJECTS) $(LIBS)

clean:
	rm -rf $(MPI_EX_MONO_OBJECTS) $(MPI_EX_DISTR_OBJECTS) $(MPI_EX_SPAWN_OBJECTS) $(MPI_EX_SPAWN_DISTR_OBJECTS) $(MPI_EX_CFGPARSE_OBJECTS) $(MPI_EX_MONO) $(MPI_EX_DISTR_TARGETS) $(MPI_EX_SPAWN_DISTR_TARGETS) $(MPI_EX_CFGPARSE)

