Patternrule and Autogenerating Prerequisites in Makefile

Hi,

I have a question about makefile pattern rules and auto generating prerequisites.

Example:

foo.o : test1.c header1.h header2.h
$(CC) $(CFLAG) -c test1.c

How can I get the header files automatically included from test1.c into foo.o?


And what is the pattern rule for making a .o from a .c file, when I have different .c files in different subdirectories.

Because, this rule is not working:

%.o : %.c
$(CC) $(CFLAG) $(INCLUDES) -c $< -o $@

It says: No targets. Stop

I hope someone can help me



I do it like this, uses gcc -M to generate dependencies.


simple dir full of standalones:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#	---------------------------------
#	Standard (GNU) makefile template
#	will take each source file as a 
#	single source stand-alone
#	---------------------------------

# use this for setting variables e.g CFLAGS LDLIBS
# rather than editing this file
USER_FILE = user.mk
-include ${USER_FILE}

ECHO = @echo

ifndef EXT
ERROR: tidy
	@echo  
	@echo  "	you need to define  the filetype: 'EXT'"
	@echo
	@echo  "	i.e 'EXT = .c'"
	@echo  "	or  'EXT = .cc'"
	@echo  "	or  'EXT = .cpp'"
	@echo  
	@echo  "	you can do it in '$(USER_FILE)'" 
	@echo  
	exit
endif

ifneq ($(EXT),.c)
CC = g++
endif

VARFILE = var.mk
DEPENDFILE = depend.mk


# if EXT is not defined we need to make it something silly so
# that ls doesn't pick up spurious stuff (see the VARFILE target)
EXT ?= EXT_file_extension_type_not_defined 
-include ${VARFILE}

INCLUDES += -I${HOME}/include -I/usr/local/include
CFLAGS += -Wall ${INCLUDES}
CXXFLAGS += ${CFLAGS}


OBJFILES = ${SRC_FILES:${EXT}=.o}
TARGETS = ${SRC_FILES:${EXT}=} 


.IGNORE:
ALL:${TARGETS}  tidy


help: tidy
	${ECHO} EXT = ${EXT}
	${ECHO} CC = ${CC}
	${ECHO} TARGETS = ${TARGETS}
	${ECHO} OBJFILES = ${OBJFILES}
	${ECHO} SRC_FILES = ${SRC_FILES}

RCS:
	mkdir RCS

safe: RCS tidy 
	echo auto generated | ci -t/dev/null -l ${SRC_FILES}  *.h

tidy:
ifeq (${MAKE_GZIPS},yes)
	gzip -f  ${DEPENDFILE} ${VARFILE}
endif
	@rm -f  ${DEPENDFILE} ${VARFILE} 

clean: tidy
	rm -f *.o  ${RCSMESSAGE}
	${ECHO} use 'purge' to get rid of programs

purge:clean
	rm -f ${TARGETS} 
	rm -f ${DEPENDFILE}.gz ${VARFILE}.gz


${DEPENDFILE}:
	@${CC} -M ${INCLUDES} *${EXT} > $@

${VARFILE}:
	-@ls *${EXT}   | xargs echo SRC_FILES= > $@

# generated dependencies (Needs to go late in the file)
-include ${DEPENDFILE}


single target multiple source files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#	---------------------------------
#	Standard (GNU) makefile template
#              for single target multiple object
#
#	---------------------------------

# use this for setting variables e.g CFLAGS LDLIBS
# rather than editing this file
USER_FILE = user.mk
-include ${USER_FILE}

ECHO = @echo

ifndef EXT
ERROR: tidy
	@echo  
	@echo  "	you need to define  the filetype: 'EXT'"
	@echo
	@echo  "	i.e 'EXT = .c'"
	@echo  "	or  'EXT = .cc'"
	@echo  "	or  'EXT = .cpp'"
	@echo  
	@echo  "	you can do it in '$(USER_FILE)'" 
	@echo  
	exit
endif

ifndef TARGET
ERROR: tidy
	@echo  
	@echo  "	you need to define TARGET"
	@echo
	@echo  "	you can do it in '$(USER_FILE)'" 
	@echo  
endif

ifneq ($(EXT),.c)
CC = g++
endif

VARFILE = var.mk
DEPENDFILE = depend.mk


# if EXT is not defined we need to make it something silly so
# that ls doesn't pick up spurious stuff (see the VARFILE target)
EXT ?= EXT_file_extension_type_not_defined 
-include ${VARFILE}

INCLUDES += -I${HOME}/include -I/usr/local/include
CFLAGS += -Wall ${INCLUDES}
CXXFLAGS += ${CFLAGS}


OBJFILES = ${SRC_FILES:${EXT}=.o}

ifeq ($(EXT),.c)
PROTOTYPES = prototypes.h
endif


.IGNORE:
ALL:${TARGET} tidy ${PROTOTYPES}

${TARGET}:${OBJFILES}
	${CC} ${LDFLAGS} ${OBJFILES} -o $@ ${LDLIBS} 

${PROTOTYPES}:${SRC_FILES}
	2>/dev/null cproto ${SRC_FILES} > $@

help: tidy
	${ECHO} EXT = ${EXT}
	${ECHO} CC = ${CC}
	${ECHO} TARGET = ${TARGET}
	${ECHO} OBJFILES = ${OBJFILES}
	${ECHO} SRC_FILES = ${SRC_FILES}

RCS:
	mkdir RCS

safe: RCS tidy 
	echo auto generated | ci -t/dev/null -l ${SRC_FILES}  *.h *.hpp

tidy:
ifeq (${MAKE_GZIPS},yes)
	gzip -f  ${DEPENDFILE} ${VARFILE}
endif
	@rm -f  ${DEPENDFILE} ${VARFILE} 

clean: tidy
	rm -f *.o  ${RCSMESSAGE}
	${ECHO} use 'purge' to get rid of programs

purge:clean
	rm -f ${DEPENDFILE}.gz ${VARFILE}.gz


${DEPENDFILE}:
	@${CC} -M ${INCLUDES} *${EXT} > $@

${VARFILE}:
	-@ls *${EXT}   | xargs echo SRC_FILES= > $@

# generated dependencies (Needs to go late in the file)
-include ${DEPENDFILE}


static library:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
LIB=${PWD}.a
#	---------------------------------
#	Standard makefile template
#	for libraries, will compile all sources
#	into a library in ..
#
#	shouldn't need to touch anything
#       takes the name from the $PWD
#
#       ..  should be called lib
#	.   MUST be called 'libname' 
#	
#	e.g. source files in:
#		$HOME/lib/libmylib
#
#       will create a library:
#
#		$HOME/lib/libmylib.a
#
#	which is linked like:
#
#	cc source.c -lmylib
#	---------------------------------

# use this for setting variables e.g CFLAGS LDLIBS
# rather than editing this file
USER_FILE = user.mk
-include ${USER_FILE}


AT   = @
RM   = ${AT} rm -f
ECHO = ${AT} echo
LS   = ${AT}ls
CFLAGS += ${INCLUDES}
CXXFLAGS = ${CFLAGS}


ifndef EXT
ERROR: tidy
	@echo  
	@echo  "	you need to define  the filetype: 'EXT'"
	@echo
	@echo  "	i.e 'EXT = .c'"
	@echo  "	or  'EXT = .cc'"
	@echo  "	or  'EXT = .cpp'"
	@echo  
	@echo  "	you can do it in '$(USER_FILE)'" 
	@echo  
	exit
endif 

ifneq ($(EXT),.c)
CC = g++
endif



DEPENDFILE  = depend.mk
VARFILE = var.mk       # generated variables


# if EXT is not defined we need to make it something silly so
# that ls doesn't pick up spurious stuff (see the VARFILE target)
EXT ?= EXT_file_extension_type_not_defined
-include ${VARFILE}

lib:${LIB}

OBJFILES = ${SRC_FILES:${EXT}=.o}

${LIB}:${LIB}(${OBJFILES}) tidy 



help:
	${ECHO} EXT = ${EXT}
	${ECHO} CC = ${CC}
	${ECHO} OBJFILES = ${OBJFILES}
	${ECHO} SRC_FILES = ${SRC_FILES}
	${ECHO} LIB = ${LIB}

tidy:
ifeq (${MAKE_GZIPS},yes)
	@gzip -f  ${DEPENDFILE} ${VARFILE}
endif
	@rm -f  ${DEPENDFILE} ${VARFILE} 
	
clean: tidy
	rm -f  *.o 
	@echo 'make purge' to rm library

purge: clean
	rm -f  ${LIB}
	rm -f ${DEPENDFILE}.gz ${VARFILE}.gz

${VARFILE}:
	-@ls *${EXT}   | xargs echo SRC_FILES= > $@

${DEPENDFILE}:
	@${CC} -M  -I. ${INCLUDES} *${EXT} > $@

-include ${DEPENDFILE}



user.mk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# edit this not the makefiles
#
# ideally you should ln -s to
# the Makefile required


EXT ?= .cpp
INCLUDES ?= -I${HOME}/include -I/usr/local/include   # includes only
LDFLAGS ?= -L${HOME}/lib
LDLIBS ?= -lbill
CFLAGS ?= -Wall -O3
CXXFLAGS ?= -Wall -O3 -std=c++98 # -Weffc++ (man g++)
MAKE_GZIPS ?= no
Last edited on
Topic archived. No new replies allowed.