makefile-compiling-back-and-forth - follow up - makefile

In continuation with my earlier question
Makefile - compiling back and forth
I made an attempt in creating a single Makefile. The two subdirectories are HAM-src and GFS-src. However, I am still unable to build it. I paste my Makefile below:
export
SHELL = /bin/sh
top_srcdir=./Temp
objdir=$(top_srcdir)/obj
bindir=${exec_prefix}/bin
cfssrcdir=${top_srcdir}/GFS-src
hamsrcdir=${top_srcdir}/HAM-src
incdir=${top_srcdir}/include
exec=${bindir}/esm_gfs-ham_v0
PROG=$(exec)
LDR = mpxlf90_r -qsmp=noauto
FFLAG90 = $(OPTS90) $(FINCS) -qfree=f90 -NS2048 -qmoddir=$(objdir) -I$(objdir)
FFLAGM = -NS2048 -qfixed -qmoddir=$(objdir) -I$(objdir)
F77 = mpxlf95
F90 = mpxlf95
F90_x = xlf90_r
F90_r = mpxlf95_r
SRCHAM = $(hamsrcdir)/ham_control.f90 $(hamsrcdir)/mo_filename.f90 \
$(hamsrcdir)/ham_namelist.f90 $(hamsrcdir)/ham_submodel.f90 \
$(hamsrcdir)/ham_submodel_diag.f90 $(hamsrcdir)/ham_ham.f90
SRCGFS_MOD=$(cfssrcdir)/machine.f $(cfssrcdir)/resol_def.f \
$(cfssrcdir)/omegas.f $(cfssrcdir)/cnvcld_v.f
OBJGFS_MOD = $(patsubst $(cfssrcdir)/%.f,$(objdir)/%.o,$(SRCGFS_MOD))
OBJHAM = $(patsubst $(hamsrcdir)/%.f90,$(objdir)/%.o,$(SRCHAM))
.SUFFIXES: $(SUFFIXES) .f90 .f .o
all: $(PROG)
$(PROG): $(OBJHAM) $(OBJGFS_MOD)
$(LDR) $(CFS_LDFLAGS) -o $# $(OBJGFS_MOD) $(OBJHAM) $(CFS_LIBS) -L$(LDFLAGS)
$(objdir)/%.o: $(cfssrcdir)/%.f
$(F77) $(FFLAGS) -c $< -o $#
$(objdir)/%.o: $(hamsrcdir)/%.f90
$(F90_r) $(F90FLAGS) -c $< -o $#
########## dependencies for $(hamsrcdir) ###########
ham_filename.o: ham_control.o
ham_namelist.o: ham_control.o ham_filename.o
ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
ham_submodel_diag.o: ham_submodel.o
########## dependencies for $(cfssrcdir) ###########
$(objdir)/omegas.o: $(cfssrcdir)/omegas.f
$(F77) $(FFLAGM) -c $(cfssrcdir)/omegas.f -o $#
$(objdir)/cnvcld_v.o: $(cfssrcdir)/cnvcld_v.f
$(F77) $(FFLAGM) -c $(cfssrcdir)/cnvcld_v.f -o $#
The error:
mpxlf95_r -q64 -O3 -qstrict -qMAXMEM=-1 -qarch=auto -qtune=auto -qcache=auto -qfloat=fltint -qsuffix=cpp=f90 -lessl_r -lmass -lmassv -I./Temp/include -I./Temp/HAM-src -qmoddir=./Temp/obj -I./Temp/obj -c ./Temp/HAM-src/ham_namelist.f90 -o ./Temp/obj/ham_namelist.o
** ham_namelist === End of Compilation 1 ===
1501-510 Compilation successful for file ham_namelist.f90.
mpxlf95_r -q64 -O3 -qstrict -qMAXMEM=-1 -qarch=auto -qtune=auto -qcache=auto -qfloat=fltint -qsuffix=cpp=f90 -lessl_r -lmass -lmassv -I./Temp/include -./Temp/HAM-src -qmoddir=./Temp/obj -I./Temp/obj -c ./Temp/HAM-src/ham_submodel.f90 -o ./Temp/obj/ham_submodel.o
"./Temp/HAM-src/ham_submodel.f90", line 425.7: 1514-219 (S) Unable to access module symbol file for module resol_def. Check path and file permissions of file. Use association not done for this module.
1501-511 Compilation failed for file ham_submodel.f90.
gmake: *** [/gpfs1/home/cccrmod/ham_expt_dec11/regrid_test/CFS-HAM/SORC_CFS-HAM/Temp/obj/ham_submodel.o] Error 1
Why makefile does not compile the resol_def.f module on encountering the dependency?
Another issue - my makefile is not working properly. It goes in a sequence in which the sources are defined.

This is difficult to untangle (a minimal, complete example really would help), but I'd suggest you change this
ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
to this
$(objdir)/ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
and see if that solves the first problem. I don't understand the last line of your question ("Another issue...").

Related

How to change the Makefile to create object file?

I am following a code from GitHub (https://github.com/dmalhotra/pvfmm).
There is a Fortran file in ./examples/src/example-f.f90. I have created a subroutine from this example-f.f90 so that I can make an object file out of it and can call this subroutine in our in-house code. The installation guide is given here (https://github.com/dmalhotra/pvfmm/blob/develop/INSTALL).
The Makefile to compile the example-f.f90 is as (https://github.com/dmalhotra/pvfmm/blob/develop/examples/Makefile):
ifndef PVFMM_DIR
PVFMM_DIR=./..
endif
-include $(PVFMM_DIR)/MakeVariables
ifndef CXX_PVFMM
$(error Cannot find file: MakeVariables)
endif
# FC=$(FC_PVFMM) # TODO: for now, FC must be provided by user
# CC=$(CC_PVFMM) # TODO: for now, CC must be provided by user
CXX=$(CXX_PVFMM)
CXXFLAGS=$(CXXFLAGS_PVFMM)
LDLIBS=$(LDLIBS_PVFMM)
RM = rm -f
MKDIRS = mkdir -p
BINDIR = ./bin
SRCDIR = ./src
OBJDIR = ./obj
INCDIR = ./include
TARGET_BIN = \
$(BINDIR)/example1 \
$(BINDIR)/example2 \
$(BINDIR)/example-sctl \
$(BINDIR)/fmm_pts \
$(BINDIR)/fmm_cheb
all : $(TARGET_BIN)
$(BINDIR)/%: $(SRCDIR)/%.f90
-#$(MKDIRS) $(dir $#)
$(PVFMM_DIR)/libtool --mode=link --tag=FC $(FC) $(CXXFLAGS) -I$(INCDIR) $^ $(LDLIBS) -o $#
...
The MakeVariables can be found in the above link.
I changed this make file so that I can make an object file of example-f.f90 (subroutine, I converted as I told before to link it in our in-house code) and also other files in our in-house code and link at the end. The new makefile looks like:
ifndef PVFMM_DIR
PVFMM_DIR=./..
endif
-include $(PVFMM_DIR)/MakeVariables
ifndef CXX_PVFMM
$(error Cannot find file: MakeVariables)
endif
FC_PVMM = mpif90
FC = mpif90
FC=$(FC_PVFMM) # TODO: for now, FC must be provided by user
CC=$(CC_PVFMM) # TODO: for now, CC must be provided by user
CXX=$(CXX_PVFMM)
CXXFLAGS=$(CXXFLAGS_PVFMM)
LDLIBS=$(LDLIBS_PVFMM)
RM = rm -f
MKDIRS = mkdir -p
BINDIR = ./bin
SRCDIR = ./src
OBJDIR = ./obj
INCDIR = ./include
all : $(project_final)
project_final: $(project)
$(PVFMM_DIR)/libtool --mode=link --tag=FC mpif90 $(CXXFLAGS) -I$(INCDIR) $^ $(LDLIBS) -o $#
project: example-f.o
cd ./src && $(MAKE)
example-f.o: $(SRCDIR)/example-f.f90
$(PVFMM_DIR)/libtool --mode=link --tag=FC mpif90 $(CXXFLAGS) -I$(INCDIR) $^ $(LDLIBS) -c $#
...
Kindly note 'project: example-f.o
cd ./src && $(MAKE)' doing to make object files of our inhouse code. In src we have separate makefile to create object files for out in-house code.
But it gives me the following:
cd ./examples && make;
make[1]: Entering directory '/home/bidesh/Coding/FMM/pvfmm-1.3.0/examples'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/bidesh/Coding/FMM/pvfmm-1.3.0/examples'
How can I modify the makefile so that I can compile the whole code that includes example-f.f90 (subroutine) along with other subroutines (in-house code)?
Thanks a lot.

make: Nothing to be done for 'all'. in Omnet

After Installng Omnetpp 5.5.1 in Ubuntu 18.04 ,For any folder in Omnetpp, make command is not making any sense.
As it showing the following message:
make: Nothing to be done for 'all'.
Even suggested methods on Internet are not working in my case.Please help.
My makefile is following for Aloha Folder.
#
# OMNeT++/OMNEST Makefile for aloha
#
# This file was generated with the command:
# opp_makemake -f --deep
#
# Name of target to be created (-o option)
TARGET = aloha$(D)$(EXE_SUFFIX)
TARGET_DIR = .
# User interface (uncomment one) (-u option)
USERIF_LIBS = $(ALL_ENV_LIBS) # that is, $(TKENV_LIBS) $(QTENV_LIBS) $(CMDENV_LIBS)
#USERIF_LIBS = $(CMDENV_LIBS)
#USERIF_LIBS = $(TKENV_LIBS)
#USERIF_LIBS = $(QTENV_LIBS)
# C++ include paths (with -I)
INCLUDE_PATH =
# Additional object and library files to link with
EXTRA_OBJS =
# Additional libraries (-L, -l options)
LIBS =
# Output directory
PROJECT_OUTPUT_DIR = out
PROJECTRELATIVE_PATH =
O = $(PROJECT_OUTPUT_DIR)/$(CONFIGNAME)/$(PROJECTRELATIVE_PATH)
# Object files for local .cc, .msg and .sm files
OBJS = $O/Host.o $O/Server.o
# Message files
MSGFILES =
# SM files
SMFILES =
#------------------------------------------------------------------------------
# Pull in OMNeT++ configuration (Makefile.inc)
ifneq ("$(OMNETPP_CONFIGFILE)","")
CONFIGFILE = $(OMNETPP_CONFIGFILE)
else
ifneq ("$(OMNETPP_ROOT)","")
CONFIGFILE = $(OMNETPP_ROOT)/Makefile.inc
else
CONFIGFILE = $(shell opp_configfilepath)
endif
endif
ifeq ("$(wildcard $(CONFIGFILE))","")
$(error Config file '$(CONFIGFILE)' does not exist -- add the OMNeT++ bin directory to the path so that opp_configfilepath can be found, or set the OMNETPP_CONFIGFILE variable to point to Makefile.inc)
endif
include $(CONFIGFILE)
# Simulation kernel and user interface libraries
OMNETPP_LIBS = $(OPPMAIN_LIB) $(USERIF_LIBS) $(KERNEL_LIBS) $(SYS_LIBS)
COPTS = $(CFLAGS) $(IMPORT_DEFINES) $(INCLUDE_PATH) -I$(OMNETPP_INCL_DIR)
MSGCOPTS = $(INCLUDE_PATH)
SMCOPTS =
# we want to recompile everything if COPTS changes,
# so we store COPTS into $COPTS_FILE and have object
# files depend on it (except when "make depend" was called)
COPTS_FILE = $O/.last-copts
ifneq ("$(COPTS)","$(shell cat $(COPTS_FILE) 2>/dev/null || echo '')")
$(shell $(MKPATH) "$O" && echo "$(COPTS)" >$(COPTS_FILE))
endif
#------------------------------------------------------------------------------
# User-supplied makefile fragment(s)
# >>>
# <<<
#------------------------------------------------------------------------------
# Main target
all: $(TARGET_DIR)/$(TARGET)
$(TARGET_DIR)/% :: $O/%
#mkdir -p $(TARGET_DIR)
$(Q)$(LN) $< $#
ifeq ($(TOOLCHAIN_NAME),clangc2)
$(Q)-$(LN) $(<:%.dll=%.lib) $(#:%.dll=%.lib)
endif
$O/$(TARGET): $(OBJS) $(wildcard $(EXTRA_OBJS)) Makefile $(CONFIGFILE)
#$(MKPATH) $O
#echo Creating executable: $#
$(Q)$(CXX) $(LDFLAGS) -o $O/$(TARGET) $(OBJS) $(EXTRA_OBJS) $(AS_NEEDED_OFF) $(WHOLE_ARCHIVE_ON) $(LIBS) $(WHOLE_ARCHIVE_OFF) $(OMNETPP_LIBS)
.PHONY: all clean cleanall depend msgheaders smheaders
.SUFFIXES: .cc
$O/%.o: %.cc $(COPTS_FILE) | msgheaders smheaders
#$(MKPATH) $(dir $#)
$(qecho) "$<"
$(Q)$(CXX) -c $(CXXFLAGS) $(COPTS) -o $# $<
%_m.cc %_m.h: %.msg
$(qecho) MSGC: $<
$(Q)$(MSGC) -s _m.cc -MD -MP -MF $O/$(basename $<)_m.h.d $(MSGCOPTS) $?
%_sm.cc %_sm.h: %.sm
$(qecho) SMC: $<
$(Q)$(SMC) -c++ -suffix cc $(SMCOPTS) $?
msgheaders: $(MSGFILES:.msg=_m.h)
smheaders: $(SMFILES:.sm=_sm.h)
clean:
$(qecho) Cleaning $(TARGET)
$(Q)-rm -rf $O
$(Q)-rm -f $(TARGET_DIR)/$(TARGET)
$(Q)-rm -f $(TARGET_DIR)/$(TARGET:%.dll=%.lib)
$(Q)-rm -f $(call opp_rwildcard, . , *_m.cc *_m.h *_sm.cc *_sm.h)
cleanall:
$(Q)$(MAKE) -s clean MODE=release
$(Q)$(MAKE) -s clean MODE=debug
$(Q)-rm -rf $(PROJECT_OUTPUT_DIR)
# include all dependencies
-include $(OBJS:%=%.d) $(MSGFILES:%.msg=$O/%_m.h.d)
This aforementioned file is missing some information like c++ INCLUDE_PATH and EXTRA_OBJS and LIBS.Is this the reason for not being run?Please Help.
The makefile says that 'Nothing to be done' because the executable is present and up to date, so it is indeed nothing to be done. This is not an error.
As you have indicated, you can execute ./aloha and then that throws a runtime error. This is NOT related to the build process.

How to efficiently write a GNU makefile with several modules with an arbitrary number of dependencies in Fortran

My makefile currently looks like this:
#Source file locations
VPATH = :../AHMCodePara
#Compiler
CC = mpifort
#Debugging Flags
#Flags =
#Regular flags
Flags = -Ofast -mkl=sequential
# File name labels
FF =
DE =
Const =
OBJDIR = OBJ
# make object directory
$(OBJDIR):
-mkdir $(OBJDIR)
CC += -module $(OBJDIR)
#Object File List
Inputs =
Tools = $(OBJDIR)/$(Const)Inputs.o
Diag$(DE) = $(Tools)
PreAnalysis = $(Tools) $(OBJDIR)/Tools.o
DOSsetupPara$(DE) = $(PreAnalysis) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
$(Const)AHMRGv3 = $(Tools) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o
#Object File List
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Diag$(DE).o $(OBJDIR)/Tools.o \
$(OBJDIR)/PreAnalysis.o $(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o
# dependence files
$(OBJDIR)/%.o: %.f90 $(%)
# #$(%)
#-rm -f #<~
$(CC) -c $< -o $# $(Flags)
All: V3.e
# Target
V3.e: $(obj)
$(CC) $(Flags) -o $# $^
clean:
rm $(OBJDIR)/*.o $(OBJDIR)/*.mod
It used to be similar to this one:
LOC = ../../AHMCode/
CC = gfortran
#Debugging
#Flags = -O0 -g -fcheck=all -Wall -llapack
#Normal
Flags = -O3 -I/usr/lib/ -L/usr/lib/ -lblas -llapack
FF = _Old
IG = #IGNORE or nothing
TT = #TYPE or nothing
V3$(FF).e: Inputs.o Tools.o PreAnalysis.o DOSsetup$(IG).o Diag$(TT).o AHMRGv3_Manyruns.o
$(CC) $(Flags) AHMRGv3_Manyruns.o Diag$(TT).o DOSsetup$(IG).o PreAnalysis.o Tools.o Inputs.o -o V3$(FF).e
Inputs.o: Inputs.f90
$(CC) $(Flags) -c Inputs.f90
Tools.o: $(LOC)Tools.f90 Inputs.o
$(CC) $(Flags) -c $(LOC)Tools.f90
PreAnalysis.o: $(LOC)PreAnalysis.f90 Inputs.o Tools.o
$(CC) $(Flags) -c $(LOC)PreAnalysis.f90
DOSsetup$(IG).o: $(LOC)DOSsetup$(IG).f90 Inputs.o Tools.o PreAnalysis.o Diag$(TT).o
$(CC) $(Flags) -c $(LOC)DOSsetup$(IG).f90
Diag$(TT).o: $(LOC)Diag$(TT).f90 Inputs.o
$(CC) $(Flags) -c $(LOC)Diag$(TT).f90
AHMRGv3_Manyruns.o: AHMRGv3_ManyRuns.f90 DOSsetup$(IG).o Diag$(TT).o Inputs.o
$(CC) $(Flags) -c AHMRGv3_Manyruns.f90
clean:
rm *.o *.mod
The section I want to compare in these makefiles is the .o file definitions. In the second makefile, I wrote these all out by hand and it worked great. My intention with the second makefile was to do the same thing but more efficiently.
The problems arose with dependencies. When I initially made changes to my makefile, I didn't put any dependencies at all. This led to problems where I would update Inputs and the relevant files wouldn't recompile (e.g. Tools.o). This is as expected so I've been looking for ways to add dependencies in a creative and efficient way that forces the relevant files to recompile.
As you can see I tried creating variables with the same name as the .f90 and .o to use $(%). This seemed kinda janky (and I didn't really think it would work) but unfortunately didn't solve my problem.
As you can see from the original makefile, the dependencies don't follow any sort of pattern. As well you can see that I am compiling Fortran and I'm pretty sure that -gen-dep doesn't do anything and if it does I'm doing it wrong.
Existing questions on the subject have been very unhelpful since the majority uses C++ and that can be very different here.
EDIT: I "fixed" my problem. Its not the most efficient and doesn't automatically generate dependencies but I like it in that its not a lot of repetitive lines.
#Object File List
oInpt =
oTool = $(OBJDIR)/$(Const)Inputs.o
oPreA = $(oTool) $(OBJDIR)/Tools.o
oDOSs = $(oPreA) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
oDiag = $(oTool)
oMain = $(oTool) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Tools.o $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o \
$(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o
# dependence files
$(OBJDIR)/$(Const)Inputs.o: $(oInpt)
$(OBJDIR)/Tools.o: $(oTool)
$(OBJDIR)/PreAnalysis.o: $(oPreA)
$(OBJDIR)/Diag$(DE).o: $(oDiag)
$(OBJDIR)/DOSsetupPARA$(DE).o: $(oDOSs)
$(OBJDIR)/$(Const)AHMRGv3.o: $(oMain)
$(OBJDIR)/%.o: %.f90
#-rm -f #<~
$(CC) -c $< -o $# $(Flags)
All: V3.e
# Target
V3.e: $(obj)
$(CC) $(Flags) -o $# $^
I just made multiple rules for each target. One a default rule that actually compiles the .o files and the other that specifies the dependencies for each .f90 file.

Issue with my Makefile. No such file or directory

I'm trying to build a MIPS program with Make. I have two files that are pretty bare as I want to get the Makefile working before continuing with functionality:
logic.asm
# contains a main method
# contains a .globl to print_strings
# calls print_strings
printer.asm
# has a print_strings method that just prints a few strings and returns
My Makefile looks like so:
RASM = /home/bin/rasm
RLINK = /home/bin/rlink
# Suffixes
.SUFFIXES: .asm .obj .lst .out
# Obj files
OBJS = logic.obj printer.obj
# ASM -> OBJ
.asm.obj:
$(RASM) -l $*.asm > $*.lst
# OBJ -> OUT
.obj.out:
$(RLINK) -m -o $*.out $*.obj > $*.map
# target
logic.out: $(OBJS)
$(RLINK) -m -o $*.out $*.out $(OBJS) > $*.map
When I run make, here's what I'm seeing:
$ make
/home/bin/rlink -m -o logic.out logic.out logic.obj printer.obj > logic.map
logic.out: No such file or directory
make: *** [logic.out] Error 1
The problem was with this line:
$(RLINK) -m -o $*.out $*.out $(OBJS) > $*.map
There should only be 1 $*.out, like so:
$(RLINK) -m -o $*.out $(OBJS) > $*.map

Variable substitution error

Does anyone know what is wrong with my Makefile?
CXX = g++ # compiler
CXXFLAGS = -g -Wall -MMD # compiler flags
MAKEFILE_NAME = ${firstword ${MAKEFILE_LIST}} # makefile name
OBJECTS1 = utf.o # object files forming executable
EXEC1 = utf # executable name
OBJECTS2 = driver.o rational.o # object files forming executable
EXEC2 = rational # executable name
OBJECTS3 = da.o qa.o pa.o ua.o # object files forming executable
EXEC3 = ho # executable name
OBJECTS = ${OBJECTS1} ${OBJECTS2} ${OBJECTS3}
EXECS = ${EXEC1} ${EXEC2} ${EXEC3}
DEPENDS = ${OBJECTS:.o=.d} # substitute ".o" with ".d"
.PHONY : all clean
all : ${EXECS}
${EXEC1} : ${OBJECTS1} # link step
${CXX} $^ -o $#
${EXEC2} : ${OBJECTS2} # link step
${CXX} $^ -o $#
${EXEC3} : ${OBJECTS3} # link step
${CXX} $^ -o $#
${OBJECTS} : ${MAKEFILE_NAME} # OPTIONAL : changes to this file => recompile
-include ${DEPENDS} # include *.d files containing program dependences
clean : # remove files that can be regenerated
rm -f ${DEPENDS} ${OBJECTS} ${EXECS}
Error:
./Makefile: 1: CXX: not found
./Makefile: 2: CXXFLAGS: not found
./Makefile: 3: Bad substitution
use the make command to run the Makefile. you can specify a target for make, like make all.
Don't execute the makefile on its own. Your shell is trying to treat it as a shell script of some kind.
Run make, which uses the makefile.

Resources