Makefile overriding recipe error when string is used inside of echo - makefile

I have the following Makefile and I get an error when I use all target. I am not sure what is the root cause of the problem.
APSTOP= ../..
VERSION=2.12.8
SVERSION=2.12
SCALAC= /afs/package/scala/scala-${VERSION}/common/bin/scalac
APSLIB = ${APSTOP}/lib/aps-library-${SVERSION}.jar
COOLCOMPILERDIR= /afs/project/cool/scala
SCALAFLAGS= -cp .:${APSLIB}
SCALACFLAGS= ${SCALAFLAGS}
APS2SCALA = ${APSTOP}/bin/aps2scala
APS2SCALAFLAGS = -p ..:${APSTOP}/base -G
SCALASRC = cool-symbol.handcode.scala cool-semant-driver.scala cool-handcode.scala cool-noinherit-semant-driver.scala
SCALAGEN = cool-symbol.scala cool-tree.scala \
cool-noinherit-semant.scala cool-dynamic-semant.scala
SCALACOPY= basic.scala A2I.scala \
CoolTokens.scala CoolScanner.scala CoolOptions.scala \
CoolParser.scala
SCALAHAND = CoolCompiler.scala
EXAMPLEDIR = ../examples
.PHONY: all clean src
src : ${SCALASRC}
all : ${SCALAGEN}
all : cool_symbol_implicit.class \
cool_tree_implicit.class \
cool_noinherit_semant_implicit.class \
cool_dynamic_semant_implicit.class
%.scala : ../%.aps
${APS2SCALA} ${APS2SCALAFLAGS} $*
cool-symbol.scala : ../cool-symbol.aps
${APS2SCALA} ${APS2SCALAFLAGS} --omit SYMBOL --omit gensym cool-symbol
%_implicit.class : %.scala
${SCALAC} ${SCALACFLAGS} $*.scala
cool_symbol_implicit.class : cool-symbol.scala cool-symbol.handcode.scala
${SCALAC} ${SCALACFLAGS} cool-symbol.scala cool-symbol.handcode.scala
cool_tree_implicit.class : cool-tree.scala cool_symbol_implicit.class
${SCALAC} ${SCALACFLAGS} cool-tree.scala
cool_noinherit_semant_implicit.class : cool-noinherit-semant.scala
${SCALAC} ${SCALACFLAGS} $<
cool_dynamic_semant_implicit.class : cool-dynamic-semant.scala
${SCALAC} ${SCALACFLAGS} $<
%.scala : RCS/%.scala,v
co $<
.PHONY: %.run
%.run : %.class
scala ${SCALAFLAGS} $*
.PHONY: %.compile
%.compile : %.scala
scalac ${SCALACFLAGS} $*.scala
.PHONY: %.semant
%.semant : ${EXAMPLEDIR}/%.cool Semant.class
scala ${SCALAFLAGS} CoolCompiler $<
.PHONY: %.debug
%.debug : ${EXAMPLEDIR}/%.cool Semant.class
scala ${SCALAFLAGS} CoolCompiler -s $<
COOLCOMPILERSCALA = \
cool-symbol.scala cool-symbol.handcode.scala cool-tree.scala \
cool-handcode.scala ${SCALACOPY} \
cool-dummy-semant-driver.scala ${SCALAHAND}
${SCALACOPY} :
echo "import cool_implicit._" | cat - ${COOLCOMPILERDIR}/$# > $#
CoolParser.scala :
echo "import cool_implicit._" | cat - ${COOLCOMPILERDIR}/$# > $#.tmp
sed 's/result.set_inheritablep(/t_Tree.s_inheritablep(result,/' \
< $#.tmp > $#
cool-parser-${SVERSION}.jar : ${COOLCOMPILERSCALA}
#rm -f *.class
${SCALAC} -deprecation ${SCALACFLAGS} ${COOLCOMPILERSCALA}
jar cvf $# *.class
install: cool-parser-${SVERSION}.jar
cp cool-parser-${SVERSION}.jar ../../lib/.
clean:
rm -f *.class ${SCALAGEN} ${SCALACOPY} *.jar
Error:
Makefile:79: warning: overriding recipe for target 'CoolParser.scala'
Makefile:76: warning: ignoring old recipe for target 'CoolParser.scala'
make: Nothing to be done for 'src'.

That is not an error: if it was an error the build would have failed. This build succeeded. In make error messages contain ***. This is just a warning about a weird thing in your makefile.
To understand it you just have to look at the lines in your makefile that make is complaining about, and read the message it printed.
You have this variable set:
SCALACOPY= basic.scala A2I.scala \
CoolTokens.scala CoolScanner.scala CoolOptions.scala \
CoolParser.scala
So this variable contains CoolParser.scala.
Next at Makefile line 76, you have this:
${SCALACOPY} :
echo "import cool_implicit._" | cat - ${COOLCOMPILERDIR}/$# > $#
This defines rules telling make how to build all the targets in the variable SCALACOPY, including CoolParser.scala.
Then at Makefile line 79, you have this:
CoolParser.scala :
echo "import cool_implicit._" | cat - ${COOLCOMPILERDIR}/$# > $#.tmp
sed 's/result.set_inheritablep(/t_Tree.s_inheritablep(result,/' \
< $#.tmp > $#
This tells make ANOTHER rule also to build CoolParser.scala, which you already provided a rule for; make will drop the first rule and use the second rule, but it will also give you a warning message telling you about it because this is very unusual and not usually what you want to do:
Makefile:79: warning: overriding recipe for target 'CoolParser.scala'
Makefile:76: warning: ignoring old recipe for target 'CoolParser.scala'

Related

Undefined reference to `compress2' and other functions in the HDF5 library

I am trying to make a code called iPIC3D and it has some prerequisite libraries such as HDF5, H5hut etc. I did everything as instructed. One has to install all the prerequisites and then run the "make" command. But while running the make command, I get a series of errors such as
/usr/local/hdf5/1.8.11-par/lib/libhdf5.a(H5Zdeflate.o): In function `H5Z_filter_deflate':
H5Zdeflate.c:(.text+0xf1): undefined reference to `compress2'
H5Zdeflate.c:(.text+0x1af): undefined reference to `inflateInit_'
H5Zdeflate.c:(.text+0x1c9): undefined reference to `inflate'
H5Zdeflate.c:(.text+0x27a): undefined reference to `inflateEnd'
H5Zdeflate.c:(.text+0x2dc): undefined reference to `inflateEnd'
H5Zdeflate.c:(.text+0x3de): undefined reference to `inflateEnd'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
Here is a copy of my makefile for reference
PIC_HOME = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
## SECTION THAT DEPENDS ON THE SYSTEM
# -- Modify this variables according
# -- to your system options.
# -- Possible flags:
# -DPARALLEL_IO Use parallel HDF5
# -DUSEH5HUT Use H5hut (must include also -DPARALLEL_IO)
# -DBATSRUS Coupling with BATS-R-US
CXX = mpicxx
HDF5_HOME = /usr/local/hdf5/1.8.11-par
H5HUT_HOME = /usr/local/H5hut/1.8.11
IPIC_FLAGS = "-DUSEH5HUT -DPARALLEL_IO"
## END OF SECTION
OPTIM = -O3
HDF5_LIB = $(HDF5_HOME)/lib/libhdf5_hl.a $(HDF5_HOME)/lib/libhdf5.a
H5HUT_LIB = $(H5HUT_HOME)/lib/libH5hut.a
H5HUTIO_LIB = $(IPIC_HOME)/H5hut-io/libH5hut-io.a
INC_DIR = ./include
INC_H5HUT = $(H5HUT_HOME)/include
INC_H5HUTIO = $(IPIC_HOME)/H5hut-io/include
INC_HDF5 = $(HDF5_HOME)/include
.SUFFIXES:
.SUFFIXES: .cpp .o .h
SRC = \
$(IPIC_HOME)/grids/Grid3DCU.cpp \
$(IPIC_HOME)/fields/BCStructure.cpp \
$(IPIC_HOME)/fields/EMfields3D.cpp \
$(IPIC_HOME)/inputoutput/phdf5.cpp \
$(IPIC_HOME)/inputoutput/Restart3D.cpp \
$(IPIC_HOME)/inputoutput/ParallelIO.cpp \
$(IPIC_HOME)/inputoutput/Collective.cpp \
$(IPIC_HOME)/performances/Timing.cpp \
$(IPIC_HOME)/PSKOutput3D/PSKhdf5adaptor.cpp \
$(IPIC_HOME)/bc/BcParticles.cpp \
$(IPIC_HOME)/bc/BcFields3D.cpp \
$(IPIC_HOME)/mathlib/EllipticF.cpp \
$(IPIC_HOME)/solvers/CG.cpp \
$(IPIC_HOME)/solvers/GMRES.cpp \
$(IPIC_HOME)/ConfigFile/src/ConfigFile.cpp \
$(IPIC_HOME)/main/iPic3Dlib.cpp \
$(IPIC_HOME)/particles/Particles3Dcomm.cpp \
$(IPIC_HOME)/particles/Particles3D.cpp \
$(IPIC_HOME)/communication/ComNodes3D.cpp \
$(IPIC_HOME)/communication/ComParser3D.cpp \
$(IPIC_HOME)/communication/ComInterpNodes3D.cpp \
$(IPIC_HOME)/communication/ComParticles3D.cpp \
ALLOBJ = $(subst .cpp,.o,$(SRC))
IPIC3D_EXE = $(IPIC_HOME)/iPic3D
IPIC3D_LIB = $(IPIC_HOME)/libiPic3Dlib.a
LDLIBS = $(IPIC3D_LIB) $(H5HUTIO_LIB) $(H5HUT_LIB) $(HDF5_LIB) -ldl
all : io lib main
io :
CXX=$(CXX) HDF5_HOME=$(HDF5_HOME) H5HUT_HOME=$(H5HUT_HOME) IPIC_FLAGS=$(IPIC_FLAGS) $(MAKE) -C $(IPIC_HOME)/H5hut-io
lib : $(ALLOBJ)
$(AR) sr $(IPIC3D_LIB) $(ALLOBJ)
ranlib $(IPIC3D_LIB)
main : iPic3D.o
$(CXX) $(LDFLAGS) -I$(INC_DIR) -I$(INC_HDF6) iPic3D.cpp -o $(IPIC3D_EXE) $(LDLIBS)
clean : cleanio
$(RM) $(ALLOBJ)
$(RM) $(IPIC3D_LIB)
$(RM) iPic3D.o
$(RM) $(IPIC3D_EXE)
cleanio :
$(MAKE) -C $(IPIC_HOME)/H5hut-io clean
%.o : %.cpp
echo " Compiling " $#
$(CXX) $(CXXFLAGS) $(OPTIM) $(IPIC_FLAGS) -I$(INC_DIR) -I$(INC_H5HUTIO) -I$(INC_H5HUT) -I$(INC_HDF5) -c $< -o $#
I am unable to understand what exactly is causing this problem.
I would say you are missing linking in the libz library as this is where the compress2 function should come from. Try adding -lz to your LDLIBS.

How to build a program with Make using different build configurations?

yesterday I wrote a Makefile to build a Programm which works fine.
Now, I try to build different build configurations.
What is the recommended way to build different configurations which differ in the list of source files and output paths?
I tried to use target specific variables...
Executables of the compiler toolchain.
COMPILER := ccrl
LINKER := rlink
ASSEMBLER := asrl
DEVICE_FILE := DR5F100LL.DVF
Compiler flags used to generate *.d files.
DFLAGS := \
-MM \
-MP \
-cpu=S2 \
-dev="$(DEVICE_FILE)" \
-no_warning_num=11179,11180 \
-g \
-Onothing
Compiler flags used to generate *.obj files from c source files.
CFLAGS := \
-cpu=S2 \
-c \
-dev="$(DEVICE_FILE)" \
-no_warning_num=11179,11180 \
-g \
-Onothing
Compiler flags used to generate *.obj files from assembler files.
ASMFLAGS := $(CFLAGS)
Linker flags
LDFLAGS := \
-library="${COMPILER_PATH}/lib/rl78cm4s.lib" \
-library="${COMPILER_PATH}/lib/rl78cm4r.lib" \
-library="./FFT_Library/libfft_rl78g13.lib" \
-nooptimize \
-entry=_start \
-security_id=00000000000000000000 \
-ocdbg=04 \
-user_opt_byte=EEFFE9 \
-debug \
-nocompress \
-memory=high \
-vectn=2=ffff \
-rom=.data=.dataR \
-rom=.sdata=.sdataR \
-nomessage \
-device="$(DEVICE_FILE)" \
-nologo \
-start=.const,.text,.RLIB,.SLIB,.textf,.constf,.data,.sdata/03000,.dataR,.bss/0F7F00,.sdataR,.sbss/0FFE20
Include directories
C_INCS := \
-I${COMPILER_PATH}/inc \
...
C source files used build the program.
C_SRCS_FFT_TEST := \
CodeGenerator/r_cg_cgc.c \
...
C_SRCS_HISTORY_TEST := \
CodeGenerator/r_cg_cgc.c \
...
C_SRCS_IOLINK_TEST := \
CodeGenerator/r_cg_cgc.c \
...
Assembler files used to build the program.
ASM_SRCS := \
...
Root directories of the build results.
OUT_ROOT_DIR := build
PUBLISH_ROOT_DIR := publish
.SECONDEXPANSION:
Name of the build configuration.
BUILD_CONFIG = Unknown
OUT_DIR =$(OUT_ROOT_DIR)/$(BUILD_CONFIG)
PUB_DIR =$(PUBLISH_ROOT_DIR)/$(BUILD_CONFIG)
Determine file paths of generated files.
OBJS = $(patsubst %.c,$(OUT_DIR)/%.obj,$(C_SRCS))
OBJS += $(patsubst %.asm,$(OUT_DIR)/%.obj,$(ASM_SRCS))
DEPS = $(OBJS:.obj=.d)
Filenames of the output files.
OUT_FILE = $(PUB_DIR)/MyFile.abs
MAP_FILE = $(OUT_DIR)/MyFile.map
.PHONY: build-definitions
build-definitions: fft-test history-test iolink-test
fft-test: BUILD_CONFIG=FFT_Test
fft-test: C_SRCS=$(C_SRCS_FFT_TEST)
.PHONY: fft-test
fft-test: $$(OUT_FILE)
history-test: BUILD_CONFIG=History_Test
history-test: C_SRCS=$(C_SRCS_HISTORY_TEST)
.PHONY: history-test
history-test:
#echo -e "Building $(BUILD_CONFIG)."
iolink-test: BUILD_CONFIG=IOLink_Test
iolink-test: C_SRCS=$(C_SRCS_IOLINK_TEST)
.PHONY: iolink-test
iolink-test:
#echo -e "Building $(BUILD_CONFIG)."
.PHONY: all
all: pre-build $(OUT_FILE) post-build
.PHONY: pre-build
pre-build:
#echo -e "Run pre-build target."
.PHONE: post-build
post-build:
#echo -e "Run post-build target."
.PHONY: clean
clean:
#echo -e "Run clean target."
#rm -f -v $(OUT_DIR)/LinkerSubCommand.tmp
#rm -f -v $(OBJS)
#rm -f -v $(DEPS)
#rm -f -v $(OUT_FILE)
#rm -f -v $(MAP_FILE)
How to build the dependency file from a c source file.
$(OUT_DIR)/%.d : %.c
#echo 'Building d file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(DFLAGS) $(C_INCS) -o "$(#:%.obj=%.d)" -MT="$#" -MT="$(#:%.obj=%.d)" "$<"
How to build the dependency file from an asm file.
$(OUT_DIR)/%.d : %.asm
#echo 'Building d file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(DFLAGS) $(C_INCS) -o "$(#:%.obj=%.d)" -MT="$#" -MT="$(#:%.obj=%.d)" "$<"
How to build the object file from a c source file.
$(OUT_DIR)/%.obj : %.c
#echo 'Building obj file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(CFLAGS) $(C_INCS) -o "$#" "$<"
#echo -e $(#:%=-input=\"%\") >> $(OUT_DIR)/LinkerSubCommand.tmp
How to build the object file from an asm file.
$(OUT_DIR)/%.obj : %.asm
#echo 'Building asm file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(CFLAGS) $(C_INCS) -o "$#" "$<"
#echo -e $(#:%=-input=\"%\") >> $$(OUT_DIR)/LinkerSubCommand.tmp
#
$(OBJ): %.obj: %.c $(DEPS)
How to build the output file from all object files.
%.abs : $(OBJS)
#echo -e "Building $(BUILD_CONFIG)."
#echo -e "The output directory is $(OUT_DIR)."
#echo -e "The publish directory is $(PUB_DIR)."
#echo -e "The source files are $(C_SRCS)."
#echo -e "The assembler files are $(ASM_SRCS)."
#echo -e "The generated object files are $(OBJS)."
#echo -e "Building output file is $#."
#mkdir -p "$(PUB_DIR)"
#mkdir -p "$(OUT_DIR)"
$(LINKER) $(LDFLAGS) -subcommand="$(OUT_DIR)/LinkerSubCommand.tmp" -list="$(MAP_FILE)" -output="$(OUT_FILE)"
I know that I should use private as scope of the target specific variables but than I have to download/compile a newer make Version...
I would like to know the recommended way to build such configurations.
Maybe someone can provide a simple (and complete) example?
Thanks a lot!
Michael
Makefile:
ifeq ($(config), debug)
CFLAGS := -DDEBUG -g
OUT_PATH := ./build/debug/
else ifeq ($(config), light_debug)
CFLAGS := -g
OUT_PATH := ./build/light_debug/
else #release config by default
OUT_PATH := ./build/release
endif
#...
Then make invokation is like this:
make confg=debug
or
make config=light_debug
or
make config=release

Makefile is always 'up to date' while files have been changed

I have a Makefile to compile several fortran files, most of which are module files. Whenever I changed the module file and initiate make command, the make says:
make: `PRM' is up to date.
PRM is the executable name. No such problem when I changed the main file. Another problem is that sometimes I also get:
make: m2c: Command not found
error. My makefile looks like:
.SUFFIXES: .f90
F90 = pgf90
NETCDF_DIR = /opt/netcdf
F90_FLAGS = -Mbackslash -Mlarge_arrays
LIBS = -L$(NETCDF_DIR)/lib -lnetcdff -lnetcdf
INCLUDE_MODULES = -I$(NETCDF_DIR)/include
VPATH = /path/FORTRAN
util_module = \
precmod.o \
strings.o
EXEC = PRM
OBJS = \
${util_module} \
mo_date.o \
mo_utils.o \
module_metcro_lib.o \
module_plumerise1.o \
module_finn_lib.o \
main_plm.o
${EXEC} : ${OBJS}
${F90} -o $# ${OBJS} ${LIBS}
.f90.o:
${F90} -c ${F90_FLAGS} ${INCLUDE_MODULES} $<
clean:
rm -f ${EXEC} ${OBJS} *.mod
thanks for answering!

Targets and dependencies in Makefiles compilation

I came across a makefile which contained the below code. However i am not able to understand the first line $(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp, what are the dependencies exactly?
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
#$(PRINTF) "$(MESG_COLOR)Compiling: $(NO_COLOR) $(FILE_COLOR) %25s$(NO_COLOR)" "$(notdir $<)"
#$(CC) $(CPPFLAGS) -c $< -o $# -MD 2> temp.log || touch temp.err
#if test -e temp.err; \
then $(PRINTF) $(ERR_FMT) $(ERR_STRING) && $(CAT) temp.log; \
elif test -s temp.log; \
then $(PRINTF) $(WARN_FMT) $(WARN_STRING) && $(CAT) temp.log; \
else printf "${OK_COLOR}%30s\n${NO_COLOR}" "[OK]"; \
fi;
#$(RM) -f temp.log temp.err
This is a static pattern rule. It can be used to build any of the targets in $(OBJS), and constructs the names of the prerequisite(s) accordingly.
SRCDIR = sources
OBJDIR = objects
OBJS = objects/foo.o objects/bar.o objects/baz.o
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
#echo the target is $#, the prereq is $<
If you call this rule with "make objects/foo.o", Make will 1) recognize that this rule applies, since the desired target is a member of the rule's list of targets, 2) match the target name "objects/foo.o" against the target pattern "objects/%.o" to obtain the stem "foo", 3) put that stem into the prereq pattern "sources/%.cpp" to obtain the name of the prereq, "sources/foo.cpp".
This is a static pattern rule. Basically it means "for each word in $(OBJS), define an explicit rule where the target pattern $(OBJDIR)/%.o matches the word and the prerequisite is the expansion of the pattern $(SRCDIR)/%.cpp".
So if OBJS is equal to $(OBJDIR)/foo.o $(OBJDIR)/bar.o $(OBJDIR)/baz.o, then the static pattern rule is equivalent to writing this:
$(OBJDIR)/foo.o : $(SRCDIR)/foo.cpp
#$(PRINTF) ...
...
$(OBJDIR)/bar.o : $(SRCDIR)/bar.cpp
#$(PRINTF) ...
...
$(OBJDIR)/baz.o : $(SRCDIR)/baz.cpp
#$(PRINTF) ...
...

recursive clean in a Makefile

I'm trying to create a Makefile which can build/clean recursively when it's called. I have the build working, but I'm getting errors with the clean command.
My directory structure is something like:
main
|
+-- Makefile
|
+-- common
| |
| +-- gcas_debug
| | |
| | +-- Makefile
| + -- gcas_nvdata
| |
| +-- Makefile
+-- gcinit
+-- Makefile
When I call make in the main directory it goes through and builds everything as I desire, but when I call make clean it does with:
mike#mike-VirtualBox:~/iCOM/framework$ make clean
for d in common/gcas_debug common/gcas_nvdata; \
do \
make --directory=$f clean; \
done
make: the `-C' option requires a non-empty string argument
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
...
I don't understand why the clean command isn't working... Any suggestions?
Full (main) Makefile:
lib_gcas_debug := common/gcas_debug
lib_gcas_nvdata := common/gcas_nvdata
libraries := $(lib_gcas_debug) $(lib_gcas_nvdata)
DESTDIR=$(PWD)/output
bindir=
gc_init := gcinit
EXE := $(gc_init)/$(gc_init)
.PHONY: all $(gc_init) $(libraries)
all: $(gc_init)
$(gc_init) $(libraries):
$(MAKE) --directory=$#
$(gc_init): $(libraries)
install: $(gc_init)
install -d -m 0755 $(DESTDIR)$(bindir)
install -m 0755 $(EXE) $(DESTDIR)$(bindir)
clean:
for d in $(libraries); \
do \
$(MAKE) --directory=$$f clean; \
done
EDIT: If I swap the for d with for $d I get instead:
mike#mike-VirtualBox:~/iCOM/framework$ make clean
for in common/gcas_debug common/gcas_nvdata; \
do \
make --directory= clean; \
done
/bin/sh: -c: line 0: syntax error near unexpected token `common/gcas_debug'
/bin/sh: -c: line 0: `for in common/gcas_debug common/gcas_nvdata; \'
make: *** [clean] Error 1
This worked for me:
SUBDIRS := foo bar baz
.PHONY: subdirs $(SUBDIRS) clean all
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $# $(MAKECMDGOALS)
clean: $(SUBDIRS)
rm -rf dist
dist: $(SUBDIRS) dist/.build_marker
dist/.build_marker:
mkdir -p dist
for d in $(SUBDIRS) ; do cp $$d/dist/* dist ; done
touch dist/.build_marker
I only need to use the for loop in the dist target to copy files. This allows make -j build parallelism, not to mention simpler-to-read Makefiles.
Read the for loop again:
for d in [...]; do make --directory=$f
Didn't you mean $d, as in
for d in [...]; do make --directory=$d
So, the Makefile should look:
for d in common/gcas_debug common/gcas_nvdata; \
do \
make --directory=$d clean; \
done

Resources