How do you force a makefile to rebuild a target?
You could declare one or more of your targets to be phony.
A phony target is one that is not really the name of a file; rather it
is just a name for a recipe to be executed when you make an explicit
request. There are two reasons to use a phony target: to avoid a
conflict with a file of the same name, and to improve performance....
A phony target should not be a prerequisite of a real target file; if
it is, its recipe will be run every time make goes to update that
file. As long as a phony target is never a prerequisite of a real
target, the phony target recipe will be executed only when the phony
target is a specified goal
How to force make to always rebuild a file
The classic way to do it is:
version.o: .FORCE
.FORCE:
(and you might add .PHONY: .FORCE
). The file '.FORCE' is presumed not to exist, so it is always 'created', so version.o
is always out of date w.r.t it, so version.o
is always compiled.
I'm not sure that making version.o
into a phony file is correct; it is actually a real file, not a phony one.
Is there a way to force rebuilding a target (make -B) without rebuilding its dependencies?
One way is to use the -o
option for all targets you don't want to be remade:
-o FILE, --old-file=FILE, --assume-old=FILE
Consider FILE to be very old and don't remake it.
EDIT
I think you're misreading the documentation for -B
; it says:
-B, --always-make
Unconditionally make all targets.
Note, the all targets here; huge
is certainly a target, and so if you use -B
it will be remade.
However, I also misread your question a bit. I thought you wanted to rebuild small
without rebuilding huge
even though huge
is new, but you're trying to get small
to be rebuilt even though huge
has not changed, right?
You definitely don't want to use -B
. That option is not at all what you are looking for.
Normally people would do that by deleting small
:
rm -f small
make small
It might be useful to have an option that forced a given target to be recreated, but that option doesn't exist.
You could use -W huge
, but again this means you need to know the name of the prerequisite not just the target you want built.
How do I force make to clean and recompile after changes to Makefile itself?
What you have can't work because after make clean
the $(EXEC)
file won't exist, so it's always out of date, so it's always rebuilt, and the rebuild will run clean
then re-exec itself, so again it will be out of date, so again make will run clean
then re-exec itself, etc.
To do what you want you need to list the makefile as a prerequisite of all of the targets. Then you don't need to run clean
or re-run make
, because all the targets will be out of date when the makefile changes, just as they'd be out of date if the source file changed. So, as an example, add Makefile
as a prerequisite to your object file targets:
%.o : %.c Makefile
$(CC) $(CFLAGS) -c -o $@ $<
Without knowing anything about the rest of your makefile we can't give more specific advice than that.
How do I force a target to be rebuilt if a variable is set?
Here is a general solution to your specific problem.
You want to be able to depend on a variable as a prerequisite. That is, you can make it a prerequisite to any target in your makefile, and when the value of the variable changes, you rebuild those targets.
Here is a function that does that, you use this function to declare a variable to be dependable, and then you can use it as a prerequisite.
Note that if the variable is not used on the command line, it will still mean that variable still has a value, namely, the empty string.
define DEPENDABLE_VAR
.PHONY: phony
$1: phony
@if [[ `cat $1 2>&1` != '$($1)' ]]; then \
echo -n $($1) > $1 ; \
fi
endef
#declare ARGS to be dependable
$(eval $(call DEPENDABLE_VAR,ARGS))
foo:foo.c ARGS
$(CC) $(CFLAGS) $(ARGS) -c foo.c -o foo
In fact, we could omit the need for "declaration", and just write a similar function that will make all variables dependable by default. But I don't like that. I prefer that the users that modify makefiles I write, declare their intentions explicitly. It is good for them :)
How the forcing rebuild in my Makefile actually work?
From the manual:
One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the recipe is executed.
In your case you have two rules for the app target. The prerequisite .force_rebuild
from the first rule is marked as .PHONY, which makes your app target always older than .force_rebuild
. This triggers execution of the recipe for the app target. That recipe is in the second rule.
Just in case, also pointing out the paragraph following the above quote:
There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message.
Force gnu make to rebuild objects affected by compiler definition
I use a file to remember the last value of such options, like this:
.PHONY: force
compiler_flags: force
echo '$(CC_FLAGS)' | cmp -s - $@ || echo '$(CC_FLAGS)' > $@
The cmp || echo
bit means the file compiler_flags
is only touched when the setting changes, so now you can write something like
$(OBJECTS): compiler_flags
to cause a rebuild of $(OBJECTS)
whenever the compiler flags change. The rule for compiler_flags will be executed every time you run make, but a rebuild of $(OBJECTS)
will be triggered only if the compiler_flags
file was actually modified.
Related Topics
What Is the Meaning of "Posix"
How to Change the Root Directory of an Apache Server
What's the Magic of "-" (A Dash) in Command-Line Parameters
Environment Variable Substitution in Sed
Forcing Bash to Expand Variables in a String Loaded from a File
Pipe To/From the Clipboard in a Bash Script
Find and Replace With Sed in Directory and Sub Directories
Can Windows Containers Be Hosted on Linux
How to Install Gcc 4.9.2 on Rhel 7.4
Command Line Program to Create Website Screenshots (On Linux)
How to Use Sed to Change My Configuration Files, With Flexible Keys and Values
Cronjob Does Not Execute a Script That Works Fine Standalone
Exploring Docker Container'S File System
"Failed to Load Platform Plugin "Xcb" " While Launching Qt5 App on Linux Without Qt Installed