Force run a recipe (--assume-old=target) - makefile

I want to force a recipe for "output.file", even though it is up-to-date.
I have already tried make --assume-old=output.file output.file, but it does not run the recipe again.
In case you are curious: use case:
I want to use this together with --dry-run to find out the command that produce a target.
I ended up hiding the file to run make --dry-run output.file, but I was hoping for something more elegant + FMI: for future debugging makefile.

I think you're misunderstanding what that option does: it does exactly the opposite of what you hoped; from the man page:
-o file, --old-file=file, --assume-old=file
Do not remake the file file even if it is older than its dependen‐
cies, and do not remake anything on account of changes in file.
Essentially the file is treated as very old and its rules are
ignored.
You want output.file to be remade, so using -o is clearly not what you want.
There is no option in GNU make to say "always rebuild this target". What you can do is tell make to pretend that some prerequisite of the target you want to be rebuilt has been updated. See this option:
-W file, --what-if=file, --new-file=file, --assume-new=file
Pretend that the target file has just been modified. When used
with the -n flag, this shows you what would happen if you were to
modify that file. Without -n, it is almost the same as running a
touch command on the given file before running make, except that
the modification time is changed only in the imagination of make.
Say for example your output.file had a prerequisite input.file. Then if you run:
make -W input.file
it will show you what rules it would run, which would include rebuilding output.file.

Related

Makefile execution properly [duplicate]

I tried to use a make file in code::blocks but I am doing it wrong. I have the version installed with the compilers included. http://sourceforge.net/projects/codeblocks/files/Binaries/10.05/Windows/codeblocks-10.05mingw-setup.exe/download. What do I do with the make file? It starts with:
CC=gcc
best, US
You don't tend to execute the make file itself, rather you execute make, giving it the make file as an argument:
make -f pax.mk
If your make file is actually one of the standard names (like makefile or Makefile), you don't even need to specify it. It'll be picked up by default (if you have more than one of these standard names in your build directory, you better look up the make man page to see which takes precedence).
As paxdiablo said make -f pax.mk would execute the pax.mk makefile, if you directly execute it by typing ./pax.mk, then you would get syntax error.
Also you can just type make if your file name is makefile/Makefile.
Suppose you have two files named makefile and Makefile in the same directory then makefile is executed if make alone is given. You can even pass arguments to makefile.
Check out more about makefile at this Tutorial : Basic understanding of Makefile

Make is deleting my target. Why?

From the docs:
Usually when a recipe line fails, if it has changed the target file
at all, the file is corrupted and cannot be used--or at least it is not
completely updated. Yet the file's time stamp says that it is now up to
date, so the next time 'make' runs, it will not try to update that file.
The situation is just the same as when the shell is killed by a signal;
*note Interrupts::. So generally the right thing to do is to delete the
target file if the recipe fails after beginning to change the file.
'make' will do this if '.DELETE_ON_ERROR' appears as a target. This is
almost always what you want 'make' to do, but it is not historical
practice; so for compatibility, you must explicitly request it.
So, here I have a makefile:
# The idea here is to auto-generate the file ('make.include')
# and to use it as a makefile.
# For simplicity, I replaced the "auto-generate" part, with "touch".
# I also simplified the dependency-tree with 'phony'.
# In practice, we re-generate, only when "need" to.
make.include : phony
+touch '$#'
make -f '$#'
.PHONY: phony
Running:
$ make -q
I get:
touch 'make.include'
make: *** Deleting file 'make.include'
Now, i don't see how to prevent make from deleting this newly auto-generated 'make.include' (which may well be quite a costly process to re-run), unless i resort to the .PRECIOUS special target.
But, demanding the user to explicitly define their "precious" targets, is not in-line with that quote from the docs above. Right?
This arises because of your use of + in +touch '$#' and executing make with the -q option. From the GNU Make Manual the -q option is
“Question mode”. Do not run any recipes, or print
anything; just return an exit status that is zero if the specified
targets are already up to date, one if any remaking is required, or
two if an error is encountered. See Instead of Executing Recipes.
The + symbol is only relevant when make is executed with the -t, -n or -q options and it tells make to execute any commands it precedes make is executed with any of the options -t, -n or -q. So, when you execute your current makefile with make -q you are asking make to check if everything is up to date without running any commands but because you've specified + before touch '$#' make must execute this command. To then leave everything the way it was before you executed make -q make must delete the file it created with +touch '$#'.
To answer your question specifically. If you don't want make to delete make.include then you can run make without the -q option on the makefile specified in your question.
However, the recipe for a target, i.e. make.include should not call its self with make -f make.include. It would probably be better to rewrite the makefile so that the recipe for make.include only creates make.include and it is then called with make -f make.include in another recipe.
make.include:
+touch $#
all: make.include
make -f $<

What's the possible reason that makefile would skip making one executable?

I try to then execute exact same compilation command for that skipped file and it is being correctly compiled. But when I put it in make file it is just skipped. Every other file is generated.
Without actually seeing the makefile (which you haven't provided), we can only guess (though I'd like to think it's an educated guess).
Since make works by checking file timestamps to see if they need rebuilding, that's one thing to look at. If the timestamp of a target is later than that of all dependencies, the target won't be built.
The other is to ensure your top level rule actually has a dependency on what you're trying to build, somewhere in the hierarchy. By that I mean the ruleset:
all: xyzzy
xyzzy:
touch xyzzy
plugh:
touch plugh
with the command make all will never touch plugh because it's not in the dependency hierarchy off all.
And make generally provides command line options for debugging (like the -d flag in GNU Make) which will tell you why it's making the decisions it's making. If you want to understand what's happening, you should probably use them,a s it makes it that much easier to debug your makefile.

Can I refer to the default target on the "make" command line?

If I type just
$ make
it will invoke the make command with the default target (typically the first target specified in the Makefile, but the rules are a bit more complicated than that).
Is there a way to specify the default target on the command line without knowing what it is, other than by simply omitting the target name?
What I'd like to be able to do is combine these two commands:
$ make clean
$ make
into a single invocation of make. If I happen to know that the default target is all, I can type:
$ make clean all
but that doesn't work if I don't know what the default target is.
Ideally, I'd like some syntax that refers to the default target (the GNU make manual calls it the "default goal"). This:
$ make clean .DEFAULT_GOAL
shows the general idea, but it doesn't work.
Second best would be a simple and reliable way to determine, from the command line, what the default target is:
$ make clean $(get-default-target)
A GNU-specific solution would be ok.
I suspect, from a quick look into the manual, that there's no good way to do this.
For a shot at the second-best solution, you can parse the default goal from the output of make -pq:
make -pq | sed -ne 's/^.DEFAULT_GOAL := //p'

How can I ctreate a simple makefile for minGW + gfortran

I am absolutely new in gfortran+minGW.
I need to create makefile.
When I run
$ gfortran -c q.f
All is ok!
But how can I run makefile like this?
CC = gfortran
q.o : q.f
$(CC) -c q2.o q2.f
I receive error “CC: command not found”.
(OS – Win 7 (64))
Tanks!!!
It kind of looks like you're trying to run the makefile as a regular script. Try
$ make
or
$ make -f mymakefilename
if you named the file something other than "makefile" or "Makefile".
You can potentially just execute the makefile, but if so you need a "shebang" line, something like
#!/usr/bin/make
at the top of the file, but frankly hardly anyone uses that option. Just use the make(1) command.
Update
It's because they're in the wrong order. Makefiles process (by default) the first target in the file. When you run make it sees the rule to make, q.o from q.f, it compiles it, and says, "Okay, I'm done."
If you put the q.exe target first, it says "Hmmm, I want to build q.exe and to do that I need a q.o. Do I have a q.o? No? Okay, hen I'll build a q.o. I have a rule for that -- I can build a q.o from q.f. okay, that's done. Now can I build q.exe? Oh, yes, I can. I'll build q.exe. Anything? Nope, I'm done."
If you were to use the commend
$ make q.exe
then you'd explicitly tell make to make q.exe, which would cause the same thing to happen, but better you should reorder your makefile and get used to the way they work.

Resources