skip to Main Content

I am trying to make a make file function that cleans everything instead of 4 specific files:

all: clean compile run

compile: main.c util.c util.h
        @echo "-------------------------------------------"
        @echo "Compiling..."
        @gcc -o test main.c util.c

run:
        @echo "-------------------------------------------"
        @echo "Running the tests...."
        @echo "================================================================>
        @./test
        @echo "================================================================>
        @echo "Completed tests...."

clean:
        @echo "-------------------------------------------"
        @echo "Cleaning..."
        @rm -v !("main.c"||"makefile"||"util.c"||"util.h")

other functions do work but I get this error for $make clean:

-------------------------------------------
Cleaning...
/bin/sh: 1: Syntax error: "(" unexpected
make: *** [makefile:19: clean] Error 2

The line "rm -v !("main.c"||"makefile"||"util.c"||"util.h")" works normally when I type in on the console.What am I doing wrong?

ps: I am on ubuntu vm

I have tried to clean every file except 4 specific files with a makefile, but I got an error instead. The line works normally on the console.

2

Answers


  1. make runs each line of the Makefile in /bin/sh. If you want a different shell, you have to set the SHELL variable. In your case, start the Makefile with

    SHELL = /bin/bash
    

    But it’s not enough, you also need to enable the extglob shell option. In GNU make, you can add the options directly to the variable:

    SHELL = /bin/bash -O extglob
    
    Login or Signup to reply.
  2. As @choroba mentioned, you’re using a special bash syntax, and make defaults to using sh. You can use the following syntax which is compatible with sh:

    clean:
       @ls | grep -xv "main.c|makefile|util.c|util.h" | tr "n" "" | xargs -0 rm
    

    The tr "n" "" converts the output to a null delimited list, and the -0 tells xargs to treat each item on the list as a separate entity. (This is to avoid issues where filenames might contain spaces). Note that the -x on grep tells it to only match a whole line.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search