lumapools
lumapools

Reputation: 84

Compiling any single C code using a Makefile

I am pretty new to Makefiles, so my question might be silly. It would be the following: Can I pass another argument to make so that I can do stuff with this additional argument? More specifically, if possible, I would want to use this to compile any single C source code into its executable using a Makefile.

For example, if I have two files foo.c and bar.c, I would want to be able to compile them using the same recipe, therefore doing something similar to make compile foo.c or make compile bar.c that compiles them into the foo or bar executables, respectively.

If it is not possible, is there an alternative I can do for simple C programs? It would be useful to save time (not updating the Makefile or not writing gcc -o name name.c every time I want to compile a C file I just created).

Thank you in advance for your patience and time.

Upvotes: 0

Views: 1052

Answers (4)

MadScientist
MadScientist

Reputation: 100836

Make has built-in rules that knows how to compile a source file into an executable.

So, you don't even have to write a makefile at all (unless you want to use special compiler options). This will work:

$ ls
bar.c   foo.c

$ make foo
cc -o foo foo.c

$ make bar
cc -o bar bar.c

If you want to modify the compiler operations, add a makefile that sets the appropriate built-in variables:

$ ls
bar.c   foo.c   Makefile

$ cat Makefile
CC = gcc
CFLAGS = -O2 -g

$ make foo
gcc -O2 -g -o foo foo.c

$ make bar
gcc -O2 -g -o bar bar.c

Upvotes: 1

dmuir
dmuir

Reputation: 4431

I use the makefile below for this. 'make' or 'make all' compiles each .c (eg eg.c) file in the directory to an executable in the same directory (eg eg). 'make eg' compiles just eg.c to eg . There's nothing special about the compiler flags -- CFLAGS -- or linker flags -- LFLAGS -- they're just what I habitually use.

CC  = gcc
CFLAGS  = -std=gnu11 -Wall -Wextra
LFLAGS  = -lm -lrt

OPATH   = ./
PROGS   += $(patsubst %.c,$(OPATH)%,$(wildcard *.c))


all: $(PROGS)
$(OPATH)% : %.c ; $(CC) $(CFLAGS) $< -o $@ $(LFLAGS)

clean:  
    \rm -f $(PROGS)

Upvotes: 1

thurizas
thurizas

Reputation: 2508

how about using this:

================== makefile =====================

CC=gcc
CCFLAGS=-ansi -pedantic -Wall

all : clean foo bar

foo : foo.c 
    $(CC) $(CCFLAGS) foo.c -o foo

bar : bar.c
    $(CC) $(CCFLAGS) bar.c -o bar

clean : 
    rm -f *.o *.*~ foo bar

====================== end makefile ======================

invoking make as make will run the default target (all in this case) removing all intermediate files and output files and then rebuilding foo and bar

invoking make as make foo will only run the rule for making foo.

invoking make as make bar will only run the rule for making bar.

invoking make as make clean will only run the rule for cleaning the project directory -- removing all intermediate and output files.

Upvotes: 0

fluter
fluter

Reputation: 13786

If you are dealing with single main file applications, a bash script sounds much simpler, build.sh:

#!/bin/bash
SOURCE=$1
BIN=${SOURCE%.c}
if [[ -z "$SOURCE" || ! -s "$SOURCE" ]]; then
    echo "SOURCE is empty"
    exit 1
fi
gcc -o "$BIN" "$SOURCE"

and then invoke it like this:

./build.sh foo.c
./build.sh bar.c

Upvotes: 1

Related Questions