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.
Related
Hi I am new to creating makefile.
I have written the following commands in a makefile but they do not seem to execute when i type make in my terminal.
However, if i type the command separately in the terminal, it works.
I am trying to open a vivado project in this tcl file and do some spyglass analysis on it and save the result in a txt file.The tcl file also runs properly if executed separately.
I cd to my project folder where all the files- sources folder, project folder, makefile is present. I named it "makefile" so that i can execute it by typing make in the terminal.The makefile contents are as follows.
.PHONY : vivado_open
vivado_open:
$(info Hello Make)
bsub -Is -q i_soc_rh7 -R "rusage[mem=32000, temp=1GB] affinity[core(8):membind=localonly]" vivado -nolog -nojou -mode batch -source vivado.tcl
Here is the result from the terminal
$make
Hello Make
make: Nothing to be done for `vivado_open'.
Sorry, but there has to be something else going on here, that you haven't told us about. It's simply not possible for you to get that output if you typed make with that makefile.
You are using a variable, not a target named vivado_open, so make would never print nothing to be done for 'vivado_open'. It would say instead something like: nothing to be done for ../projectfiles/test.prj
Further, you didn't answer my question about TABs vs. spaces. If both the info and bsub lines are indented with TABs, there's no possible way that make would print Hello Make, without also printing the bsub command and trying to run it.
You must have another makefile in your directory, maybe named Makefile or GNUmakefile, that is being used instead of makefile. Or maybe you have an environment variable like MAKEFILES set which is causing other makefiles to be read.
If none of those appear to be true, you'll have to run make -d and see if you can figure out what's happening. That output is far too large to post to StackOverflow, so you'll have to try to read it yourself.
EDITED
OK, the problem is you're using spaces to indent your rules. In make, all recipe lines must be indented with a hard TAB character. Normal spaces don't mean anything special to make. Basically your makefile is interpreted as if you'd written this:
.PHONY : vivado_open
vivado_open:
$(info Hello Make)
bsub -Is -q i_soc_rh7 -R "rusage[mem=32000, temp=1GB] affinity[core(8):membind=localonly]" vivado -nolog -nojou -mode batch -source vivado.tcl
This is why you get this message "nothing to be done": you haven't actually defined a recipe for vivaldo_open, so there is literally nothing that make knows to do to update that target.
As an aside, normally you would get a syntax error for the bsub line because make doesn't know what that is. However, if you look carefully at your line you'll see that it contains a :. So, make is interpreting this as a set of targets and set of prerequisites, like this:
bsub ... affinity[core(8) : membind=localonly]" vivado ... vivado.tcl
(make doesn't care about quotes or other special characters like [] etc.)
So. Be sure you indent your recipe lines with TAB characters and you'll be fine. This is probably the single most common issue people have with makefiles.
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
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.
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.
I have a Makefile that starts by running a tool before applying the build rules (which this tool writes for me). If this tool, which is a python script, exits with a non-null status code, I want GNU Make to stop right there and not go on with building the program.
Currently, I do something like this (top level, i.e. column 1):
$(info Generating build rules...)
$(shell python collect_sources.py)
include BuildRules.mk
But this does not stop make if collect_sources.py exits with a status code of 1. This also captures the standard output of collect_sources.py but does not print it out, so I have the feeling I'm looking in the wrong direction.
If at all possible, the solution should even work when a simple MS-DOS shell is the standard system shell.
Any suggestion?
There might be a better way, but I tried the following and it works:
$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))
Here I did assume that your_command does not give any output, but it shouldn't be hard to work around such a situation.
Edit: To make it work with the default Windows shell (and probably any decent shell) you could write your_command && echo ok instead of the if within the shell function. I do not think this is possible for (older) DOS shells. For these you probably want to adapt your_command or write a wrapper script to print something on error (or success).
Ok, here's my own solution, which is unfortunately not based on the status code of the collect_sources.py script, but which Works For Me (TM) and lets me see any output that the script produces:
SHELL_OUTPUT := $(shell python collect_sources.py 2>&1)
ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),)
$(info $(SHELL_OUTPUT))
else
$(error $(SHELL_OUTPUT))
endif
The script is written so that any error produces an output beginning with "collect_sources: error:". Additionally, if python cannot find or execute the given script, it outputs an error message containing the message "[Errno 2]" or similar. So this little piece of code just captures the output (redirecting stderr to stdout) and searches for error messages. If none is found, it simply uses $(info) to print the output, otherwise it uses $(error), which effectively makes Make stop.
Note that the indentation in the ifeq ... endif is done with spaces. If tabs are used, Make thinks you're trying to invoke a command and complains about it.
You should use a regular target to create BuildRules.mk:
BuildRules.mk: collect_sources.py
python $< >$#
include BuildRules.mk
This is the standard trick to use when automatically generating dependencies.
Fixing https://stackoverflow.com/a/226974/192373
.PHONY: BuildRules.mk
BuildRules.mk: collect_sources.py
echo Generating build rules...)
python $< >$#
$(MAKE) -f BuildRules.mk
Make sure you're not invoking make/gmake with the -k option.