Search code examples
bashmakefileextglob

Makefile: How to get wildcard (!arch)/*.c


I'm trying to make a makefile for compiling all the source files in my project, wich are spread in several directories like this:

libc/
  arch/
  include/
  math/
  stdio/

And i want to exclude all the files from the arch and include directories, I can do this in the shell using the command ls !(arch)/*.c But when i try to do the same using

$(wildcard !(arch)/*.c)

it doesn't work. How can i make it work in my makefile? Can i use something like !(arch || include) to exclude both directories?


Solution

  • $(wildcard !(arch)/*.c)
    

    it doesn't work. How can i make it work in my makefile? Can i use something like !(arch || include) to exclude both directories?

    Assuming you're asking about GNU Make, the answer to both questions is no.

    The syntax of built-in wildcards in GNU Make is pretty basic:

    The wildcard characters in make are ‘*’, ‘?’ and ‘[…]’, the same as in the Bourne shell.

    You can use built-in functions for this kind of task:

    $(wildcard $(addsuffix *.c,$(filter-out arch/,$(wildcard */))))
    $(wildcard $(addsuffix *.c,$(filter-out arch/ include/,$(wildcard */))))
    

    Or just shell out to find:

    $(shell find -name "*.c" -a \! -path "./arch/*" -a \! -path "./include/*")
    
    # This one is a bit more efficient:
    $(shell find \( -path "./arch" -prune -o -path "./include" -prune -o -name "*.c" \) -a -type f)