How to build multiple targets with similar name? - c

So I have the exact same question as the one below, but no one has answered it.
Pattern matching Makefile with multiple executable targets
I am trying to build a series of small test files each have a pattern of "test*.c" to test my library.
I wanted to write a makefile that builds executables for every one of the test files all at once (each name: test1, test2, test3..etc.). However, I am not sure how to achieve that.
What I have so far is the following:
SRC := $(shell find *.c)
ALL_PROG := $(patsubst %.c, %, *.c)
.PHONY: all
all: $(ALL_PROG)
$(ALL_PROG): $(SRC)
-gcc $< -o $#
This is a bad attempt because the targets take all .c files as dependency, which caused circular dependency.
Using shell script can get the job done very easily, but I am wondering if there's a way to do the same job.
Thanks in advance.

Use $(ALL_PROG): %: %.c instead of $(ALL_PROG): $(SRC).
Here is an example Makefile I might use with GNU make:
CC := gcc
CFLAGS := -Wall -O2
LDFLAGS := -lm
PROGS := $(patsubst %.c, %, $(wildcard *.c))
.PHONY: all clean test $(patsubst %, test#%, $(PROGS))
all: $(PROGS)
clean:
rm -f $(PROGS)
$(PROGS): %: %.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $#
$(patsubst %, test#%, $(PROGS)): test#%: %
./$^
test: $(patsubst %, test#%, $(PROGS))
As usual, note that the indentation should use a Tab rather than spaces; the editor used here on stackoverflow.com auto-converts them to spaces.
The PROGS variable will contain the names of all *.c files in the directory.
The .PHONY: directive tells Make which targets do not refer to actual files. The $(patsubst %, test#%, $(PROGS)) expands to the list of executable names, with each name prepended with test#: if the directory contains files foo.c and bar.c, this expands to test#foo test#bar.
The $(PROGS): %: %.c recipe compiles each .c file to the corresponding binary.
The $(patsubst %, test#%, $(PROGS)): test#%: % recipe creates a test target for each binary. If we have files foo.c and bar.c, then this rule expands to test#foo test#bar: test#%: %. This means that for both test#foo and test#bar targets, the corresponding test#% target requires the % binary. The ./$^ in turn expands to ./%, and thus the binary name. (If you don't want Make to show the command being run, use #./$^. If you don't care if a test fails, use -./$^.)
The test recipe expands to test#foo test#bar if we have foo.c and bar.c; i.e. all possible test targets.
You can run make clean test to recompile all .c files in the directory, and execute them.
If you are only worried about a specific test program, say foo.c, you can run make test#foo, which will recompile the program if foo.c is newer than foo.

You can do that. I am updating a simple make file which builds multiple targets. You can modify it as your requirement.
TEST1 = test1.exe
TEST2 = test2.exe
### Executable Program Files ###
all : $(TEST1) $(TEST2)
$(TEST1) : test1.c
gcc -o $(TEST1) test1.c
$(TEST2) : test2.c
gcc -o $(TEST2) test2.c

Related

Makefile for multiple files in different directories

I am a newbie in creating makefiles, and would be glad if someone could help me.
I have created several header files (for function declarations) and corresponding .c programs (8 in total), for the function definitions (including the main function). These are listed in the .../include/ directory. Additionally, I have created another directory for the storing the output files : .../bin/ after compilation. I tried to link the .o files, but was unsuccessful. I have attached a small piece of the makefile code (similar one taken from the internet) :
CC = g++
CFLAGS = -Wall -O3
INC_DIR := /media/sf_~share/151*/Codes/include
OBJ_DIR := /media/sf_~share/151*/Codes/obj
INC_FILES := $(wildcard $(INC_DIR)/%.c)
OBJ_FILES := $(patsubst $(INC_DIR)/%.c, $(OBJ_DIR)/%.o, $(INC_FILES))
all : $(APP)
$(APP) : $(OBJ_FILES)
$(CC) $(CFLAGS) -o $# $^
$(OBJ_DIR)/%.o : $(INC_DIR)/%.c
$(CC) $(CFLAGS) -o $# $<
clean:
rm -f *.o $(APP)
I would be glad if someone could either suggest me a different code, or rectify this as it is.
There are a few mistakes in your Makefile:
Wildcard usage
You should use *.c rather than %.c for wildcard expansion, like this:
INC_FILES := $(wildcard $(INC_DIR)/*.c)
Patsubst usage
You don't need to specify the full pattern $(INC_DIR)/%.c for patsubst, instead, simply use:
OBJ_FILES := $(patsubst %.c, %.o, $(INC_FILES))
Missing $(APP) value
I don't know if you simply forgot to add this to the sample or not, but since $(APP) is an empty string, the makefile says:
make: Nothing to be done for `all'.
Adding APP := program triggers a build for all the *.c files in include.

Makefile does not iterate over all the source files?

I want to compile many source file and build a library from them.
My makefile looks approximately like this:
SOURCES := /home/test/src/\*.c
OBJECTS := $(SOURCES:.c=.o)
.PHONY: compileLibrary
compileLibrary:
$(CC) -fPIC -c $(SOURCES) -o $(OBJECTS)
$(CC) -shared -o libshared.so $(OBJECTS)
How ever the process does not iterate over each source file, it seems that makefile does not replace the * in SOURCES by its value.
*.c, on its own, is not expanded, you have to use the wildcard function (like $(wildcard *.c))
It is *.c, not \*.c. \ is escape and removes the special meaning of *.
Obviously your makefile shouldn't contain absolute path. Normally the current directory has to be the one where the makefile is in, so take advantage of it.
You should be actually using the features of make:
libshared.so: $(OBJECTS)
$(CC) -shared -o $# $<
compileLibrary: libshared.so
(note: you can probably do without the compilation rule, because the default is likely good enough)

Maintaining a list of programs I don't want Make to compile that I could change with >> and SED instead of editing the makefile?

I'm pretty new to Make. My current Makefile is below. It compiles all .c files into the respective executable file. The list of c files is constantly growing (I'm adding more and more files, p1.c, p2.c, p3.c, ...). So I want it to compile most of them, but if there's a particular file that has errors I don't want to bother with, I'd like to be able to put it on do-not-compile list--that is, instead of telling make what I do want to compile, it would be faster to tell it what I don't want to compile. It would be easy to have a file say dont.txt that I add and remove lines to, each of which contain "px.c". If I had such a file, how would I tell make not to compile those .c files?
CFLAGS = -g -pedantic -std=c99 -Wall
SRCS = $(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))
all: $(PROGS)
%: %.c
$(CC) $(CFLAGS) -o $# $<
Thank
you can filter out source files which you do not want to compile like
SRCS = $(filter-out excludefile.c, $(wildcard *.c))
Also if you maintain files name which you want to exclude then use command as follows
for example file is exclude.txt then
EXCLUDES := $(shell cat ./exclude.txt)
SRCS = $(filter-out $(EXCLUDES), $(wildcard *.c))

sample make file for creating more than one exe files with different directory [duplicate]

This question already has answers here:
Building multiple executables with similar rules
(5 answers)
Closed 9 years ago.
I am having a directory called test where make file should be. i am having subdirectory called sub1, sub2, sub3.
test/Makefile
test/sub1
test/sub2
test/sub3
I want to create exe1 by compiling sub1, exe2 by compiling sub2 and exe3 from sub3.
Can i add more than one directory in vpath?? or any other solution
You could simply have a very simple makefile in the test directory, just going into the subdirectories and calling makefiles in them. The subdirectories have makefiles that builds normally, but simply put the executable in the parent directory.
First of all: Yes you could add more than one directory in vpath. Each entry is separated with a colon ':'
vpath %.c test/sub1:test/sub2:test/sub3
But you'll getting into trouble as soon you have the same filename (with different content) in two directories. Consider:
test/Makefile
test/sub1/main.c
test/sub1/foo.c
test/sub1/bar.c
...
test/sub2/main.c
test/sub2/blish.c
test/sub3/blash.c
...
test/sub3/main.c
test/sub3/okEnoughForNow.c
And your makefile containing:
vpath %.c sub1:sub2:sub3
exe1.exe : main.c foo.c bar.c
gcc -o $# $^
exe2.exe : main.c blish.c blash.c
gcc -o $# $^
exe3.exe : main.c okEnoughForNow.c
gcc -o $# $^
The result would be:
gcc -o exe1.exe sub1/main.c sub1/foo.c sub1/bar.c
gcc -o exe2.exe sub1/main.c sub2/blish.c sub2/blash.c
gcc -o exe3.exe sub1/main.c sub3/okEnoughForNow.c
As you can see, all exe's contain sub1/main.c as this is the main.c found first; Its path appears first on the vpath.
Joachim's Approach is definitive a simple, and very common solution. I would choose it as well if the programs in your subfolders are completely unrelated: You could have in each directory a makefile containing something like:
SRC := $(wildcard *.c)
%.exe : $(SRC)
gcc -o $# $^
Assuming, all .c files in each of your sub* shall be part of your program, and there are no subfolders in your sub's. Otherwise you'll need a different approach to scan your .c files, or specify them individually.
In your main makefile you can run for each subfolder a new instance of make, using those makefiles. Which gives you a main Makefile like:
# Get all subfolders name without trailing slash
PROGS := $(patsubst %/,%,$(wildcard */))
# Each subfolder can be made by calling make in
# that folder. A file prog.exe is created.
.PHONY : $(PROGS)
$(PROGS) :
$(MAKE) -C $# prog.exe
# Now every .exe depends on its subfolder, calls
# Make there - see rule above and copies the
# prog.exe from there into the root, with the name
# of the subfolder. (Alternatively you could use
# mv instead of cp)
%.exe : %
cp $</prog.exe $#
Assuming the name of your .exe is the same as the directory name and all subfolders are containing programs.
However, calling make from a running make instance (recursive make) can cause a real headache as soon as there are any dependencies between the generated files of the subfolders.
Another solution:
A different approach whithout using recursive make is having rules dynamically created. In that case your main Makefile could look like this. (I'm again assuming all subfolders are containing programs, all subfolders are flat, and all .c files in those subfolders are part of your program) This has the advantage that you'll have to maintain just one makefile, and there can be any dependency between the different programs. But still it has the disadvantage that you cannot manage your different programs seperately.
That's the complete makefile:
%.exe :
gcc -o $# $^
PROGS := $(patsubst %/,%,$(wildcard */))
$(foreach P,$(PROGS),$(eval OBJ_$(P) := $(wildcard $(P)/*.c)))
$(foreach P,$(PROGS),$(eval $(P).exe : $(OBJ_$(P))))
.PHONY : all
all : $(addsuffix .exe,$(PROGS)
We're starting with a rule for compiling: Any .exe is generated by invoking gcc having all prerequisites as source files.
%.exe :
gcc -o $# $^
Then, next step is to obtain all "programs" by scanning for all subfolders and stripping off the trailing slash
PROGS := $(patsubst %/,%,$(wildcard */))
The next step is to create for each program a variable containig all Sources. Note the eval function expands, and passes everything to make as it has been written in the Makefile.
$(foreach P,$(PROGS),$(eval SRC_$(P) := $(wildcard $(P)/*.c)))
Thus the line above, with your sub1, sub2 and sub3 will become:
SRC_sub1 := $(wildcard sub1/*.c)
SRC_sub2 := $(wildcard sub2/*.c)
SRC_sub3 := $(wildcard sub3/*.c)
The eval function can even be used to create rules:
$(foreach P,$(PROGS),$(eval $(P).exe : $(SRC_$(P))))
So this will expand to (assuming the file structure in the example above)
sub1.exe : sub1/main.c sub1/foo.c sub1/bar.c
sub2.exe : sub2/main.c sub2/blish.c sub2/blash.c
sub3.exe : sub3/main.c sub3/okEnoughForNow.c
Now we have three rules without a recipe. Make says "if you have a rule without recipe, and an implicit rule that matches can be found, this rule is used with the prerequisites added from the rule that does not have the recipe" Thus, for those 3 rules the implicit rule of %.exe above applies.
Basically that's the trick. For your convenience you can add
.PHONY : all
all : $(addsuffix .exe,$(PROGS))
So make all makes everything.
Extension:
If you'd like to be able to make the .o files seperately as well, you could add one more implicit rule like:
%.o : %.c
gcc -c -o $# $<
and make your programs dependent on the .o rather than on the .c files:
$(foreach P,$(PROGS),$(eval OBJ_$(P) := $(patsubst %.c,%.o,$(wildcard $(P)/*.c))))
$(foreach P,$(PROGS),$(eval $(P).exe : $(OBJ_$(P))))
Then you'll have your .exe dependend on the .o that can be found by changing .c into .o after scanning all sources. Via the implicit rule chain %.o : %.c make will know what to do.

compile headers dependencies with makefile

I am programming an UDP client server application in the C programming language; I want to automatically compile 2 sources files and 3 header files whenever the dependencies change so I decided to use the make utility.
The makefile target is called "edit" :
edit : server_UDP.o client_UDP.o \
gcc -o edit server_UDP.o client_UDP.o \
client_UDP.o : client_UDP.c cliHeader_UDP.h wrapHeader.h
gcc -c client_UDP.c
server_UDP.o : server_UDP.c servHeader_UDP.h wrapHeader.h
gcc -c server_UDP.c
It doesn't trigger a recompile when I change a few lines of code in wrapHeader.h.
How do to I modify the edit makefile rule(s) when there is a change in wrapHeader.h to recompile server_UDP and client_UDP ?
**note : wrapHeader.h is the main header
cliHeader_UDP.h : include "wrapHeader.h"
servHeader_UDP.h : include "wrapHeader.h"
I think what you want are Make dependency files.
You can specify the compiler to generate a dependency file for you with the '-MMD -MP' arguments, which create a new file with the same name as the source file except with the extension *.d, in the same folder as your source.
The dependency file contains all the headers the code depends on, which will lead to GNU make compiling your source file if a header it uses is modified.
An example dependency file enabled makefile:
# Makefile
CC := gcc
LD := g++
# The output executable.
BIN := program
# Toolchain arguments.
CFLAGS :=
CXXFLAGS := $(CFLAGS)
LDFLAGS :=
# Project sources.
C_SOURCE_FILES := mysourcefile1.c src/myothersrc.c
C_OBJECT_FILES := $(patsubst %.c,%.o,$(C_SOURCE_FILES))
# The dependency file names.
DEPS := $(C_OBJECT_FILES:.o=.d)
all: $(BIN)
clean:
$(RM) $(C_OBJECT_FILES) $(DEPS) $(BIN)
rebuild: clean all
$(BIN): $(C_OBJECT_FILES)
$(LD) $(C_OBJECT_FILES) $(LDFLAGS) -o $#
%.o: %.c
$(CC) -c -MMD -MP $< -o $# $(CFLAGS)
# Let make read the dependency files and handle them.
-include $(DEPS)
This should work for your situation:
SOURCES := server_UDP.c client_UDP.c
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
DEPS := $(OBJECTS:.o=.d)
edit: $(OBJECTS)
gcc -o edit $(OBJECTS)
%.o: %.c
gcc -c $< -o $#
-include $(DEPS)
You did not say that edit.c includes your two specific headers, but I guess it must, if it links to the objects.
This is exactly the scenario where makepp plays out one of its strengths: If you follow the convention that for every .o file you need to link there is an include statement of a corresponding name (in your case that would be client_UDP.h & server_UDP.h) then makepp will figure everything out itself, besides detecting the header files as dependencies.
This even works recursively, so if you had a wrapHeader.c (where there is no corresponding include statement in edit.c), that would get automatically compiled and linked.
So you don't need a makefile. But if you want to avoid calling makepp edit everytime, then you can create a one-liner
edit:
You will only need to learn make syntax, if you have more complex requirements. But if you do, there is no limit. Besides doing almost all that GNU make can, there are lots more useful things, and you can even extend your makefiles with some Perl programming.

Resources