I have a make build system that I am trying to decipher that someone else wrote. I am getting an error when I run it on a redhat system, but not when I run it on my solaris system. The versions of gmake are the same major revision (one off on minor revision).
This is for building a C project, and the make system has a global Makefile.global that is inherited by each directory’s local Makefile
The Makefile.global has all the targets in it, starting with
all: $(LIB) $(BIN)
The global file also has the following line
ifndef INCLUDE_GEN_DEPS
sinclude $(GEN_DEPS)
endif
where LIB builds libs and BIN builds binaries.
jumping down the targets I have
$(LIB) : $(GEN_LIB)
$(GEN_LIB) : $(GEN_DEPS) $(GEN_OBJS)
$(AR) $(ARFLAGS) $(GEN_LIB) $(GEN_OBJS)
$(GEN_DEPS) :
@set -e; rm -f $@; \
$(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ; \
cat $@.tmp > $@ ; \
cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ; \
rm $@.tmp
$(GEN_OBJS) :
$(CC) $(CFLAGS) $(INCDIRS) -c $(*F).c -lmpi -o $@
I think these are all the relevant targets I need to include to answer my question.
Definitions of those variables:
CC = icc
CDEP_FLAG = -M
CFLAGS = various compiler flags ifdef type flags
INCDIRS = include directory where all .h files are
GEN_OBJDIR = /lib/objs
HOME_SRC = .
GEN_LIB = lib/$(LIB)
GEN_DEPDIR=/lib/deps
GEN_DEPS = $(addprefix $(GEN_DEPDIR)/,$(addsuffix .d,$(basename $(OBJS))))
I think this has everything covered you need. Basically self explanatory from the names.
Now as best I can tell, this is generating in /lib/deps a .d file that has the object and source dependencies in it. In other words, for the utilities.a library, I will get a utils.o and utils.c dependency stack, all in the file utils.d
There is some syntax error that is being generated in that file I think, because I get the following error:
../lib/deps/util.d:25: *** target pattern contains no '%'. Stop.
gmake[2]: *** [all] Error 2
gmake[1]: *** [all] Error 2
gmake: *** [all] Error 2
I am not sure if my error is in the dependency generation, or some further down part, like the object generation target?
If you need further info, let me know, I will add to post
Compare what gets written into lib/deps/util.d on your working (Solaris) machine with the non-working (redhat), paying particular attention to line 25. That will probably give you a good hint as to what’s going wrong.
If they’re identical, the problem is the one-off make minor version.
If thye’re different, the problem is probably some difference between the tools being run, or (more likely) different versions of icc installed.
edit
decoding make rule:
This rule makes the dependency files in
$(GEN_DEPS), which correspond to all the source files with the.cchanged to.dCause any errors to immediately exit this rule with a failure, rather than continuing, and remove the target we’re about to regenerate
Run icc on the .c file corresponding to the .d file we’re trying to generate with flags to automatically generate dependencies instead of compiling. The
basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'clause is translating the .d name back to the .c name.
Pipe the output (which is the depdendency rules) to the sed script
sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g', which will add the dependency file itself as a something that depends on everything that icc found for the.o(object) file to depend on. Write all of this to a temp file.Copy the temp file to the output dependency file.
Append a second copy of the dependencies to the dependency file, modified by a little script which strips off the target and makes the first header into the target. So this is adding an additional set of dependencies for the first header file that appears in the source file.
Remove the temp file.