how to expand variables to multiple rules in makefile? - makefile

Say that I have two variables in Makefile
CXXFILES = a.cpp b.cpp
OBJFILES = a.o b.o
I would like to write a rule that will expand to
a.cpp : a.o
g++ -o a.o a.cpp
b.cpp : b.o
g++ -o b.o b.cpp
Note that I'm not looking for
%.o : %.cpp
g++ -o $# $<
because I don't want to match all .cpp files -- I only want those files specified by a variable.

Sounds like a job for a Static Pattern Rule:
Here is an example, which compiles each of foo.o and bar.o from the
corresponding .c file:
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $#

Related

Makefile multiple sources ouputs variable expansion

suppose CC variable is a compiling command and we don't need any additional flags. Simple part of makefile compiling main.c and next.c to main.o and next.o:
all: main.o next.o
%.o : %.c
$(CC) $< -o $#
Now suppose I would like to have output files in variable:
all: $(OBJ)
OBJ = main.o next.o
%.o : %.c
$(CC) $< -o $#
Of course it won't work. I understand why but I can't find solution. Can you help me?

How to convert a source c files to corresponding .o files using suffix rule in makefile?

Suppose we have a.c b.c c.c .So the make file will like this
app: a.o b.o c.o
gcc -o app.o a.o b.o c.o
a.o: a.c
gcc -c a.c
b.o: b.c
gcc -c b.c
c.o: c.c
gcc -c c.c
In the future more C files may be added. So do I need to make target of .o extensions for each .c file. I got to know about suffix rules which uses the .source-extension.target-extension. But I could understand how to use this suffix rule in the make file. Please provide me the command to be included in make file and please describe the syntax.I am newbie to makefile.
You can use the below makefile.
app: a.o b.o c.o
gcc -o $# $^
a.o : a.h
b.o : b.h
c.o : c.h
%.o: %.c
gcc -c $<
Where $# is the target(app), $^ is the list of dependencies and $< is the corresponding c file to compile to object file
Below is the sample makefile for compiling c code.
TARGET = a.out
SRCS = a.c b.c c.c
OBJS = $(SRCS:.c=.o)
CFLAGS = -g -ggdb -O2 -Wall -Werror
CC = gcc
RM = rm
.PHONY: all clean
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET) : $(OBJS)
$(CC) $^ -o $#
clean:
$(RM) *.o
$(RM) $(TARGET)

Generate makefile targets from a list of source files

I'm trying to create a build system using make and would like to do the following:
have a list of source files specified in the makefile, e.g.
SOURCES = a.cpp b.cpp c.cpp
Automatically create build targets that depend on each file separately
I.e a single rule that would automatically expand into:
a.o: a.cpp
$(CC) $(CFLAGS) -c a.cpp -o a.o
b.o: b.cpp
$(CC) $(CFLAGS) -c b.cpp -o b.o
c.o: c.cpp
$(CC) $(CFLAGS) -c c.cpp -o c.o
I've tried the following:
SOURCES = a.cpp b.cpp c.cpp
OBJECTS = $(SOURCES:.cpp=.o)
$(OBJECTS): $(SOURCES)
$(CC) $(CFLAGS) -c $< -o $#
However, this seems to expand into the following
a.o: a.cpp b.cpp c.cpp
$(CC) $(CFLAGS) -c a.cpp -o a.o
b.o: b.cpp b.cpp c.cpp
$(CC) $(CFLAGS) -c a.cpp -o b.o
c.o: c.cpp b.cpp c.cpp
$(CC) $(CFLAGS) -c a.cpp -o c.o
Which is not right
Is there a simple way to achieve the result that i wrote earlier?
Make already has built-in rules that convert a .cpp file to a .o file. Just write:
SOURCES = a.cpp b.cpp c.cpp
all: $(SOURCES:.cpp=.o)
and it will work. If you want to know how to write your own rules, read about implicit rules, in particular pattern rules.

A simple Makefile that doesn't create the executable file

I have the following Makefile:
CC = gcc
OBJS = a.o b.o c.o
EXEC = prog
DEBUG = #-g for debug
CFLAGS = -std=c99 -Wall -Werror $(DEBUG)
$(EXEC) : $(OBJS)
a.o : a.c a.h b.h
b.o : b.c b.h
c.o : c.c c.h b.h
clean:
rm -f $(OBJS) $(EXEC)
It creates the object files but it doesn't create the executable file - prog.
How do I fix it?
Thanks!
$(EXEC): $(OBJS)
$(CC) -o $# $(CFLAGS) $(OBJS)
Basically, when you list multiple objects as dependencies, the implicit rules can't be used, so you have to write the command to execute yourself. The $# is a shorthand for $(EXEC) in this case; it is the target being created.

Apply the same compilation command to several source files

Let's say I have several .cpp files which are built by the same way:
main.o : main.cpp
$(CC) -c main.cpp $(COMPILATION_FLAGS)
file1.o : file1.cpp
$(CC) -c file1.cpp $(COMPILATION_FLAGS)
file2.o : file2.cpp
$(CC) -c file2.cpp $(COMPILATION_FLAGS)
How can I write this command only once, and then apply it to main, file1 and file2, to exclude code duplication?
http://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html
http://www.gnu.org/software/make/manual/html_node/Pattern-Examples.html#Pattern-Examples
Something like
%.o : %.cpp
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $#
should do what you want.
Why don't you use CFLAGS and CPPFLAGS rather than COMPILATION_FLAGS?

Resources