I do not know why I am getting these error messages from the shell or where ever they are coming from?
I've simplified a make file. Here is the make file simple.mk
# simple trial makefile
$(warning Making where CURDIR is $(CURDIR))
$(warning $(shell ls -ld "$(CURDIR)" ) )
$(shell "ls -l $(CURDIR)" )
$(shell "\ls -l /home/me/BitHoist/run/objects" )
I run it.
me $ make -f simple.mk
simple.mk:2: Making where CURDIR is /home/me/BitHoist/source
simple.mk:3: drwxrwxr-x. 2 me me 4096 Apr 27 18:37 /home/me/BitHoist/source
/bin/sh: ls -l /home/me/BitHoist/source: No such file or directory
/bin/sh: \ls -l /home/me/BitHoist/run/objects: No such file or directory
make: *** No targets. Stop.
me $
I figured out one solution, enclose in $(warning )
I do not know why I am getting these error messages?
/bin/sh: ls -l /home/me/BitHoist/source: No such file or directory
/bin/sh: \ls -l /home/me/BitHoist/run/objects: No such file or directory
Seems to be an error message from sh.
Robert
Running $(shell "ls -l $(CURDIR)" ) is like typing "ls -l /home/me/BitHoist/source" to the shell prompt (including quotes).
Try that and you'll see you'll get the same error you get from the makefile. Make passes those quotes along to the shell verbatim, so the shell is trying to run a program literally named ls -l /home/me/BitHoist/source, which is obviously not a real program name. Hence the error.
Related
I have a single line Makefile that throws the following error: Makefile:1: *** missing separator. Stop. I know there are dozens of duplicate questions with the same error message but most of them suggest something to do with using not using tabs or mysterious special characters.
$ cat -e -v -t Makefile
set -e$
$ make
Makefile:1: *** missing separator. Stop.
As far as I can see, there are no mysterious special characters. Perhaps there are characters that cat -e -v -t doesn't show?
The following works, so I'm guessing it isn't an issue with my make installation:
$ cat -v -e -t Makefile
foo:$
^Iecho "Foo"$
$ make
echo "Foo"
Foo
Some relevant version and shell information.
$ make --version
GNU Make 3.81
$ echo $0
-bash
Edit: See comment by #AProgrammer
Note it throws the same error message regardless of what I have below the set -e.
$ cat -e -v -t Makefile
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:1: *** missing separator. Stop.
Edit 2:
Note adding #!/bin/bash throws the same error message.
$ cat -e -v -t Makefile
#!/bin/bash$
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:2: *** missing separator. Stop.
Edit 3:
Running set -e on my shell directly seems to work (it exits the failed make call as expected).
$ set -e
$ make
Makefile:2: *** missing separator. Stop.
Saving session...completed.
Deleting expired sessions...11 completed.
[Process completed]
There is absolutely no reason for which make would be able to interpret arbitrary shell commands outside of rules.
If you want to exit rules immediately when there is an error, there are several ways to do it, more or less portably.
First, each line in a rule is executed by a separate instance of the shell. This means that if you don't merge them manually (with \ and ;), you'll get the behavior you want if you have one command per line.
Then you can use set -e as part of the probably few rules which need it. For instance;
foo:
set -e; for i in a b c d; mkdir $$i; done
With GNU Make, you can change the flags used to call the shell, additionally passing -e:
.SHELLFLAGS=-ec
With POSIX Make, you can change the shell. I don't know if passing a flag is supported, but it seems so with GNU Make:
SHELL=/bin/sh -e
but you can always pass a wrapper which set the flags as you want:
SHELL=/path/to/mywrapper
with mywrapper being
#!/bin/sh
exec /bin/sh -e "$#"
I'm preparing some latex files and decided to make some makefile to help me to compile and clean de latex files. So I created the following makefile
aula=listaProb
all: compile clean
compile:
pdflatex $(aula).tex
clean:
rm -rf !(makefile|$(aula).tex|$(aula).pdf) -v
But when I execute "make" I get the following mistake
rm -rf !(makefile|listaProb.tex|listaProb.pdf) -v
/bin/sh: 1: Syntax error: "(" unexpected
makefile:8: recipe for target 'clean' failed
make: *** [clean] Error 2
But the command
rm -rf !(makefile|listaProb.tex|listaProb.pdf) -v
works fine on the terminal.
What is wrong? I can't find any mistake :/..
Ps. I use this way to remove the files because I want to delete all but the specified files. It needs the command
shopt -s extglob
before use it. If anyone knows how to do it without use extglob, it would be nice.
Thanks
The problem is recipe commands are passed to /bin/sh which cannot process that syntax. You can change your Makefile to say:
clean:
bash -O extglob -c "rm -rf !(makefile|$(aula).tex|$(aula).pdf) -v"
To force this command to be run in bash with extglob on.
Or define SHELL variable for your make e.g. by running:
make SHELL="/bin/bash -O extglob" clean
Or adding:
SHELL := /bin/bash -O extglob
To your make file. The former option only affects shell invocation of that one command, the latter will apply to all your recipes (commands).
I have a makefile including the following lines:
buildrepo:
#$(call make-repo)
define make-repo
for dir in $(C_SRCS_DIR); \
do \
mkdir -p $(OBJDIR)/$$dir; \
done
endef
On the line with the commands for dir in $(C_SRCS_DIR); \ I get the following error message:
"dir not expected at this moment"
make: *** [buildrepo] Error 255
I am using GNU make.
Can anybody tell me what is going wrong?
Actually this for ... in ... ; do ... done statement is a Unix command not a GNU make command, therefore I guess you are using a Windows machine (or any other one). You have to find the equivalent for your system.
But GNU make has a foreach function which works like this :
$(foreach dir,$(C_SRCS_DIR),mkdir -p $(OBJDIR)/$(dir);)
Also note that in your very specific case (not related to GNU make but to Windows) you can create all the dirs without a for/foreach loop, just like this :
mkdir -p $(addprefix $(OBJDIR)/,$(C_SRCS_DIR))
I have a GNU makefile that looks something like this:
SOME_BINARY := $(shell `which some-binary` --help 2> /dev/null)
all: test_if_some_binary_exists
test_if_some_binary_exists:
ifdef SOME_BINARY
#echo "some-binary found!"
else
#$(error 'some-binary' not found!)
endif
Let's say I already have a binary called some-binary, which takes the option --help and writes a help message to standard error:
$ some-binary --help
Some-Binary v1.2.3 (c) 2015 Foo Bar Baz
...
However, it is really a symbolic link to a file located elsewhere on the file system:
$ ls -l `which some-binary`
lrwxr-xr-x 1 alexpreynolds admin 34 Aug 18 15:01 /usr/local/bin/some-binary -> ../Cellar/some-binary/1.2.3/bin/some-binary
When I run make all or make test_if_some_binary_exists, then I get an error as if the binary does not exist (when in fact it does):
$ make test_if_some_binary_exists
makefile:9: *** 'some-binary' not found!. Stop.
How do I correctly test for existence of a binary — potentially a symbolic link — within a GNU makefile?
When I enter this command:
./vw -d click.train.vw -f click.model.vw --loss_function logistic
on cygwin I got this error:
-bash: ./vw: No such file or directory
I actually want to implement "PREDICTING CTR WITH ONLINE MACHINE LEARNING" website link for reference :
http://mlwave.com/predicting-click-through-rates-with-online-machine-learning/
Any help would be appreciated.
Answer based on common mistakes.
Execution by inexact name
Filename with blanks
Suppose you write ls in the command line and obtain the following:
$ ls
anyfile command
Then, you call your command with ./command and get the following:
$ ./command
bash: ./command: No such file or directory
Here you can think ls is wrong, but the actuality is that you can't easily recognize if a filename have, for example, leading or trailing spaces:
$ ls -Q # -Q, --quote-name -> enclose entry names in double quotes
"anyfile" "command "
As you see, here my command has a trailing space:
$ ./"command " # it works
Filename with extension
A common mistake is to call the command by the name without the extension (if any).
Let's name the command: command.sh:
$ ./command # wrong
$ ./command.sh # OK
Wrong file path
If you call your command with the prefix ./, it needs to be in your current directory ($PWD). If it is not, you will get:
$ ./command # relative path -> same as "$PWD/command"
bash: ./command: No such file or directory
In that case, you can try the following:
Executing the command by its absolute path
$ /home/user/command # absolute path (example). It starts with a slash (/).
Let the shell locate the command
If you provide just the command name without slashes, bash searches in each directory of the $PATH variable, for an executable file named command.
$ command
You can do that search with the which command:
$ which command
/usr/bin/command
If the search fails, you'll get comething like:
$ which unexistent_command
which: no unexistent_command in (/usr/local/sbin:/usr/local/bin:/usr/bin)
Broken link
Now, suppose you write ls -Q in the command line and obtain the following:
$ ls -Q
"anyfile" "command"
This time, you can be 100% secure command exists but when you try to execute it:
$ ./command
bash: ./command: No such file or directory
Reason? bash complains command doesn't exist, but what doesn't exist is the file command is pointing to by a Symbolic link. e.g.:
$ ls -l
total 0
-rw-r--r-- 1 user users 0 Jan 14 02:12 anyfile
lrwxrwxrwx 1 user users 27 Jan 14 02:12 command -> /usr/bin/unexistent_command
$ ls /usr/bin/unexistent_command
ls: cannot access /usr/bin/unexistent_command: No such file or directory
Notice that the following surely throw different errors that the one you are getting...
Execution permission
To execute a file, it must have the x bit activated. With ls -l you can check the file permission.
$ ls -l command
-rw-r--r-- 1 user users 0 Jan 3 19:52 command
In this case (it doesn't have the x bit activated), you can give permission with chmod:
$ chmod +x command
$ ls -l command
-rwxr-xr-x 1 user users 0 Jan 3 19:52 command