How to trace Makefile line numbers for troubleshooting? - makefile

This is related to How to trace Makefile targets for troubleshooting? I'm working on an old PowerMac G5. It is alive because I use it for testing older compilers and big-endian, PowerPC.
I'm trying to determine which line in a makefile is causing unexpected EOF while looking for matching ``'. Our makefile does not use the backtick (we added them for testing this issue); and trial/error and guessing is moving too slow for a makefile with 1000's of lines.
When I run make with --debug, it fails to print line numbers:
$ make --debug=a
GNU Make 3.82
Built for powerpc-apple-darwin9.8.0
...
Reading makefiles...
Reading makefile `GNUmakefile'...
bash: -c: line 0: unexpected EOF while looking for matching ``'
bash: -c: line 1: syntax error: unexpected end of file
bash: -c: line 0: unexpected EOF while looking for matching ``'
bash: -c: line 1: syntax error: unexpected end of file
bash: -c: line 0: unexpected EOF while looking for matching ``'
bash: -c: line 1: syntax error: unexpected end of file
bash: -c: line 0: unexpected EOF while looking for matching ``'
bash: -c: line 1: syntax error: unexpected end of file
Updating makefiles...
...
make --help does not appear to discuss it:
$ make --help 2>&1 | grep -i line
$
My first question is, how do I tell GNU make to print line numbers?
My second question is, how is a program that has been around as long as make has so lame with respect to debug support?

These errors are not being printed by make. They are being printed by the shell. As far as make is concerned, there are no errors here, so it won't print any tracing information.
Without seeing the makefile we can't be sure but almost certainly the problem is in $(shell ...script...) statements, where the ...script... has a syntax error. I assume your shell scripts are contained in make variables, which makes it difficult to see exactly what is being sent to the shell and whether it has a syntax error.
I agree that GNU make doesn't have good debugging for this: when debugging is enabled it should be printing details about the script that is invoked by the shell function and where it was invoked from (in the makefile).
I think #Vroomfondel has the best idea; add in $(info ...) messages to your makefile near likely-looking $(shell ...) invocations, like:
$(info starting shell: $(SCRIPT))
OUT := $(shell $(SCRIPT))
Using binary searching you should be able to pin it down pretty quickly even in a very long makefile.

You could try make --trace (at least with GNU make 4), or consider using remake (a variant of make capable of debugging), as remake -x.
For debugging complex Makefile-s, using remake is quite handy
You could consider using other build automation tools, e.g. ninja.
If you use GNU make, you'll better upgrade it to a newer version (and enable Guile extensions when configuring it).
Linux: find ./makefile_dir -mtime -10, see which file changed: foo.c, then grep -n foo.c Makefile and see line number in Makefile

Related

How do I get GNU parallel to work on git bash in Windows 7?

I was able to install GNU Parallel globally in git-bash by following this answer.
However, on running an example command as mentioned in the parallel-tutorial,
parallel -k echo ::: A B C > abc-file
I keep getting this error
sh: -c: option requires an argument
sh: -c: option requires an argument
sh: -c: option requires an argument
.
.
.
What am I doing wrong here?
So the root cause is that CygWin (contrary to GNU/Linux) does not respect redirection of STDERR if the command line is too long.
GNU Parallel figures out how long the longest possible command line is by doing a binary search for the length. This is awfully slow on CygWin because forking a 12 MB command line is horribly slow (and 12 MB seems to be the limit in my version of CygWin).
Luckily it only has do be done once. After this GNU Parallel caches the line length in ~/.parallel/tmp/HOSTNAME/linelen, and this is the reason why you experience the problem when ~/.parallel/tmp is removed.
This is also the reason why it seemed that using a different version worked: You simply had a single run that finished, and thus cached the length. It was not the change of version that did this.
Until I manage to get CygWin to ignore the sh: -c: option requires an argument all you need to do is to ignore it and be patient. I should probably also put in a small warning, to let CygWin users know that they have to be patient the first time.
Run:
parallel echo ::: 1
It will spit out the sh: -c: option requires an argument around 25 times, but that is fine. It will take around 30 seconds to complete.
After this everything should be fast(er) and you should not see the error.
It should be fixed in the newest version in GIT: https://savannah.gnu.org/git/?group=parallel
You are not the first to have this problem, and currently we do not know what causes it. I have access to a Windows-10 machine and I do not see that behaviour. A workaround seems to be using an older version of GNU Parallel. You can help by figuring out which versions work. When you have a single version (look here: https://ftpmirror.gnu.org/parallel), that works, run this:
testone() {
v="$1"
wget -c https://ftpmirror.gnu.org/parallel/parallel-$v.tar.bz2
tar xvf parallel-$v.tar.bz2
cd parallel-$v
src/parallel true ::: 1
}
export -f testone
parallel -k --joblog my.log testone {1}{2}22 ::: {2012..2020} ::: {01..12}
grep -E '\s0\s0\stest' my.log
This will give all versions that do work.
Post the output from parallel -Dall echo ::: foo for both the newest working version, the following version, and the newest version (20200322).

`/bin/bash: -c: line 13: syntax error: unexpected end of file` obscure error when changing variable in a Makefile

I've got this strange thing happening which seems totally unrelated to the error I got afterwards.
My AutoTools build system works great, but if I change this line in my Makefile, to use $(top_builddir) instead of $(top_srcdir), then the build starts failing this way:
...
/usr/bin/mcs -r:/usr/lib/pkgconfig/../../lib/cli/glib-sharp-3.0/glib-sharp.dll -out:gobject-intptr-ctor-verifier.exe GObjectIntPtrCtorVerifier.cs
Making all in Hyena
/bin/bash: -c: line 13: syntax error: unexpected end of file
How the hell this single change can cause this and how to debug this problem? How to know what file is bash trying to interpret? I'm at a loss here.
I'd try tracing the commands that are executed. Maybe make can be modified to be more verbose. Otherwise I suggest strace:
original_command='make all' # or whatever it was you executed
strace -s2000 -eexecve -o/tmp/make.commands -f $original_command
Then look at the file /tmp/make.commands, search for bash, and in particular search for inline shell scripts that are 13 lines long.
Glad you solved your problem. In the more general case, this error, and other similar errors, are usually caused by a syntax error in the Automake file that makes its way into the Makefile. Sometimes a line number in the Makefile is reported, so you can examine the generated Makefile; in your case it wasn't.
make -n can help, by printing out each command that make would execute without actually executing it.

MakeFile error too many arguments

I am doing a simple make file and iam getting the error too many arguments. I do not know what it is talking about
here is my code
project1: *.cpp *.h
g++ -o main *.cpp
here is what the terminal is saying
unixapps1:project1> project1: *.cpp *.h
project1:: Too many arguments.
I think the problems are two-fold:
You have an awfully large number of source files in your directory — so much so that the length of the names is too long for your shell.
You are mis-executing the makefile as if it was a shell script. The error message is what you'd get if you ran sh makefile and the project1: line was the first (non-blank, non-comment) line in it.
You need to run make or (if the makefile is named project1.mk) make -f project1.mk.
If I've guessed wrong (I hope I have), then you need to clarify what is prompt and what is command line in your question. Conventionally, you use $ as the shell prompt (for sh and relatives; % if you're using C shell or one of its relatives, or # if you're running as root — which you should not be doing if you are programming).

Error with conditional in a make file

I have a make file that is throwing an error. I believe that the problem is down to a conditional statement that I have the syntax wrong for but can't figure out what is actually wrong.
To be clear I am running the code using the command make {target_name}
The code is
ifeq ($(isDynamic), d)
libExt=.so
else
libExt=.a
endif
The error is
/bin/sh: 0403-057 Syntax error at line 1 : `(' is not expected.
You're running a Makefile as a shell script. You probably want to run make on it instead. Possibly you want to turn it into a make script, although this usually isn't quite what people intend; make the first line
#! /usr/bin/make -f
(or wherever GNU make is) and chmod +x it.

How to find the line number of an error in a Makefile?

I am running the following command:
make -f makefile.gcc
And the output is:
make: -c: Command not found
How can I find out which line is causing the error? The makefile is hundreds of lines long and there's no way of figuring it out otherwise.
I tried the -d switch, but that didn't print any useful information.
This might help you locate what goes wrong if you do run strace on the make command. Then you can search the makefile for that afterwards.
Here's a link to a post about strace:
http://linuxhelp.blogspot.com/2006/05/strace-very-powerful-troubleshooting.html
It seems like the problem is that the makefile contain paths with '\' in them and since I'm running on Linux, that's going to be a problem.
I'm still working on a solution for that.

Resources