Makefile - wildcard, how to do that properly? - c++

FLAGS:= -Wall -Wvla -g -lm
OBJECT := Nominated.h UniversityNominated.h AliceGraduate.h BobGraduate.h CollegeNominated.h ColinGraduate.h DannyGraduate.h NominatedList.h Parser.h Parser.cpp
all: Hire
Nominated.o: Nominated.h Nominated.cpp
g++ -c $(FLAGS) Nominated.cpp -o Nominated.o
NominatedList.o: Nominated.h NominatedList.h NominatedList.cpp
g++ -c $(FLAGS) NominatedList.cpp -o NominatedList.o
UniversityNominated.o: Nominated.h UniversityNominated.h UniversityNominated.cpp
g++ -c $(FLAGS) UniversityNominated.cpp -o UniversityNominated.o
AliceGraduate.o: Nominated.h UniversityNominated.h AliceGraduate.h AliceGraduate.cpp
g++ -c $(FLAGS) AliceGraduate.cpp -o AliceGraduate.o
BobGraduate.o: Nominated.h UniversityNominated.h BobGraduate.h BobGraduate.cpp
g++ -c $(FLAGS) BobGraduate.cpp -o BobGraduate.o
CollegeNominated.o: Nominated.h CollegeNominated.h CollegeNominated.cpp
g++ -c $(FLAGS) CollegeNominated.cpp -o CollegeNominated.o
ColinGraduate.o: Nominated.h CollegeNominated.h ColinGraduate.h ColinGraduate.cpp
g++ -c $(FLAGS) ColinGraduate.cpp -o ColinGraduate.o
DannyGraduate.o: Nominated.h CollegeNominated.h DannyGraduate.h DannyGraduate.cpp
g++ -c $(FLAGS) DannyGraduate.cpp -o DannyGraduate.o
Parser.o: $(OBJECT)
g++ -c $(FLAGS) Parser.cpp -o Parser.o
Parser: Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ar rcu libParser.a Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ranlib libParser.a
Hire: Hire.cpp Parser
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *~
.PHONY: clean all
so this is my Makefile.
How can I make less ugly ?
I am always read about that but I can not get the idea
How ?
I mean I understand I need to use the wildcard tool but as you I probably used it wrong

Here's an example of how to use wildcard and pattern substitution:
SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp,%.o,$(SOURCES))
CXX := g++ -Wall -Wvla -g
.cpp.o:
${CXX} -c $<
This will build all the .cpp files into their object files.

There's many things you can do, but one of the best is a pattern rule for specific types. All of your objects seem to be built the same way.
%.o: %.cpp
${CXX} -c $(FLAGS) -o $# $<
You'll notice that this doesn't include any header files as dependencies. Manually maintaining the header dependencies in a Makefile is a bad idea because it's bound to get out of date as you modify your program. Sometimes your compiler can generate make-friendly dependencies for you automatically. Assuming you have a list of objects such as this:
OBJS := $(SOURCES:%.c=%.o)
You can include this at the very end of your Makefile (with no blank line afterward)
-include $(OBJS:.o=.d)
Then add, -MMD to your compiler flags. This will cause GCC to generate .d files that contain the header dependencies for each of your objects as a Make rule, and the above include line will include those rules and use them to resolve the dependencies of your objects. This will mean that any header change will cause all files that include it (directly or indirectly) to be rebuilt.

Try this:
FLAGS = -Wall -Wextra
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp,%.o,$(SRC))
DEP = $(patsubst %.cpp,%.d,$(SRC))
PARSER = $(filter-out Hire.o,$(OBJ))
all: $(DEP) build
build:
make Hire
%.d:
g++ -MM $*.cpp > $*.d
%.o: %.cpp
g++ $(FLAGS) -c $*.cpp
libParser.a: $(PARSER)
ar rcu libParser.a $(PARSER)
ranlib libParser.a
Hire: Hire.cpp libParser.a
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *.d *~
.PHONY: clean all
#
# This line includes all the dependencies.
# There is one for each file.
# Check the *.d files after you run make
-include $(DEP)

Related

Compile each cpp file in separate directory

The results for this topic strangely all did not work.
Finally I found a variant that is logical for me and works from the same order.
CC := g++
CFLAGS := -g -Wall
objects = test helloworld
all: $(objects)
$(objects): %: %.cpp
$(CC) $(CFLAGS) -o $# $<
I have tried a lot and probably fail to fully understand the line %: %.cpp.
My interpretation is: I take from every object the dependency which in turn is based on a file which is then traceable to a .cpp file.
My theory is test expects test.o and then test.cpp.
How do I rewrite this to directory?
I have already read some things with wildcards and a pattern replace.
Like
SRC_DIR := src
OBJ_DIR := obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...
main.exe: $(OBJ_FILES)
g++ $(LDFLAGS) -o $# $^
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
But the behavior was not the expected.
When 2 cpp files were in the folder the result was
g++ -o helloworld.o helloworld.cpp
g++ -o helloworld.o test.cpp
Or vice versa that only the cpp file was always the same.
I have the feeling to miss something extremely.
Update:
The make version is
GNU Make 4.3
Built for aarch64-unknown-linux-android
The Goal
What I would like to achieve is
src/
Test.cpp
Helloworld.cpp
Obj/
Make :
Obj/
Helloworld.out
Test.out
Try this:
CXX := g++
CXXFLAGS := -g -Wall
TARGETS=obj/test.out obj/helloworld.out
all:$(TARGETS)
obj/%.out:src/%.cpp
$(CXX) $(CXXFLAGS) -o $# $^
clean:
rm obj/*

Makfile usees same cpp file to generate objects [duplicate]

This is a part of my makefile :
SRC = ./
DIRS = src libs/maths libs/struct
BIN_DIR = ./bin/
SRC_DIRS= $(foreach dir, $(DIRS), $(addprefix $(SRC), $(dir)))
SRC_TEST= $(sort $(SRC_DIRS))
SRCS = $(foreach msrc, $(SRC_DIRS), $(wildcard $(msrc)/*.c))
DEL_PRE = $(foreach target, $(SRCS), $(notdir $(target)))
ADD_PRE = $(foreach target, $(DEL_PRE), $(addprefix $(BIN_DIR), $(target)))
OBJS = $(ADD_PRE:.c=.o)
.PHONY: all clean re
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(OBJS) -o $# $(LDLIBS)
$(OBJS): $(SRCS)
$(CC) -o $# -c $<
When i use make all, i have in output :
gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c src/main.c
gcc -o bin/pears.o -c src/main.c
gcc -o bin/outil.o -c src/main.c
gcc -o bin/verif.o -c src/main.c
But i would like to have for each target, it assigned dependency :
gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c libs/maths/cosin.c
gcc -o bin/pears.o -c libs/maths/pears.c
gcc -o bin/outil.o -c libs/struct/outil.c
gcc -o bin/verif.o -c libs/struct/verif.c
How can i fix it ?
This seems like a very common misconception; I just answered effectively this same question yesterday. I'm not sure where it comes from or how to combat it.
This rule:
$(OBJS): $(SRCS)
$(CC) -o $# -c $<
does not somehow magically combine the contents of the OBJS variable and the SRCS variable to figure out how they match up. The variable references are simply expanded, and the result is this:
bin/main.o bin/cosin.o ... : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
which is the same as if you'd written this:
bin/main.o : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
bin/cosin.o : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
...
Now, you can hopefully see why you compile the same file: in every rule you have the same prerequisites, so $< is always the first one, which is always src/main.c.
There are multiple ways to work this but if you really want to have all the source files from different directories compiled into object files in the same directory your job is harder, because there's no common pattern that will match them all. In this case the simplest thing to do is use VPATH for directory search: replace the above rule with this:
$(BIN_DIR)/%.o : %.c
$(CC) -o $# -c $<
then tell make how to find your source files, like this:
VPATH := $(sort $(dir $(SRCS))
Be aware this method can't be used for any source files that are themselves generated output that make is expected to create.

Compile All source file in a directory and store objs in different directory

Following is my make file
CC = g++
CFLAGS = -Wall -c -fPIC
INCLUDES = -I${HOME}/ComingSoon/api/include
LFLAGs = -L${HOME}/ComingSoon/lib
LIB_DIR = ${HOME}/ComingSoon/lib
LIBS = -lapi
API_SRCDIR = ${HOME}/ComingSoon/api/source
API_SOURCE = $(wildcard ${HOME}/ComingSoon/api/source/*.cpp)
#API_SOURCE = $(shell find $(API_SRCDIR) -name '*.cpp')
API_OBJ_SOURCE = $(wildcard ${HOME}/ComingSoon/api/obj/*.o)
OBJS_DIR_API = ${HOME}/ComingSoon/api/obj/
OBJS = $(patsubst $(API_SRCDIR)/%.cpp,$(OBJS_DIR_API)%.o,$(API_SOURCE))
api: $(OBJS)
$(OBJS): $(API_SOURCE) Makefile
$(CC) $(CFLAGS) $(INCLUDES) $< -o $#
clean_api:
rm -rf ${HOME}/ComingSoon/lib/*.so
rm -rf ${HOME}/ComingSoon/api/obj/*.o
I want to complie all the source files in the source directory.
The make file is compiling as
g++ -Wall -c -fPIC -I/home/soumya/ComingSoon/api/include /home/soumya/ComingSoon/api/source/multiply.cpp -o /home/soumya/ComingSoon/api/obj/multiply.o
g++ -Wall -c -fPIC -I/home/soumya/ComingSoon/api/include /home/soumya/ComingSoon/api/source/multiply.cpp -o /home/soumya/ComingSoon/api/obj/add.o
But the output should be as follows
g++ -Wall -c -fPIC -I/home/soumya/ComingSoon/api/include /home/soumya/ComingSoon/api/source/multiply.cpp -o /home/soumya/ComingSoon/api/obj/multiply.o
g++ -Wall -c -fPIC -I/home/soumya/ComingSoon/api/include /home/soumya/ComingSoon/api/source/add.cpp -o /home/soumya/ComingSoon/api/obj/add.o
The makfile is compiling the same source file to make two different object file. Where I am doing wrong?
What should I use in place of
$(OBJS): $(API_SOURCE) Makefile
Your API_SOURCE variable contains multiply.cpp add.cpp, so your rule comes out to:
$(OBJS): multiply.cpp add.cpp Makefile
$(CC) ... $< -o $#
So $< always expands to multiply.cpp. The correct way is to write a pattern rule:
$(OBJS_DIR_API)%.o: $(API_SRCDIR)/%.cpp Makefile
$(CC) ... $< -o $#

GCC linking a static library

I have seen questions like these on SO but everyone has different answers and directory structures that aren't working for me.
My makefile:
CC = g++
DEBUG = -g -std=c++11
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
start: clean BingResultSet.o main.o
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
rm -f *.o
BingResultSet.o: BingResultSet.cpp BingResultSet.h
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c BingResultSet.cpp
main.o: main.cpp
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c main.cpp
clean:
rm -f $(OBJECT_FILES) $(TARGET)
My file structure:
/Desktop/DataMiner/.cpp, .h, and makefile
/Desktop/DataMiner/HTTPClientLib/include/HTTPClient.h
/Desktop/DataMiner/HTTPClientLib/lib/HTTPClient.a
What's the correct way to link my static lib in my makefile?
Here's my $0.02:
there was no static library involved. Assuming you meant the .o files
you mix dependencies and build rules, instead, avoid repeating build rules:
$(TARGET): $(OBJECT_FILES)
$(CXX) $(DEBUG) $(INC_PATH) $^ -o $# $(LIB_PATH)
%.o: %.cpp
$(CXX) $(DEBUG) $(INC_PATH) -c $< -o $#
You used CC for a C++ compiler. That's strange. Use CXX
You used LDFLAGS when you were just compiling
You hardcoded the source and destination paths. Instead use the automatic variables ($^, $< for source; $# for destination)
You tried to hardcode header dependencies. That's error-prone and messes up source specification (you don't want $^ to list .h files in your command line...). Instead, use gcc -MM¹ to generate the dependencies for you!
Next, do a conditional include of those dependencies:
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
It's usually handy to keep the .o files so you can speed up builds. Of course, this was not a good plan until you generated the header dependencies automatically. If you insist, you can comment the .PRECIOUS target. Intermediate targets are automatically deleted by GNU Make
Here's the integrated offering I ended up with:
CXX = g++
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
CPPFLAGS = -g -std=c++11
CPPFLAGS+= $(INC_PATH)
# standard derived flags:
CXXFLAGS+=$(CPPFLAGS)
LDFLAGS+=$(LIB_PATH)
start: .depends $(TARGET)
$(TARGET): $(OBJECT_FILES)
$(CXX) $(CXXFLAGS) $^ -o $# $(LDFLAGS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
clean:
rm -f .depends $(OBJECT_FILES) $(TARGET)
# to keep the .o files:
.PRECIOUS: $(OBJECT_FILES)
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
On a very simple sample set of files you get:
$ make clean
rm -f .depends BingResultSet.o main.o main
$ make
g++ -MM -g -std=c++11 -I HTTPClientLib/include -c *.cpp > .depends
g++ -I HTTPClientLib/include -c BingResultSet.cpp -o BingResultSet.o
g++ -I HTTPClientLib/include -c main.cpp -o main.o
g++ -I HTTPClientLib/include BingResultSet.o main.o -o main -L HTTPClientLib/lib/
$ cat .depends
BingResultSet.o: BingResultSet.cpp BingResultSet.h
main.o: main.cpp BingResultSet.h
test.o: test.cpp
¹ (or similar, see man-page)

make objects in Makefile

I have the following Makefile:
CXX = g++
CXXFLAGS = -Wall -g
SOURCES := divisor.cpp multiplier.cpp
OBJECTS := ${SOURCES:.cpp=.o}
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
%: %.o $(OBJECTS)
$(CXX) $(CXXFLAGS) $#.o -o $#.out
$(OBJECTS): %.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
clean:
rm -f *.o
What I want this make file is the following:
If I add a source file called 123.cpp to the working directory, I want it to generate its object file and then link the compiled sources specified in $(SOURCES), this means:
g++ -c -Wall -g 123.cpp
g++ multipler.o divisor.o 123.o -o 123
If multiplier.cpp or divisor.cpp has to be generated or updated, I want make to do it.
But I'm failing, because divisor.o and multiplier.o are not automatically generated
How may I achieve this?
Edit
Just to clarify, there are two types of source code files in the working directory: divisor.cpp, multipler.cpp is one type, and any other file, say, 123.cpp is the other type. In a sense, divisor.cpp and multiplier.cpp are requisites to the other source files.
I want to automate the process of compiling the prerequisites and link them when compiling the other files
g++ -c multiplier.cpp
g++ -c divisor.cpp
g++ -c -Wall -g 123.cpp
g++ multipler.o divisor.o 123.o -o 123
Use the wildcard function:
SOURCES := $(wildcard *.cpp)
Then, you can remove your "special" source files:
SPECIAL_SOURCES := divisor.cpp multiplier.cpp
SOURCES := $(filter-out $(SPECIAL_SOURCES),$(SOURCES))
And change your rules to build the stuff you actually want:
$(SPECIAL_OBJECTS) := $(SPECIAL_SOURCES:.cpp=.o)
$(BINARIES) := $(patsubst .cpp,,$(SOURCES))
$(SPECIAL_OBJECTS) : %.o : %.cpp
$(CXX) $(CXXFLAGS) -c -o $# $^
$(BINARIES) : % : %.cpp $(SPECIAL_OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $^