Search code examples
shellmakefileglob

Shell wildcard/glob for optional string in a makefile


I'm trying to "optimize" my 'clean' target in multi-platform Makefiles so I was looking for a way to remove executable files with or without the Windows-extension .exe.

Of course, you could do

rm file file.exe

but I was looking for something like

rm file(.exe)?

I also tried

rm file{,.exe}

which doesn't work either.

I was surprised to see that what I tried did not work, so I'm mostly posting this to learn more about globing, as the version with the two explicit filenames works fine.


Solution

  • Make executes commands with /bin/sh by default, which has limited globbing support.

    $ cat Makefile 
    test:
        echo foo{bar,baz}
    $ make
    echo foo{bar,baz}
    foo{bar,baz}
    

    If you want fancy features like curly braces to work you'll need to switch the shell by setting SHELL.

    $ cat Makefile 
    SHELL = /bin/bash
    
    test:
        echo foo{bar,baz}
    $ make
    echo foo{bar,baz}
    foobar foobaz
    

    I wouldn't necessarily advise doing so as it makes your Makefile less portable.

    For what it's worth, GNU Automake's strategy is to set an EXEEXT variable based on the platform. Then the clean rule is:

    rm -f file$(EXEEXT)