Search code examples
makefilesyntax-errorgnu-makeglob

Negative glob in Makefile recipe syntax error


If I run the following command directly in /bin/bash it executes perfectly:

cp test_!(*.o) ./tmp/

(I just want to copy all files but objects)

Anyway if I put this command inside a Makefile recipe it gives

bin/bash: -c: line 0: syntax error near unexpected token `('

Example of Makefile

all:
        cp test_!(*.o) ./tmp/

What's wrong with that?


Solution

  • Your glob:

    test_!(*.o)
    

    employs extended globbing syntax.

    Look at this:

    $ shopt | grep extglob
    extglob         on
    

    And then at:

    $ cat Makefile
    SHELL := /bin/bash
    
    all:
        shopt | grep extglob
    
    $ make
    shopt | grep extglob
    extglob         off
    

    Invoked in the terminal, bash is in interactive mode (as per bash -i), and shell opt extglob is on.

    Invoked by make, bash is not in interactive mode (as per bash -c <command>), and shell opt extglob is off.

    You can make your recipe command work by enabling extglob in the .SHELLFLAGS of your makefile, e.g.

    $ cat Makefile
    SHELL := /bin/bash
    .SHELLFLAGS := -O extglob -c
    
    all:
        cp test_!(*.o) ./tmp/
    
    $ make
    cp test_!(*.o) ./tmp/
    cp: cannot stat 'test_!(*.o)': No such file or directory
    Makefile:5: recipe for target 'all' failed
    make: *** [all] Error 1
    

    As you see, no matches in my working directory, but no syntax error.