How to compile all .c files in a directory and dump every binary without .c extension

I have a directory with several c source files (each file is a small program in itself) that I would like to compile right away and output the binary for each in the bin / subdirectory. The binary file name must be one of the original c file, but no .c extension. How can I accomplish something like this in the Makefile?

Example:

-src
    ll.c
    lo.c
    -bin
        ll
        lo

      

The first thing I came up with was this:

CFLAGS=-Wall -g
SRC=$(wildcard *.c)

all: $(SRC)
    gcc $(CFLAGS) $(SRC) -o bin/$(SRC)

      

But it doesn't work as I thought it would.

+3


source to share


3 answers


The line all: $(SRC)

tells make that the target all

contains all source files as prerequisites.

The recipe for this purpose ( gcc $(CFLAGS) $(SRC) -o bin/$(SRC)

) then tries to run gcc on all source files and says that it generates as output bin/<first word in

$ (SRC) with the rest of the words from

$ (SRC) `other, optional, gcc arguments.



You need something more:

SRCS := $(wildcard *.c)
# This is a substitution reference. http://www.gnu.org/software/make/manual/make.html#Substitution-Refs
BINS := $(SRCS:%.c=bin/%)

CFLAGS=-Wall -g

# Tell make that the all target has every binary as a prequisite and tell make that it will not create an `all` file (see http://www.gnu.org/software/make/manual/make.html#Phony-Targets).
.PHONY: all
all: $(BINS)

bin:
    mkdir $@

# Tell make that the binaries in the current directory are intermediate files so it doesn't need to care about them directly (and can delete them). http://www.gnu.org/software/make/manual/make.html#index-_002eINTERMEDIATE
# This keeps make from building the binary in the current directory a second time if you run `make; make`.
.INTERMEDIATE: $(notdir $(BINS))

# Tell make that it should delete targets if their recipes error. http://www.gnu.org/software/make/manual/make.html#index-_002eDELETE_005fON_005fERROR 
.DELETE_ON_ERROR:

# This is a static pattern rule to tell make how to handle all the `$(BINS)` files. http://www.gnu.org/software/make/manual/make.html#Static-Pattern
$(BINS) : bin/% : % | bin
        mv $^ $@

      

+2


source


[I forgot where you said you wanted to do this in the Makefile. My solution here is a forward shell.]

I would use something like



CFLAGS=-Wall -g

for cfile in *.c
do
    cc $CFLAGS -o bin/`basename $cfile .c` $cfile
done

      

0


source


Make is smart enough to do it with implicit rules. Make sure the makefile doesn't exist and doesn't run:

  for f in *.c; do make CFLAGS='-Wall -g' ${f%.c} && mv ${f%.c} bin; done

      

0


source







All Articles