Frederic wrote:
> Hi, all,
> I am modifying a big program written by somebody else.
> When I modified some ".h" files, say a.h, then I run "make all", but I
> found out make didn't recompile those files which included "a.h" file. In
> my case "a.h" has some inline functions, so I have to manually remove
> those .o files in order to get a fresh incremental build.
> My question is: is this phenomenon caused by bad-wrritten make files or I
> misunderstood the functionality of make? Thanks.
> ===============================================================================================
> |Frederic |
> | |
> |The road goes ever on and on. |
> | - Bilbo Baggins |
> ===============================================================================================
I do not know that the question is stupid. There are a lot of bad
makefiles out there, so this is a common problem. A pity, too, since the
C and C++ compilers make the job so easy.
I make my makefiles automagically, nearly.
Here is a stripped-down prototype makefile, basic.mk:
# Copyright (C) 2001 Jean-David Beyer
# This program is free software; you can redistribute it and/or
# [GNU license. etc.]
DEBUG_FLAG = -g
OPT_LEVEL = -O6
OBJS = TEST5.o UG5.o
AR = /usr/bin/ar
CAT = /bin/cat
CHMOD = /bin/chmod
CP = /bin/cp
CXX = /usr/bin/g++
ECHO = /bin/echo
RM = /bin/rm
SOURCES = ${OBJS:.o=.cc}
.SUFFIXES : .o .cc
MY_BIN = ${MY_ROOT}/bin
MY_HEADERS = ${MY_ROOT}/include
MY_LIB = ${MY_ROOT}/lib
MY_ROOT = /home/jdbeyer
MY_STOCKS = ${MY_ROOT}/stocks
MY_STOCK_HEADERS = ${MY_STOCKS}/include
MY_STOCK_LIB = ${MY_STOCKS}/lib
IBM_DB2_PATH = ${IBM_DB2_ROOT}/sqllib
IBM_DB2_BIN = ${IBM_DB2_PATH}/bin
IBM_DB2_DB2 = ${IBM_DB2_BIN}/db2
IBM_DB2_SAM_CPP = ${IBM_DB2_PATH}/samples/cpp
IBM_DB2_HEADERS = ${IBM_DB2_PATH}/include
IBM_DB2_LIB = ${IBM_DB2_PATH}/lib
SYS_CXX_HEADERS = /usr/include/g++-3
#SYS_LIB = /usr/lib
SYS_LIB = /usr/i386-glibc21-linux/lib
CXX_FLAGS = ${DEBUG_FLAG} ${OPT_LEVEL}
CXX_INCLUDES = -I${MY_HEADERS} -I${MY_STOCK_HEADERS} \
-I${IBM_DB2_HEADERS} -I${SYS_CXX_HEADERS}
CXX_LIBS = -L${MY_STOCK_LIB} -L${MY_LIB} -L${IBM_DB2_LIB}
BTD5
all: TEST5 UG5
UG5: UG5.o ${MY_STOCK_LIB}/libstock.a ${MY_LIB}/libmine.a
${CXX} ${DEBUG_FLAG} ${CXX_LIBS} \
-Wl,--dynamic-linker ${SYS_LIB}/ld-linux.so.2 \
-Wl,-L,${IBM_DB2_LIB},-L${SYS_LIB} \
-Wl,-rpath,${IBM_DB2_LIB},-rpath,${SYS_LIB} \
-o $@ UG5.o \
-lstock -lmine \
-ldb2 ${SYS_LIB}/libc.so
TEST5: TEST5.o ${MY_STOCK_LIB}/libstock.a ${MY_LIB}/libmine.a
${CXX} ${DEBUG_FLAG} ${CXX_LIBS} \
-Wl,--dynamic-linker ${SYS_LIB}/ld-linux.so.2 \
-Wl,-L,${IBM_DB2_LIB},-L${SYS_LIB} \
-Wl,-rpath,${IBM_DB2_LIB},-rpath,${SYS_LIB} \
-o $@ TEST5.o \
-lstock -lmine \
-ldb2 ${SYS_LIB}/libc.so
.cc.o:
${CXX} -c ${CXX_FLAGS} ${CXX_INCLUDES} $<
install: UG5 TEST5
${CAT} TEST5 > ${MY_BIN}/TEST5
${CAT} UG5 > ${MY_BIN}/UG5
clean:
${RM} -f ${OBJS} testit.o
${RM} -f TEST5.cc~ UG5.cc~
${RM} -f basic.mk~ makefile~
clobber: clean
${RM} -f TEST5 UG5
makefile : basic.mk ${MY_HEADERS}/myLib.H ${MY_STOCK_HEADERS}/dbBase.H
${RM} -f $@
${ECHO} "# This makefile automatically generated." > $@
${ECHO} "# It is made from basic.mk." >> $@
${ECHO} "# Do not bother to modify this makefile directly." >> $@
${ECHO} " " >> $@
${CAT} basic.mk >> $@
${ECHO} '# Automatically-generated dependencies list:' >> $@
${CC} ${CFLAGS} -M ${CXX_INCLUDES} ${SOURCES} >> $@
${CHMOD} -w $@
The stuff of principle interest is mainly the stuff just above, starting
with
makefile :
If I run
make -f basic.mk makefile,
I get a makefile that that looks, in part, like this:
# This makefile automatically generated.
# It is made from basic.mk.
# Do not bother to modify this makefile directly.
# Copyright (C) 2001 Jean-David Beyer
# This program is free software; you can redistribute it and/or
# [rest of GPL]
# jdbe...@exit109.com
DEBUG_FLAG = -g
OPT_LEVEL = -O6
[snip]
# Automatically-generated dependencies list:
TEST5.o: TEST5.cc /usr/include/g++-3/iostream \
/usr/include/g++-3/iostream.h /usr/include/g++-3/streambuf.h \
/usr/include/libio.h /usr/include/_G_config.h
/usr/include/bits/types.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
/usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h \
/usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
/usr/include/g++-3/string /usr/include/g++-3/std/bastring.h \
/usr/include/g++-3/cstddef /usr/include/g++-3/std/straits.h \
/usr/include/g++-3/cctype /usr/include/ctype.h /usr/include/endian.h \
/usr/include/bits/endian.h /usr/include/g++-3/cstring \
/usr/include/string.h /usr/include/g++-3/alloc.h \
/usr/include/g++-3/stl_config.h /usr/include/g++-3/stl_alloc.h \
/usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
/usr/include/sys/select.h /usr/include/bits/select.h \
/usr/include/bits/sigset.h /usr/include/bits/time.h \
/usr/include/sys/sysmacros.h /usr/include/alloca.h \
/usr/include/assert.h /usr/include/pthread.h /usr/include/sched.h \
/usr/include/signal.h /usr/include/bits/initspin.h \
/usr/include/bits/sigthread.h /usr/include/g++-3/iterator \
/usr/include/g++-3/stl_relops.h /usr/include/g++-3/stl_iterator.h \
/usr/include/g++-3/std/bastring.cc /usr/include/math.h \
/usr/include/bits/huge_val.h /usr/include/bits/mathdef.h \
/usr/include/bits/mathcalls.h /usr/include/unistd.h \
/usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
/usr/include/getopt.h /home/jdbeyer/stocks/include/db_dates.H \
/home/jdbeyer/include/myLib.H
/home/jdbeyer/stocks/include/stock_item.H \
/home/jdbeyer/stocks/include/testDerived.H \
/home/jdbeyer/stocks/include/dbBase.H /usr/include/stdio.h \
/usr/include/bits/stdio_lim.h /home/jdbeyer/stocks/include/utils.H
UG5.o: UG5.cc /usr/include/g++-3/iostream
/usr/include/g++-3/iostream.h \
/usr/include/g++-3/streambuf.h /usr/include/libio.h \
/usr/include/_G_config.h /usr/include/bits/types.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
/usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h \
/usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
/usr/include/g++-3/string /usr/include/g++-3/std/bastring.h \
/usr/include/g++-3/cstddef /usr/include/g++-3/std/straits.h \
/usr/include/g++-3/cctype /usr/include/ctype.h /usr/include/endian.h \
/usr/include/bits/endian.h /usr/include/g++-3/cstring \
/usr/include/string.h /usr/include/g++-3/alloc.h \
/usr/include/g++-3/stl_config.h /usr/include/g++-3/stl_alloc.h \
/usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
/usr/include/sys/select.h /usr/include/bits/select.h \
/usr/include/bits/sigset.h /usr/include/bits/time.h \
/usr/include/sys/sysmacros.h /usr/include/alloca.h \
/usr/include/assert.h /usr/include/pthread.h /usr/include/sched.h \
/usr/include/signal.h /usr/include/bits/initspin.h \
/usr/include/bits/sigthread.h /usr/include/g++-3/iterator \
/usr/include/g++-3/stl_relops.h /usr/include/g++-3/stl_iterator.h \
/usr/include/g++-3/std/bastring.cc /usr/include/math.h \
/usr/include/bits/huge_val.h /usr/include/bits/mathdef.h \
/usr/include/bits/mathcalls.h /usr/include/unistd.h \
/usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
/usr/include/getopt.h /home/jdbeyer/stocks/include/db_dates.H \
/home/jdbeyer/include/myLib.H
/home/jdbeyer/stocks/include/stock_item.H \
/home/jdbeyer/stocks/include/ugDerived.H \
/home/jdbeyer/stocks/include/dbBase.H /usr/include/stdio.h \
/usr/include/bits/stdio_lim.h /home/jdbeyer/stocks/include/utils.H
Now if you make all, TEST5, or UG5, it will consider all those header
files to determine what to rebuild. If someone changed stdio_lim.h, for
example, it would cause recompilation, and stdio_lim.h does not appear
in any of the header files that I explicitly called for in the files
being compiled.
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 73926.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 7:55pm up 8 days, 22:29, 2 users, load average: 2.24, 2.19, 2.11