How to get GNU Make to tell me why it is rebuilding a target - makefile

Is there a way to tell make to show me a list of inputs to a target and which ones are triggering a rebuild because they have been modified?

Yes, you can use the -d option in make to show detailed information about the dependencies and the commands being executed. For example, if you run make -d , make will show a list of the dependencies of the target, as well as the commands being executed and their output.
Additionally, you can use the -n option to show what make would do, without actually executing any commands. This is useful to see which targets would be rebuilt because their dependencies have been modified. For example, if you run make -n , make will show the dependencies of the target and the commands that would be executed, without actually executing them.

Related

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

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.

Rerun execute_process on file change

I am looking for a way to get CMake to re-run a shell command every time it detects that the dependencies for a specific target/executable has changed. I tried adding a custom command the has a dependency on a target, but this does not seem to be doing the trick.
Example of what I thought might work:
ADD_CUSTOM_COMMAND(
OUTPUT temp
DEPENDS my_Target
COMMAND ./some_command.sh)
Any suggestions of a command that may be able to run a command when a dependency change has been detected for a target. Or even better if we can check for a change in specific files.
From your description, it sounds like you might want this:
cmake_minimum_required(VERSION 2.8)
project(cmaketest)
add_custom_command(OUTPUT some_file.cpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.cpp
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/bar.cpp
${CMAKE_CURRENT_BINARY_DIR}/some_file.cpp
VERBATIM
)
add_executable(mn main.cpp some_file.cpp)
Put the output file in the source list of the target which depends on it.
add_custom_command() uses simple check for OUTPUT file existence to determine if the command should be run. If it doesn't exist, then CMake do make my_Target and only then run your command. At the same time, if OUTPUT exist, CMake doesn't run anything at all.
To achieve what you want you need to add_custom_target() (probably with ALL keyword to run it with make) and implement checking for changes inside your some_command.sh.

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'

invoke make from build

I'd like to simplify the workflow so that rather than issuing these commands
$ make program_unittest
... output of $MAKE ...
$ ./program_unittest args
I could have my program automatically attempt to compile itself (if the source has been updated) when it is run, so that I do not have to go back and run make myself.
Here's what I'm thinking: My unit test build should first check if there is a makefile in the directory it's in, and if so, fork and exec make with the target corresponding to itself. If make determines "nothing to be done", it will continue on its way (running the unit-tests). However, if make actually performs a compilation, one of two things may happen. gcc (invoked by make) might be able to overwrite the build (an older version of which is already running) during compilation, in which case I can then perhaps exec it. If my system does not permit gcc to overwrite the program which is in use, then I have to quit the program before running make.
So this has become quite involved already. Are there perhaps more elegant solutions? Maybe I could use a bash script? How do I ascertain if make issued compilation commands or not?
Why not have make run the unit tests?

How can I capture GNUMake differences between two directories

I have a tricky issue with gmake, when I build from the parent directory, something is different and the make does not build all the .o(s) it needs and fails, but if I cd to the directory and do a make it builds them fine.
How can I get GNUmake to tell me the difference between these two runs? There must be some make variables set in the parent that break the child, but I need help figuring out how to track them down.
If running make from the parent directory fails to build foo.o, then try make foo.o. If that fails then try running make -n foo.o in both directories (to print the commands instead of executing them) to see what it's doing differently. If it succeeds, then it's not even trying to build foo.o when run from the parent directory; make -n may shed some light, and as a last resort make -d will give you a torrent of information about the decision process, why it's doing what it's doing.
Here's a handy trick to see the value of variables. Put this rule in your makefile:
show_%:
#echo $# is $($*)
Now you can run make show_FOO and it will tell you the value of the variable FOO.
Finally, are you sure you know where you build your .o files? Make is very good at using things there to build files here, but not the other way around, so it can lose track of intermediate files if you're not careful.

Resources