How to add all rule to process task A (then) -> task B - makefile

I have
todo: $(SRC)
$(CC) -o todo $^ $(CFLAGS)
ctodo: $(LIBS)
$(CC) ${INCLUDES} -c -o todo.a $^ $(CFLAGS)
I want to have some kind of all by default which will build library first and todo after it.
alike all: ctodo -> todo (in pseudocode) How to make it?

Your question is a little unclear, but in general the way to get Make to execute rules in order is to make one a prerequisite of another:
.PHONY: all
all: todo
todo: $(SRC) | ctodo
$(CC) -o todo $^ $(CFLAGS)
ctodo: $(LIBS)
$(CC) ${INCLUDES} -c -o todo.a $^ $(CFLAGS)
(I've used the | so that ctodo won't show up in $^.)

Related

How to write a general pattern in makefile

I have multiple programs which share the same structure of compilation.
test_variance : test_variance.o
$(CPP) -o test_variance.exe $(CFLAGS) test_variance.o $(LIBDIR) $(LIBS)
test_variance_incremental: test_variance_incremental.o
$(CPP) -o test_variance_incremental.exe $(CFLAGS) test_variance_incremental.o $(LIBDIR) $(LIBS)
test_hyper: test_hyper.o
$(CPP) -o test_hyper.exe $(CFLAGS) test_hyper.o $(LIBDIR) $(LIBS)
test_hyper.o: test_hyper.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_hyper.cpp
test_variance_incremental.o: test_variance_incremental.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_variance_incremental.cpp
test_variance.o : test_variance.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c test_variance.cpp
So for compling .o, I can use the pattern
%.o: %.cpp
$(CPP) $(CFLAGS) $(INCLUDES) -c $<
I wonder if there is a general pattern for compling the executive. I've tried
TARGETS = test_variance test_variance_incremental test_hyper
$(TARGETS): $#.o
$(CPP) -o $#.exe $^ $(CFLAGS) $(LIBDIR) $(LIBS)
But Make tells me there is no input files and I think my usage of $# is wrong. Any advice?
You should use CC and CFLAGS for compiling C code, and CXX and CXXFLAGS for compiling C++ code. CPP (in make) is used for running the C preprocessor (only). The standard variable to hold libraries is LDLIBS.
If you use these variables then you don't even need to define your own rules at all: there are built-in rules in make that already know how to compile and link C++ programs. All you need is this:
TARGETS = test_variance test_variance_incremental test_hyper
all: $(TARGETS)
Anyway, if you want to write it explicitly you can write:
TARGETS = test_variance test_variance_incremental test_hyper
all: $(TARGETS)
% : %.o
$(CXX) -o $# $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
(you should definitely not name the target test_variance, but then have your link line build test_variance.exe: the target name and the file that the recipe builds must always be the same).

How to write build target for sources from different paths?

At first, I'm a noobie in makefiles...
I have next targets in my Makefile:
$(BUILD_PATH)/%.o: %.c $(GEN_PATH)/%.c
$(CC) $(FLAGS) $(CFLAGS) $(HEADERS) -c $< -o $#
server: $(BUILD_PATH)/main.o $(BUILD_PATH)/socket.o $(BUILD_PATH)/settings.o $(BUILD_PATH)/options.o
$(CC) -L$(LIB_PATH) -Wl,-rpath=$(LIB_PATH) $(FLAGS) $(CFLAGS) -o $(DIST_PATH)/server $^ $(LDFLAGS)
I specified that object files must be compiled from the current folder and $(GEN_PATH) but it doesn't work and I am getting error:
make: *** No rule to make target '../build/server/options.o', needed by 'server'. Stop.
How can I write this rule right?
P.S. It's not primary question but how can I write my input targets shorter? I tried this variant:
server: $(BUILD_PATH)/%.o
$(CC) -L$(LIB_PATH) -Wl,-rpath=$(LIB_PATH) $(FLAGS) $(CFLAGS) -o $(DIST_PATH)/server $^ $(LDFLAGS)
But it didn't work.

How to replace parent directory in Makefile

I've the following situation:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp modelChecking/Estado.cpp modelChecking/Formula.cpp modelChecking/ModelChecking.cpp lib/VisitTree.cpp
SUFIX=$(SOURCES:.cpp=.o)
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
home/main.o: home/main.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Estado.o: modelChecking/Estado.cpp
$(CC) $(CFLAGS) $< -o $#
...
...and so on.
As you can see, I have different directories to compile my executable.
Now, I want to put every file .o in the bin/ folder and the variable OBJECT must replace the every parent directory, and I tried different ways:
OBJECTS=$(SUFIX:%/ = bin/)
OBJECTS=$(subst %/,bin/,$(SUFIX))
OBJECTS=$(patsubst %/,bin/,$(SUFIX))
When I use something like this $(subst home/,bin/,$(SUFIX)) it works, because I type the substring "home/", but I need of a regular expression to replace all directories.
And I'll need to change the target too, perhaps the code below will works:
%.o: %.cpp
$(CC) $(CFLAGS) $< -o $#
... But I prefer every target separate
You are looking for SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
The Makefile will look like:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
bin/main.o: home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
bin/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
However I suggest to use SUBDIRS instead. Create to Makefiles
Makefile
SUBDIRS = bin
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $#
bin/Makefile
SOURCES=../home/main.cpp ../modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
main.o: ../home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
Configuracao.o: ../modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
This way you will not have to worry about object prefix.

Makefile generic binaries compilations

I have a set of source files that share the same Makefile rule pattern:
bin1: bin1.o libfoo.a
$(LDENV) $(CC) $(CFLAGS) $(LDFLAGS) -o $# $^
bin2: bin2.o libfoo.a
$(LDENV) $(CC) $(CFLAGS) $(LDFLAGS) -o $# $^
bin3: bin3.o libfoo.a
$(LDENV) $(CC) $(CFLAGS) $(LDFLAGS) -o $# $^
...
Now, how may I refactor this to avoid repeating the same rule over and over? This is easy if a file extension is added to the binaries:
%.out: %.o libfoo.a
$(LDENV) $(CC) $(CFLAGS) $(LDFLAGS) -o $# $^
But is it possible to do the same without using one?
You can use Static Pattern Rules:
bin1 bin2 bin3: %: %.o libfoo.a
$(LDENV) $(CC) $(CFLAGS) $(LDFLAGS) -o $# $^
This way this is cleaner and you are sure that the % only match bin1, bin2 and bin3 targets (I think this is want you want).

How to make this Makefile more concise?

I know there are ways to remove duplicates $(CC) $(CFLAGS) $# $^ in Makefile. Can you tell me how to make the Makefile below more concise?
CC=gcc
CFLAGS=-pthread -g -o
all: p1 p2
p1: p1.c
$(CC) $(CFLAGS) $# $^
p2: p2.c
$(CC) $(CFLAGS) $# $^
To make your Makefile more concise, you can write it as follows.
CC=gcc
CFLAGS=-pthread -g -o
all: p1 p2
%: %.c
$(CC) $(CFLAGS) $# $^
Then you can add as many p's as you want on the all: line. As long as you provide pN.c, make will compile them into the corresponding pN.
Yes, you can combine commands "by prerequisite". For example:
CC=gcc
CFLAGS=-O3
INCLS=-I$(BASEDIR)/include
LIBS=$(BASEDIR)/lib/thread.a
OBJS = dotprod_mutex.o dotprod_serial.o
EXEC = dotprod
$(EXEC): $(OBJS)
$(CC) -o $(EXEC) $(OBJS) $(LIBS)
$(OBJS): dotprod.h
$(CC) $(CFLAGS) $(INCLS) -c $*.c
or somesuch -- you'll need to go through the details and make sure those libraries and so on actually make sense.
Note that the phrase $(OBJS): dotprod.h means that $(OBJS): depends on the presence of dotprod.h.
You will want to read the manual to get all the gory details, in particular:
Letting Make deduce commands
Combine by prerequisite
As for tools to automate this stuff, you want automake and autoconf: http://sourceware.org/autobook/

Resources