I just have writed some pure c programs for practice, each little program have a XXX.h file XXX.c file and XXX_test.c file with the main function in it. both of the XXX.c file and the XXX_test.c may have include some other YYY.h files. I use the the gcc -MM to find the dependency of XXX_test.c files automatically. finally, I come up with the makefile(using GNU makefile) XXX.mk:
# change your targets to your real targets
MINGW := MINGW32_NT-6.1
CC = gcc
OFLAG = -o
CFLAGS = -Wall -g -DDEBUG
# get the dependent header files and change their name to source files
TARGET := XXX_test
FILES := $(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET))))
SRCS := $(FILES:.h=.c)
DEPS := $(SRCS:.c=.d)
OBJECTS := $(SRCS:.c=.o)
#determine the os platform
ifdef SystemRoot
ifeq ($(shell uname), ${MINGW})
RM = rm -f
FixPath = $1
else
RM = del /Q
FixPath = $(subst /,\,$1)
endif
else
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
endif
endif
all: ${TARGET}
# include .d files generated by gcc -MMD opt
-include $(DEPS)
# to generate the .o files as well as the .d files
%.o:%.c
$(CC) $(CFLAGS) -c -MMD $< -o $@
# generate the executable program
${TARGET}: ${OBJECTS}
${CC} $^ ${OFLAG} $@
.PHONY:clean
# the "$" is not needed before "FixPath"
clean:
$(RM) $(call FixPath, ${OBJECTS} ${DEPS})
each little program have a XXX.mk file. they are almost the same except that the content in the variable TARGET is different(see the makefile above). so I have XXX.mk, YYY.mk etc … The question I want to ask is how can I convert all the makefiles, i.e. XXX.mk, YYY.mk … into one makefile? for example generic.mk with a varible TARGETS(note the S) assigned to XXX_test YYY_test .... the thing that I find difficult to handle is the variable dependencies:
TARGET --> OBJECTS --> SRCS --> FILES --> TARGET(the FILES is generate by gcc using -MM opt)
↓
DEPS(used to include the .d files)
each target(such as XXX_test) should depend on their on bunch of files. I want to see the power of GNU makefile, how could I do it? I am learning to use the gmake.
as you found out, the main problem you are having is, that the expansion of OBJECTS from the DEPS doesn’t work well with multiple targets.
one possibility to solve this is to use a two stage approach, where the second stage deals only with building a single binary (and does all the dependency tracking and binary object compilation), and the first stage calls the 2nd one for each given binary.
this solution involves two Makefiles (not exactly what you asked for, but still):
Makefile:
this makefile simply calls another make with the program to build as argument and the secondary Makefile.sub:
if you insist on using a single Makefile, then i’m afraid, that you have to do the dependency tracking manually.
one of the more common build-systems is autotools where you have to provide the sources for each binary yourself (to run the following you need autotools installed; run
autoreconfto generateconfigureandMakefile.infrom the following code; then run./configureto create a cross-platform Makefile):Makefile.am:
configure.ac: