[C++] How do you force a makefile to rebuild a target


Answers

The -B switch to make, whose long form is --always-make, tells make to disregard timestamps and make the specified targets. This may defeat the purpose of using make, but it may be what you need.

Question

I have a makefile that builds and then calls another makefile. Since this makefile calls more makefiles that does the work it doesnt really change. Thus it keeps thinking the project is built and upto date.

dnetdev11 ~ # make
make: `release' is up to date.

How do i force the makefile to rebuild the target?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

Note: Names removed to protect the innocent

Edit: Final Fixed version:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib






This simple technique will allow the makefile to function normally when forcing is not desired. Create a new target called force at the end of your makefile. The force target will touch a file that your default target depends on. In the example below, I have added touch myprogram.cpp. I also added a recursive call to make. This will cause the default target to get made every time you type make force.

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make



If you don't need to preserve any of the outputs you already successfully compiled

nmake /A 

rebuilds all




Someone else suggested .PHONY which is definitely correct. .PHONY should be used for any rule for which a date comparison between the input and the output is invalid. Since you don't have any targets of the form output: input you should use .PHONY for ALL of them!

All that said, you probably should define some variables at the top of your makefile for the various filenames, and define real make rules that have both input and output sections so you can use the benefits of make, namely that you'll only actually compile things that are necessary to copmile!

Edit: added example. Untested, but this is how you do .PHONY

.PHONY: clean    
clean:
    $(clean)



On my Linux system (Centos 6.2), there is a significant difference between declaring the target .PHONY and creating a fake dependency on FORCE, when the rule actually does create a file matching the target. When the file must be regenerated every time, it required both the fake dependency FORCE on the file, and .PHONY for the fake dependency.

wrong:

date > $@

right:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE



I tried this and it worked for me

add these lines to Makefile

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

save and now call

make new 

and it will recompile everything again

What happened?

'new' calls clean 'clean' do 'rm' which removes all object files that have the extension of '.o' 'new' calls 'make'. 'make' see that there is no '.o' files so it goes ahead and creates all the '.o' again. then the linker links all of the .o file int one executable output

Good luck