-1

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

7
  • 1
    Add a line continuation (a backslash) to the first line of the recipe. Make sure it is the last character of the line. As the recipe is written the two lines are executed in two different shells and the extglob option is set only for the first shell. Other possibilities: use the .ONESHELL GNU make feature or write the recipe on a single line. Note: except for this first line of the clean recipe, all other semi-colons are useless. Commented Nov 6, 2021 at 6:54
  • As you mentioned the "backslash" to be added, I do not get the point. Can you show me how to modify the current code? Huge thanks. Commented Nov 6, 2021 at 7:34
  • Do you know what the backslash character is? It looks like this: \. Just add one at the end of the line shopt -s extglob;. Commented Nov 6, 2021 at 10:14
  • 1
    Even with this, it will not work as-is. At least, not portably. That behavior is not available in a POSIX shell, it will only work in bash. But make doesn't invoke bash by default, it invokes /bin/sh. On some systems /bin/sh is actually bash and it will work. On other systems, /bin/sh is a simple POSIX shell and it will fail. If you want make to always use bash you have to set the variable SHELL = /bin/bash. Commented Nov 6, 2021 at 14:04
  • 1
    Thanks for the reply, so for in the makefile is not available to have ``` shopt -s extglob ``` ? Commented Nov 7, 2021 at 1:17

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This is also the way I tried, but do not work for me
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
Seems still does not work. I give a sum up for the problem.
0

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

Comments

-2

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

2 Comments

@glenn jackman for the error message
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.