I am creating Makefile and it gives me following error
Makefile:124: *** unterminated call to function `foreach': missing `)'. Stop.
The Makefile around line 124 is
.PHONY: popiso
popiso: isolinux_cfg $(foreach x,$(_$(country)_pops_roles), pop_iso_$(x)) $(isomedia)
#echo $#
#echo
#echo allhostname $(allhostname)
#echo
#echo
#echo allnetwork_setup $(allnetwork_setup)
#sudo cp $(addsuffix .ks.cfg,$(allhostname)) $(isomedia)
#sudo cp isolinux.cfg $(isomedia)/isolinux/
#echo ready to make iso
$(_$(country)_pops_roles) gets expanded correctly and it calls pop_iso_XXXX 4 times as it suppose to.
And then it gives above mentioned error.
I'm using RHEL6 - 64bit machine
I'm not that deep into Makefile/Gmake, and so I'm not sure what's the issue.
$ make -v
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-redhat-linux-gnu
Hemanshu
Edit: Remake version: run using 'remake all -X'
This is how the main line expands
popiso: isolinux_cfg pop_iso_loc2_role1 pop_iso_loc2_role2 pop_iso_loc1_role1 pop_iso_loc1_role2 /raw/ops-xxxx/media
It makes first 5 targets successfully and then stops as follow
end pop_iso_loc1_role2
/raw/patel/xxxx-build-test/build-tools/ks/Makefile:166 Successfully remade target file `pop_iso_loc1_role2'.
<- (/raw/patel/xxxx-build-test/build-tools/ks/Makefile:166)
pop_iso_loc1_role2
remake<19>
-> (/raw/patel/xxxx-build-test/build-tools/ks/Makefile:119)
/raw/ops-xxxx/media:
remake<20>
/raw/patel/xxxx-build-test/build-tools/ks/Makefile:124 Must remake target `popiso'.
Makefile:125: *** unterminated call to function `foreach': missing `)'. Stop.
***Entering debugger because we encountered a fatal error.
** Exiting the debugger will exit make with exit code 2.
popiso
remake<21>
then for testing purpose I removed sixth target '/raw/ops-xxxx/media' but error still says the same
You say that "it calls pop_iso_XXXX 4 times as it suppose to".
That proves that the problem is not in this foreach(). If it were, I would expect that the foreach would not get expanded at all.
The following brief, standalone Makefile, works correctly and gives the expected results without errors:
_a_pops_roles=foo bar
country=a
popiso: $(foreach x, $(_$(country)_pops_roles), pop_iso_$(x))
pop_iso_foo:
echo 1
pop_iso_bar:
echo 2
This usage is identical to what you have.
Look for other foreach loops in your Makefile, where the problem actually is.
For example: you have another call on the same line to $(isomedia). If this macro expands out to a foreach, and it has a syntax error, this would be reported as an error on this line even though the typo is somewhere else.
You can't always trust line numbers.
Related
I'm new to Linux & shell and I'm struggling with checking if the compilation is successful.
g++ code.cpp -o code.o 2>error.txt
if [ ! -e error.txt ]
then
do something
else
echo "Failed to compile"
I guess an error file is created even if the compilation is successful. What is the content of the error file when there is no error? I need to change the if condition to check if the compilation is successful.
It's just the order of things. What happens when the shell parses the string g++ code.cpp -o code.o 2>error.txt is:
The shell creates error.txt, truncating the file if that name already exists.
g++ is called with its error output redirected to the new file.
If g++ does not write any data, then the file remains as it was (empty) at the end of step 1.
You probably aren't so much interested in the error file as you are the return value. You probably ought to just do:
if g++ code.cpp -o code; then : do something; done
or even just:
g++ code .cpp -o code && : do something
but if really want to do something else with the errors, you can do:
if g++ code.cpp -o code.o 2> error.txt; then
rm error.txt
: do something
else
echo >&2 Failed to compile code.cpp.\ See "$(pwd)"/error.txt for details.
fi
Make sure you escape at least one of the spaces after the . so that you get 2 spaces after the period (or just quote the whole argument to echo). Although it's become fashionable lately to claim that you only need one space, all of those arguments rely on the use of variable width fonts and any command line tool worth using will be used most often in an environment where fixed width fonts are still dominant. This last point is totally unrelated to your question, but is worth remembering.
I am running a simple linux system with busybox and hush as the shell.
When I try to run the standard "./configure" for compiling programs, I always get the following error:
/Programs/blazeos/build/bison-3.4.1 # ./configure
hush: ambiguous redirect
hush: syntax error at 'fi'
If I run it with "ash ./configure" it runs without any problems, so it seems to be related to the hush shell. Does anyone know why this is happening or how I can debug it? I have tried it with several different source packages, such as "flex", "bison", "m4" etc. and I always get the same error.
This happens in as_fn_error:
as_fn_error ()
{
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
$as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
$as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
This happens because >&$4 (getting the file descriptor number to redirect to by evaluating $4) is not supported in hush. Arguably, this violates the letter of the POSIX sh standard; bolding for emphasis is mine:
The redirection operator: [n]>&word shall duplicate one output file descriptor from another, or shall close one. If word evaluates to one or more digits, the file descriptor denoted by n, or standard output if n is not specified, shall be made to be a copy of the file descriptor denoted by word
As I read the specification, "evaluates to" means that expansions should be run, so using a parameter expansion should be legal in that location. Thus, this is (arguably) a missing feature in hush that would be required for standards compliance.
If you're interested in trying to work around the issue, in all the cases where this optional parameter is used, it's given a hardcoded value of 5. Thus, you could simply change >&$4 to >&5, and this specific error would be avoided.
This is really just out of curiosity.
A typo made me notice that in Bash, the following:
$ .anything
does not print any error ("anything" not to be interpreted literally, it can really be anything, and no space after the dot).
I am curious about how this is interpreted in bash.
Note that echo $? after such command returns 127. This usually means "command not found". It does make sense in this case, however I find it odd that no error message is printed.
Why would $ anything actually print bash:anything: command not found... (assuming that no anything cmd is in the PATH), while $ .anything slips through silently?
System: Fedora Core 22
Bash version: GNU bash, version 4.3.39(1)-release (x86_64-redhat-linux-gnu)
EDIT:
Some comments below indicated the problem as non-reproducible at first.
The answer of #hek2mgl below summarises the many contributions to this issue, which was eventually found (by #n.m.) as reproducible in FC22 and submitted as a bug report in https://bugzilla.redhat.com/show_bug.cgi?id=1292531
bash supports a handler for situations when a command can't be found. You can define the following function:
function command_not_found_handle() {
command=$1
# do something
}
Using that function it is possible to suppress the error message. Search for that function in your bash startup files.
Another way to find that out is to unset the function. Like this:
$ unset -f command_not_found_handle
$ .anything # Should display the error message
After some research, #n.m. found out that the described behaviour is by intention. FC22 implements command_not_found_handle and calls the program /etc/libexec/pk-command-not-found. This program is part of the PackageKit project and will try to suggest installable packages if you type a command name that can't be found.
In it's main() function the program explicitly checks if the command name starts with a dot and silently returns in that case. This behaviour was introduced in this commit:
https://github.com/hughsie/PackageKit/commit/0e85001b
as a response to this bug report:
https://bugzilla.redhat.com/show_bug.cgi?id=1151185
IMHO this behaviour is questionable. At least other distros are not doing so. But now you know that the behaviour is 100% reproducible and you may follow up on that bug report.
I was trying to get the result of file function in makefile for my demo with a small makefile as:
CMD = cat
OBJECTS = Makefile Makefile-filter-func
program : $(OBJECTS)
$(file >$#.in) $(foreach O,$^,$(file >>$#.in,$O))
#echo The file has been created.
all :
$(CMD) $(CMDFLAGS) #$#.in
#echo The file contents are printed.
#rm $#.in
#echo The file removed.
I want to see the file the file name using ls command but this makefile has following error:
Makefile-file-func:7: *** recipe commences before first target. Stop.
where am I getting wrong.
A pointer to the answer can be found in the source code of make (version 3.82), in the file read.c:
989 /* This line starts with a tab but was not caught above because there
990 was no preceding target, and the line might have been usable as a
991 variable definition. But now we know it is definitely lossage. */
992 if (line[0] == cmd_prefix)
993 O (fatal, fstart, _("recipe commences before first target"));
With this information, it is possible to reproduce your issue by inserting spaces at the right spot. In the code below, ~ denotes a space and <TAB> denotes a TAB:
program : $(OBJECTS)
~~~~~~~~$(file >$#.in) $(foreach O,$^,$(file >>$#.in,$O))
<TAB> #echo The file has been created.
Since the spaces and tabs get lost in your question, it is a bit hard to see if this is exactly your case as well though.
Note that recipes are normally supposed to start with a TAB.
I'm trying to get PHP phar command line tool installed on my Debian VM, how here described:
(1) download the php-src, I assume it's in /tmp/php/src
(2) make the dir /tmp/phar
(3) Save this as /tmp/php-src/ext/phar/Makefile.
(4) cd /tmp/php-src/ext/phar
(5) run sudo make
Now after step 5 I get an error:
:/tmp/php-src/ext/phar# make
Makefile:11: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
As I know, there can be two possible causes for this error message:
Tabs in the make file. I've tested the file with od -t c Makefile. The file contains no tabs (\t).
It could be a bug of make v3.81 and need a patch or an upgrade to (yet instable: "Warning: This package is from the experimental distribution.") v3.82. I've downloaded and istalled (dpkg -i make_3.82-1_amd64.deb) it, but the error is still occuring.
What causes the error? How can it be avoided?
Thx
(Answered in a comment: See Question with no answers, but issue solved in the comments (or extended in chat))
#Beta wrote:
The line should begin with a tab, not a bunch of spaces.
The OP wrote:
I've replaced all 8-spaces sequences with tabs and can execute the make script now.
I used:
cat Makefile|sed "s/ /\t/" > Makefile