stupid make question

stupid make question

Post by Frederi » Sat, 28 Jun 2003 06:06:16



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                                                                |
===============================================================================================

 
 
 

stupid make question

Post by Robert Helle » Sat, 28 Jun 2003 07:14:16



  In a message on Thu, 26 Jun 2003 17:06:16 -0400, wrote :

F> Hi, all,
F>
F> I am modifying a big program written by somebody else.
F> When I modified some ".h" files, say a.h, then I run "make all", but I
F> found out make didn't recompile those files which included "a.h" file. In
F> my case "a.h" has some inline functions, so I have to manually remove
F> those .o files in order to get a fresh incremental build.
F>
F> My question is: is this phenomenon caused by bad-wrritten make files or I
F> misunderstood the functionality of make? Thanks.

It is bad written make files.  'Make' is not super human, you need to
list *all* of the dependencies.

There are two options:

1) *Manually* listing all of the .h files:

foo.o : foo.c a.h b.h c.h ...

2) Use the c preprocessor to generate the header dependencies:

Typical makefile fragment:

HEADERS = Character.h Record.h Dice.h Monster.h Spells.h Dressings.h Space.h
LSRCS = Character.cc Dice.cc Monster.cc Spells.cc Dressings.cc Space.cc
CXX             = c++
BaseCXXFLAGS    = -g -O2
DEFS            =  -DSTDC_HEADERS=1 -DSIZEOF_LONG=4 -DSIZEOF_INT=4 -DHAVE_BOOL=1
SHLIB_CFLAGS    = -fPIC
INCLUDES        = -I.
CXXFLAGS = $(DEFS) $(BaseCXXFLAGS) $(SHLIB_CFLAGS) $(INCLUDES) -c -Wall

# other defs and rules ommited

# Make sure some target depends on .depend (I usually include .depend on
# the 'all' target).

.depend: $(LSRCS) $(HEADERS)
        $(CXX) -M $(CXXFLAGS) $(LSRCS)  > .depend
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

man gcc (-M):

       -M  [ -MG ]
              Tell the preprocessor to output a rule suitable for
              make describing the  dependencies  of  each  object
              file.   For each source file, the preprocessor out<AD>
              puts one make-rule whose target is the object  file
              name  for  that  source file and whose dependencies
              are all the files `#include'd in it.  This rule may
              be  a single line or may be continued with `\'-new<AD>
              line if it is long.  The list of rules  is  printed
              on  standard  output  instead of the preprocessed C
              program.

              `-M' implies `-E'.

              `-MG' says to treat missing header files as  gener<AD>
              ated  files and assume they live in the same direc<AD>
              tory as the source file.  It must be  specified  in
              addition to `-M'.

F>
F> ===============================================================================================
F> |Frederic                                                                                     |
F> |                                                                                             |
F> |The road goes ever on and on.                                                                |
F> |              - Bilbo Baggins                                                                |
F> ===============================================================================================
F>                                                                                                                

 
 
 

stupid make question

Post by Frederi » Sat, 28 Jun 2003 08:03:20


Thank you very much. This is the most informative answer I got.

I just refreshed my make knowledge and read all the makefiles in the
directories and found out the original author simply left out all the
".h" into consideration. I am just amazed that this problem had remained
uncovered for so long(since 1995). The program is a very large scientific
computation software and a few Profs and Ph.Ds use brute-force method to develop a
program with millions of lines of code. There is no design documents at
all. Maybe because most of the original authors were using Fortran before
and Fortran doesn't have the notion of header files.



>   In a message on Thu, 26 Jun 2003 17:06:16 -0400, wrote :

> F> Hi, all,
> F>
> F> I am modifying a big program written by somebody else.
> F> When I modified some ".h" files, say a.h, then I run "make all", but I
> F> found out make didn't recompile those files which included "a.h" file. In
> F> my case "a.h" has some inline functions, so I have to manually remove
> F> those .o files in order to get a fresh incremental build.
> F>
> F> My question is: is this phenomenon caused by bad-wrritten make files or I
> F> misunderstood the functionality of make? Thanks.

> It is bad written make files.  'Make' is not super human, you need to
> list *all* of the dependencies.

> There are two options:

> 1) *Manually* listing all of the .h files:

> foo.o : foo.c a.h b.h c.h ...

> 2) Use the c preprocessor to generate the header dependencies:

> Typical makefile fragment:

> HEADERS = Character.h Record.h Dice.h Monster.h Spells.h Dressings.h Space.h
> LSRCS = Character.cc Dice.cc Monster.cc Spells.cc Dressings.cc Space.cc
> CXX             = c++
> BaseCXXFLAGS    = -g -O2
> DEFS            =  -DSTDC_HEADERS=1 -DSIZEOF_LONG=4 -DSIZEOF_INT=4 -DHAVE_BOOL=1
> SHLIB_CFLAGS    = -fPIC
> INCLUDES        = -I.
> CXXFLAGS = $(DEFS) $(BaseCXXFLAGS) $(SHLIB_CFLAGS) $(INCLUDES) -c -Wall

> # other defs and rules ommited

> # Make sure some target depends on .depend (I usually include .depend on
> # the 'all' target).

> .depend: $(LSRCS) $(HEADERS)
>         $(CXX) -M $(CXXFLAGS) $(LSRCS)  > .depend
> #
> # include a dependency file if one exists
> #
> ifeq (.depend,$(wildcard .depend))
> include .depend
> endif

> man gcc (-M):

>        -M  [ -MG ]
>               Tell the preprocessor to output a rule suitable for
>               make describing the  dependencies  of  each  object
>               file.   For each source file, the preprocessor out<AD>
>               puts one make-rule whose target is the object  file
>               name  for  that  source file and whose dependencies
>               are all the files `#include'd in it.  This rule may
>               be  a single line or may be continued with `\'-new<AD>
>               line if it is long.  The list of rules  is  printed
>               on  standard  output  instead of the preprocessed C
>               program.

>               `-M' implies `-E'.

>               `-MG' says to treat missing header files as  gener<AD>
>               ated  files and assume they live in the same direc<AD>
>               tory as the source file.  It must be  specified  in
>               addition to `-M'.

> F>
> F> ===============================================================================================
> F> |Frederic                                                                                     |
> F> |                                                                                             |
> F> |The road goes ever on and on.                                                                |
> F> |              - Bilbo Baggins                                                                |
> F> ===============================================================================================
> F>

 
 
 

stupid make question

Post by Jean-David Beye » Sat, 28 Jun 2003 09:16:11


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

 
 
 

1. --stupid question but then there are no stupid questions--

        I'm a beginner here so, so far everything i read has gone
    way over my head. My problem is I got a script sent to me
    decoded or something like that. You are supposed to enter the
    data into a uudecode or something but I'm not sure how that's
    done. There's a program on the university's main menu that
    called UUDECODE but everytime I run it through it, it says it
    can't open the file. Comments ??????? Help ?

        eric

2. TERMINATED: Rev Nutjob FormedByShit

3. Stupid or not so stupid questions

4. Who can install the driver for EP-4101 that is Fast-Ethernet in PCMCIA

5. Stupid, stupid question

6. Trouble at slashdot.org?

7. One stupid question and one not so stupid

8. Printing to Apple Laserwriter

9. REALLY STUPID QUESTIONS (not so stupid)

10. stupid choice = another stupid newbie question

11. STUPID STUPID question

12. Stupid Newbie asks a stupid question

13. Stupid, stupid, stupid...