BACKGROUND
This is related to my question GNU make - transform every prerequisite into target (implicitly)
I've posted this question because it's interesting and may be useful by itself - to understand make - and I don't want it to get lost in the "original" question.
INFO
I have a file Dummy.mk:
%:: null
#:
null:
#:
which I pass to my make as make all MAKEFILES=Dummy.mk.
When I replace null with saflkjsaflkjdsa,
%:: saflkjsaflkjdsa
#:
saflkjsaflkjdsa:
#:
the behavior of the build was different: the rule was never executed.
The reason is because this is a "terminal rule":
One choice is to mark the match-anything rule as terminal by defining
it with a double colon. When a rule is terminal, it does not apply
unless its prerequisites actually exist. Prerequisites that could be
made with other implicit rules are not good enough. In other words, no
further chaining is allowed beyond a terminal rule.
Since saflkjsaflkjdsa did not exist, the rule was not executed. Ok fine I understand that.
But when I set Dummy.mk using the keyword null
%:: null
#:
null:
#:
the %:: rule does execute i.e. it captures ALL targets, filenames, etc giving me outputs of the form :2: update target <item> due to: null where <item> is any filename or target that make reads in.
Since the rule is executing using null but not with using saflkjsaflkjdsa, make is definitely detecting null as "existing".
QUESTION
But then why do I still get the output :5: target 'null' does not exist?
Is that because of the OS- or shell-level peculiarities of null existing but not existing at the same time?
Environment
* Windows 8, 64-bit
* Make 4.2.1 (here's output of make
# GNU Make 4.2.1
# Built for Windows32
# Copyright (C) 1988-2016 Free Software Foundation, Inc.
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
find_and_set_shell() path search set default_shell = C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe
...
* Shell that make is using internally is:
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>where sh
C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>sh --help
GNU bash, version 3.1.17(1)-release-(i686-pc-msys)
Usage: sh [GNU long option] [option] ...
sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.
Is that because of the OS- or shell-level peculiarities of null existing but not existing at the same time?
Since you didn't specify which OS or shell you're using, it's impossible for us to say. All I can say is that I tried to replicate your problem on my GNU/Linux system and couldn't: on my system no targets were built in either case (using null or saflkjsaflkjdsa made no difference)
My suspicion is you're using Windows; I have a vague recollection that null is special somehow on Windows. But, I don't do Windows so I can't say for sure.
Related
I have a Makefile, which fails at some point, with a git error. How can I view the git command that causes the whole make process to fail? More precisely, I am looking for a list of commands (including the ones that start with #) that I can run on an identical setup, to achieve the same effect as what make does.
I know for a script, instead of #! /bin/bash you would add a flag -x to it, and that would display all the commands before their execution. How do I do the same thing for make?
I am looking for a list of commands (including the ones that start with #) that I can run on an identical setup, to achieve the same effect as what make does.
By default, make echoes all recipe commands it runs, except those prefixed with #. The POSIX specifications for make do not describe a way to override that effect of # (but see below). It is conceivable that your make has an extension for that, but the make implementations you are most likely to be using (GNU make or BSD make, since you seem to assume that your standard shell is bash) do not.
Additionally, in POSIX-conforming make implementations, including the two mentioned above, the special target .SILENT can be used to suppress echoing the commands of some or all targets, and the -s command-line option can be used to suppress echoing for all targets.
You can print recipe commands prefixed with # if you run make with the -n (no-op) flag. That will print the commands for out-of-date targets without running them, except that those prefixed with a + are run even in no-op mode. Commands prefixed with # are included among those printed. Under some circumstances, the fact that most commands are not actually run in this mode can affect the output, but all the cases I can think of at the moment involve recursive make, and I think they are fairly unlikely.
POSIX seems to indicate that -n does not override -s or .SILENT, so if you have to deal with those then you may have no alternative but to modify your makefile. If you happen to be using GNU make, however, you will find that -n does override .SILENT and -s in that implementation. The same may be true of other makes.
The following Makefile target doesn't fail:
test:
echo `blah`
How can I can make it fail besides running the backticked command on its own on the previous line.
$ make --version
GNU Make 4.0
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
This isn't a make problem, not really. Make simply waits for the shell it invoked to finish, then checks the exit code. If it's 0 (success) then make assumes the job succeeded. If it's any other value, make believes the job failed.
If you run this command at the shell, you'll see that the exit code is not preserved:
$ echo `bah`
...errors...
$ echo $?
0
There's nothing make can do about this. You'll have to find a way to ensure that your command exits with a failure. You haven't given us enough information about what actual command you want to run to help you solve this problem.
ETA
There are lots of possibilities. But since you've still not provided any real specifics, I'll just suggest one possibility: you can test the resulting value to see if it was empty or not:
test:
var=`blah`; [ -n "$$var" ] || exit 1; ...do stuff with $$var...
I'm working on a project which requires using make.
From the command like I run either make Release or make Debug.
However, there is not a makefile in the directory in which I run the make command.
How can I tell which makefile the make command is using?
In GNU make you can use the make variable MAKEFILE_LIST to inspect which makefile(s) were read; yes, there can be more than one due to multiple -f options and include directives.
If you need the name of the last read makefile, use $(lastword $(MAKEFILE_LIST)).
See also the GNU make manual.
GNU make has a debug option. If you use -d, make will print all debugging output.
The debug level can be changed with --debug[=FLAGS].
--debug=v should show you which makefiles were parsed.
GNU make manual:
v (verbose):
A level above ‘basic’; includes messages about which makefiles were parsed, prerequisites that did not need to be rebuilt, etc. This option also enables ‘basic’ messages.
See the man page for additional information.
I see that this is the same question as
Making cmake print commands before executing
But that answer doesn't work for me. I'm guessing that answer only works with cmake. What options work without cmake?
Note tried these
make VERBOSE=1 target
make target VERBOSE=1
VERBOSE=1 make target
make V=1 target
make target V=1
V=1 make target
make -V target
make -v target
none of them worked.
make -v returns
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
By default, make does print every command before executing it. This printing can be suppressed by one of the following mechanisms:
on a case-by-case basis, by adding # at the beginning of the command
globally, by adding the .SILENT built-in target.
somewhere along the make process, by invoking sub-make(s) with one of the flags -s, --silent or --quiet, as in $(MAKE) --silent -C someDir, for example. From that moment on, command echoing is suppressed in the sub-make.
If your makefile does not print the commands, then it is probably using one of these three mechanisms, and you have to actually inspect the makefile(s) to figure out which.
As a workaround to avoid these echo-suppressing mechanisms, you could re-define the shell to be used to use a debug mode, for example like make SHELL="/bin/bash -x" target. Other shells have similar options. With that approach, it is not make printing the commands, but the shell itself.
If you use the flag -n or --just-print, the echo-suppressing mechanisms will be ignored and you will always see all commands that make thinks should be executed -- but they are not actually executed, just printed. That might be a good way to figure out what you can actually expect to see.
The VERBOSE variable has no standard meaning for make, but only if your makefile interprets it.
For my version of make, I found BOTH paramters -n and -d helped.
GNU Make 3.80 Copyright (C) 2002 Free Software Foundation, Inc
-d Print lots of debugging information.
-n, --just-print, --dry-run, --recon
Don't actually run any commands; just print them.
When a bunch of makefile fragments are included, the line numbers don't make sense without this key debug flag.
CreateProcess(....exe,...)
Reading makefile `../../../../build/Makefile.options' (search path) (don't care) (no ~ expansion)...
Makefile:361: Extraneous text after `else' directive
Makefile:368: Extraneous text after `else' directive
Makefile:368: *** only one `else' per conditional. Stop.
in my case i was able to suppress commands in output by setting up below variable in top my make file
# Use `make V=1` to print commands.
$(V).SILENT:
add the above line in top of you make file and when you call any target it wont print
Before :
muhasan#admins-MacBook-Pro fx.identitymanagement % make dockerstatus
cd identity.API/ && docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------
identityapi_backend_1 dotnet Identity.API.dll Up 0.0.0.0:5000->80/tcp
identityapi_db_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
muhasan#admins-MacBook-Pro fx.identitymanagement %
After :
muhasan#admins-MacBook-Pro fx.identitymanagement % make dockerstatus
Name Command State Ports
--------------------------------------------------------------------------------------
identityapi_backend_1 dotnet Identity.API.dll Up 0.0.0.0:5000->80/tcp
identityapi_db_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
muhasan#admins-MacBook-Pro fx.identitymanagement %
My Makefile
# Use `make V=1` to print commands.
$(V).SILENT:
Path = identity.API
builddocker:
cd devops && cp -rv Dockerfile docker-compose.yml ../${Path}/ && cd ..
installdocker:
cd ${Path}/ && docker-compose up -d
dockerstatus:
cd ${Path}/ && docker-compose ps
I think this is what you want:
make MAKE_VERBOSE=1 target
I'm trying to debug a compilation problem, but I cannot seem to get GCC (or maybe it is make??) to show me the actual compiler and linker commands it is executing.
Here is the output I am seeing:
CCLD libvirt_parthelper
libvirt_parthelper-parthelper.o: In function `main':
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:102: undefined reference to `ped_device_get'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:116: undefined reference to `ped_disk_new'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:122: undefined reference to `ped_disk_next_partition'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:172: undefined reference to `ped_disk_next_partition'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:172: undefined reference to `ped_disk_next_partition'
collect2: ld returned 1 exit status
make[3]: *** [libvirt_parthelper] Error 1
What I want to see should be similar to this:
$ make
gcc -Wall -c -o main.o main.c
gcc -Wall -c -o hello_fn.o hello_fn.c
gcc main.o hello_fn.o -o main
Notice how this example has the complete gcc command displayed. The above example merely shows things like "CCLD libvirt_parthelper". I'm not sure how to control this behavior.
To invoke a dry run:
make -n
This will show what make is attempting to do.
Build system independent method
make SHELL='sh -x'
is another option. Sample Makefile:
a:
#echo a
Output:
+ echo a
a
This sets the special SHELL variable for make, and -x tells sh to print the expanded line before executing it.
One advantage over -n is that is actually runs the commands. I have found that for some projects (e.g. Linux kernel) that -n may stop running much earlier than usual probably because of dependency problems.
One downside of this method is that you have to ensure that the shell that will be used is sh, which is the default one used by Make as they are POSIX, but could be changed with the SHELL make variable.
Doing sh -v would be cool as well, but Dash 0.5.7 (Ubuntu 14.04 sh) ignores for -c commands (which seems to be how make uses it) so it doesn't do anything.
make -p will also interest you, which prints the values of set variables.
CMake generated Makefiles always support VERBOSE=1
As in:
mkdir build
cd build
cmake ..
make VERBOSE=1
Dedicated question at: Using CMake with GNU Make: How can I see the exact commands?
Library makefiles, which are generated by autotools (the ./configure you have to issue) often have a verbose option, so basically, using make VERBOSE=1 or make V=1 should give you the full commands.
But this depends on how the makefile was generated.
The -d option might help, but it will give you an extremely long output.
Since GNU Make version 4.0, the --trace argument is a nice way to tell what and why a makefile do, outputing lines like:
makefile:8: target 'foo.o' does not exist
or
makefile:12: update target 'foo' due to: bar
Use make V=1
Other suggestions here:
make VERBOSE=1 - did not work at least from my trials.
make -n - displays only logical operation, not command line being executed. E.g. CC source.cpp
make --debug=j - works as well, but might also enable multi threaded building, causing extra output.
I like to use:
make --debug=j
https://linux.die.net/man/1/make
--debug[=FLAGS]
Print debugging information in addition to normal processing. If the FLAGS are omitted, then the behavior is the same as if -d was specified. FLAGS may be a for all debugging output (same as using -d), b for basic debugging, v for more verbose basic debugging, i for showing implicit rules, j for details on invocation of commands, and m for debugging while remaking makefiles.
Depending on your automake version, you can also use this:
make AM_DEFAULT_VERBOSITY=1
Reference: AM_DEFAULT_VERBOSITY
Note: I added this answer since V=1 did not work for me.
In case you want to see all commands (including the compiled ones) of the default target run:
make --always-make --dry-run
make -Bn
show commands executed the next run of make:
make --dry-run
make -n
You are free to choose a target other than the default in this example.