Syntax error in Makefile: end of file unexpected (expecting "fi") - bash

Here is my make target:
copy_python:
if test -d $(VIRTUAL_ENV)/lib; then \
cp -a $(VIRTUAL_ENV)/lib/python2.7/site-packages/. ./package/tmp/; \
fi
if test -d $(VIRTUAL_ENV)/lib64; then \
cp -a $(VIRTUAL_ENV)/lib64/python2.7/site-packages/. ./package/tmp/; \
fi
Here is the error:
/bin/sh: 2: Syntax error: end of file unexpected (expecting "fi")
Makefile:28: recipe for target 'copy_python' failed
make: *** [copy_python] Error 2
Why does this error occur?

You have an extra space after the ending backslash, at the end of the second cp command. For this reason, \ no longer acts as a line continuation and the fi on the next line is not passed to sh

Related

syntax error near unexpected token '(' in bash script when selecting files [extend]

Question similar to here, but for my use case, I'd like to place inside the makefile.
#!/bin/bash
# Example:
# make run TEST_CASE="testbench.sv"
# make clean
compile:
vcs $(TEST_CASE) -sverilog;
run: compile
./simv
uvm_compile:
vcs $(TEST_CASE) -sverilog;
clean:
shopt -s extglob;
rm -v !(*.sv|*svh|"makefile");
The problem exist in make clean, and I got the following result:
ycliao#localhost:[~/workspace/i2c_vip/uvm_practice]: make clean
shopt -s extglob;
rm -v !(*.sv|*svh|"makefile");
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `rm -v !(*.sv|*svh|"makefile");'
make: *** [clean] Error 1
As I understand makefiles, every line is executed in a separate shell. So you need to add a line continuation to concatenate the commands so that they execute in the same shell:
SHELL = /bin/bash
# ...
clean:
shopt -s extglob; \
rm -v !(*.sv|*svh|"makefile");
This is demonstrated in Example makefiles on the wikipedia Make page.
I believe the problem is a bash problem. For some reason, it doesn't seem possible to do shopt followed by some command as a one-liner. Let's take make completely out of the picture. In a bash shell:
$ ls -1 /tmp/hosts.tar.*
/tmp/hosts.tar.bz2
/tmp/hosts.tar.gz
$ shopt -s extglob ; ls -1 /tmp/hosts.tar.#(bz2|gz)
bash: syntax error near unexpected token `('
$ ls -1 /tmp/hosts.tar.#(bz2|gz)
bash: syntax error near unexpected token `('
$ shopt -s extglob
$ ls -1 /tmp/hosts.tar.#(bz2|gz)
/tmp/hosts.tar.bz2
/tmp/hosts.tar.gz
To Sum up, for the makefile, it is not allow to have this.
ycliao#localhost:[~/workspace/i2c_vip/uvm_practice]: make clean
shopt -s extglob; \
rm -v !(*.sv|*svh|"makefile");
/bin/bash: -c: line 1: syntax error near unexpected token `('
/bin/bash: -c: line 1: `rm -v !(*.sv|*svh|"makefile");'
make: *** [clean] Error 1

Why does the parallel command not work with backslashes when taking input from file?

Consider the following file saved as commands.txt
ls \
&& pwd
ls \
&& pwd
Now,
bash commands.txt
works as expected to give
LICENSE
/home/username/utilities
LICENSE
/home/username/utilities
but
parallel < commands.txt
gives the error
/bin/bash: -c: line 0: syntax error near unexpected token `&&'
/bin/bash: -c: line 0: `&& pwd'
ls: cannot access '\': No such file or directory
/bin/bash: -c: line 0: syntax error near unexpected token `&&'
/bin/bash: -c: line 0: `&& pwd
Why do multiple lines with the same command separated by \ not seem to work with parralel as such?
Why do multiple lines with the same command separated by \ not seem to work with parralel as such?
Because parallel does not parse \ and executes a separate shell for each line.
If your input has \n\n after each group (and only there), you can do:
cat commands.txt | parallel -d '\n\n'

What is this error in a Makefile?

Using 'make' from the ARM DS-5 5.22 release on Cygwin, I am processing a makefile containing the lines:
if [[ ! -d "$(OBJ_DIR)" ]]; \
then $(MD) "$(OBJ_DIR)"; fi
This evaluates to:
if [[ ! -d "../../output/obj" ]]; \
then mkdir -p "../../output/obj"; fi
When making, I get an error:
make -C ./src/modules
make[1]: Entering directory `C:/Users/me/Documents/proj/src/modules'
if [[ ! -d "../../output/obj" ]]; \
then mkdir -p "../../output/obj"; fi
! was unexpected at this time.
make[1]: *** [setenv] Error 255
make[1]: Leaving directory `C:/Users/me/Documents/proj/src/modules'
make: *** [drivers] Error 2
When explicitly running the mkdir command from the command line, it works as expected and the output/obj directory is created with no problems.
This script works fine on other computers.
What does the ! was unexpected at this time. error mean, and how to fix that?
UPDATE: The make command is invoked from the following shell script:
#!/bin/bash
set -e
export PATH='./:/usr/bin/:/cygdrive/c/Program Files/ARMCompiler6.6/bin/'
export ARM_PRODUCT_PATH='c:/DS-5_v5.22/sw/mappings'
export USEARMCOMPILER6=1
export DS5VER=DS-5_5.22
/cygdrive/c/DS-5_v5.22/bin/make "$#"

How to escape parenthesis for the cp command inside a Makefile

I have this Makefile:
VAR=foo(1).txt foo(2).txt
foobar: $VAR
cp -p $^ foo/
When I run it I get this error:
$ make test
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `cp -p foo(1).txt foo(2).txt foo/'
Makefile:3: recipe for target 'foobar' failed
make: *** [test] Error 1
How to quickly get rid of it?
You can wrapt the file names in double quotes
cp "foo(1).txt" "foo(2).txt" /out
Test
$ cp "foo(1).txt" "foo(2).txt" out/
$ ls out/
foo(1).txt foo(2).txt
Or much safer would be
cp 'foo(1).txt' 'foo(2).txt' out/

Makefile delete all files but one [duplicate]

I have a simple Makefile that just contains this one target. It looks like this:
SHELL:=/bin/bash
clean:
rm !(*.tex|Makefile|*.pdf)
When I run this command in bash it works fine, i.e. it gives no errors and it removes the desired files. However when I run make clean it gives the following errors:
$ make clean
rm !(*.tex|Makefile|*.pdf)
/bin/bash: -c: line 0: syntax error near unexpected token `('
/bin/bash: -c: line 0: `rm !(*.tex|Makefile|*.pdf)'
make: *** [clean] Error 1
Has anybody got an idea what I'm doing wrong? Thanks.
Change the SHELL line to
SHELL:=/bin/bash -O extglob
The extglob option is not set by default, so you have to do that yourself.

Resources