Failing to link to SFML libraries using Makefile even though it works as a one liner - makefile

Here is my directory structure :
.
├── a.out
├── assets
│   └── ...
├── build
│   ├── apps
│   └── objects
├── include
│   └── engine
│   └── Class.h
├── Makefile
└── src
├── engine
│   └── Class.cpp
└── program.cpp
I can compile program.cpp into a.out using the following command :
g++ src/engine/*.cpp src/program.cpp -Iinclude/ -L/usr/lib -lstdc++ -lm -lsfml-graphics -lsfml-window -lsfml-system -Wall
While this works, this project is likely to grow and obviously making a serious Makefile would be preferable to direct compiling with a one liner. So I've used a Makefile format that I've used many times before, and that works perfectly fine but I've never linked it to outside libraries in the past. Here is the Makefile I'm using :
CXX := -g++
CXXFLAGS := -std=gnu++0x -g -Wall
LDFLAGS := -L/usr/lib -lstdc++ -lm -lsfml-graphics -lsfml-window -lsfml-system
BUILD := ./build
OBJ_DIR := $(BUILD)/objects
APP_DIR := $(BUILD)/apps
TARGET := program
INCLUDE := -Iinclude/
SRC := $(wildcard src/engine/*.cpp) $(wildcard src/*.cpp)
OBJECTS := $(SRC:%.cpp=$(OBJ_DIR)/%.o)
all: build $(APP_DIR)/$(TARGET)
$(OBJ_DIR)/%.o: %.cpp
#mkdir -p $(#D)
$(CXX) $(CXXFLAGS) $(INCLUDE) -o $# -c $<
$(APP_DIR)/$(TARGET): $(OBJECTS)
#mkdir -p $(#D)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/$(TARGET) $(OBJECTS)
.PHONY: all build clean debug release
build:
#mkdir -p $(APP_DIR)
#mkdir -p $(OBJ_DIR)
debug: CXXFLAGS += -DDEBUG -g
debug: all
release: CXXFLAGS += -O2
release: all
clean:
-#rm -rvf $(OBJ_DIR)/*
-#rm -rvf $(APP_DIR)/*
However, this leads to compilation errors, in the form of undefined references to SFML methods :
./build/objects/src/engine/Class.o: In function `Class::draw()':
/dir/Class.cpp:60: undefined reference to `sf::RenderTarget::getView() const'
I'm confused as to why this happens given that the one liner above compiles fine. The Makefile also works just fine if I remove all references to SFML from my code. Were the added LDFLAGS not enough even though they're all that's needed to make my one liner link to SFML ? If so, what else is needed ?

From gcc link options
-llibrary
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
So put the libraries (-l<lib_1> ... -l<lib_x>) last on the line, after your object files.

Related

C++ Makefile path include and src directory makefile

I'm trying to create a Makefile for my C++ project, which has the following structure:
root
├── include/
| └──external
| └── stb_image.h
│ └── all .h files here
├── src/
| └── main.cpp
│ └── all .cpp files here
└── Makefile
To compile this project, I'm trying to use the Makefile proposed in this answer, which is for gcc, but I have added CC:=g++ so it should work (I think):
SRC_DIR := src
OBJ_DIR := obj
BIN_DIR := bin
EXE := $(BIN_DIR)/color
SRC := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
CPPFLAGS := -Iinclude -MMD -MP
CFLAGS := -g -std=c++2a -Wall
LDFLAGS := -Llib
LDLIBS := -lpthread
CC := g++
.PHONY: all clean
all: $(EXE)
$(EXE): $(OBJ) | $(BIN_DIR)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
$(BIN_DIR) $(OBJ_DIR):
mkdir -p $#
clean:
#$(RM) -rv $(BIN_DIR) $(OBJ_DIR)
-include $(OBJ:.o=.d)
But when running make I obtain a very long error which I do not understand. I do not know if this error comes from having main.cpp without a main.h.
I need this makefile because I want to separate the declarations and the implementations of my project. Before doing that, I had everything done in headers files and I could compile my project with the following command:
g++ -g -std=c++2a -Wall -Isrc/include -o bin/color.exe src/main.cc -lpthread
Any idea what am I doing wrong? I still do not know a lot about Makefiles, so maybe I'm doing something weird.

Getting Make to automatically detect changes in protocol buffers

I want Make to automatically compile protos when I update them, here is what I've got so far:
TARGET=main
BIN_DIR=bin
SRC_DIR=src
OBJ_DIR=obj
PROTO_DIR=protos/
PROTO_COMPILE_DIR=src/$(PROTO_DIR)
CC = g++
CFLAGS = -Wall -std=c++17 -ggdb -pipe -I.
LINKER = g++
LFLAGS = $(CFLAGS) -lprotobuf
SOURCES = $(wildcard src/*.cc) \
$(wildcard src/protos/*.cc) \
$(wildcard src/db_handler/*.cc)
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cc=$(OBJ_DIR)/%.o)
$(BIN_DIR)/$(TARGET): proto $(OBJECTS)
#mkdir -p $(BIN_DIR)/
$(LINKER) $(OBJECTS) $(LFLAGS) -o $#
$(OBJECTS): $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
#mkdir -p obj/ obj/protos obj/db_handler
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: proto
proto:
#printf "Compiling protos...\n"
#cd $(PROTO_DIR) && protoc * --grpc_out=../$(PROTO_COMPILE_DIR)\
--cpp_out=../$(PROTO_COMPILE_DIR)\
--plugin=protoc-gen-grpc="/usr/local/bin/grpc_cpp_plugin"\
&& cd ../
It successfully compiles protos; but, it does so every time, even if there are no changes in files. How can I prevent this and compile protos only if protos change?
Edit: Added project structure
├── LICENSE
├── makefile
├── protos
│   ├── client.proto
│   └── person.proto
├── README.md
└── src
├── db_handler
│   ├── db_handler.cc
│   └── db_handler.h
├── main.cc
└── protos
├── client.grpc.pb.cc
├── client.grpc.pb.h
├── client.pb.cc
├── client.pb.h
├── person.grpc.pb.cc
├── person.grpc.pb.h
├── person.pb.cc
└── person.pb.h
You want to add the source files of the protocol buffers to the right (the prerequisites) of the rule that cares about them. This is how Make understands and tracks their time stamps.
By adding the files to the prerequisites, Make will understand that this is the rule which cares about those source files.
PROTO_SOURCES := $(wildcard $(PROTO_DIR)/*.proto)
PROTOS := $(patsubst $(PROTO_DIR)/%.proto,$(PROTO_COMPILE_DIR)/%.cc,$(PROTO_SOURCES))
$(PROTOS): $(PROTO_SOURCES)
#printf "Compiling protos...\n"
#cd $(PROTO_DIR) && protoc * --grpc_out=../$(PROTO_COMPILE_DIR)\
--cpp_out=../$(PROTO_COMPILE_DIR)\
--plugin=protoc-gen-grpc="/usr/local/bin/grpc_cpp_plugin"
However, this $(PROTOS) : $(PROTO_SOURCES) is not good if you use parallel builds; because, Make will try to run the command once for each output file. So, make will run N instances of the command at the same time, which means they may clobber each other.
In order to know the fully correct solution you need to provide more information (for those not familiar with protoc). Is it a requirement that you invoke protoc once with all inputs? Or is it valid to run protoc individually on each input .proto file to get its output? Then you can write a pattern rule that generates one file at a time.
Note 1: As to your other attempt, if you use .PHONY to mark the rule then Make will rebuild the rule every time weather it needs to or not.
Note 2: You don't need the cd .. at the end of the second instruction, since it is run in a sub shell.
Thanks to #FiddlingBits I managed to figure out how to do it correctly
TARGET=main
BIN_DIR=bin
SRC_DIR=src
OBJ_DIR=obj
PROTO_DIR=protos/
PROTO_COMPILE_DIR=src/$(PROTO_DIR)
rm = rm -f
CC = g++
CFLAGS = -Wall -std=c++17 -ggdb -pipe -I.
LINKER = g++
LFLAGS = $(CFLAGS) -lprotobuf
SOURCES = $(wildcard src/*.cc) \
$(wildcard src/protos/*.cc) \
$(wildcard src/db_handler/*.cc)
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cc=$(OBJ_DIR)/%.o)
PROTOS := $($(PROTO_DIR)/%.proto=$(PROTO_COMPILE_DIR)/%.cc)
$(BIN_DIR)/$(TARGET): $(PROTOS) $(OBJECTS)
echo $(PROTOS)
#mkdir -p $(BIN_DIR)/
$(LINKER) $(OBJECTS) $(LFLAGS) -o $#
$(OBJECTS): $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
#mkdir -p obj/ obj/protos obj/db_handler
$(CC) $(CFLAGS) -c $< -o $#
$(PROTOS):
#printf "Compiling protos...\n"
#cd $(PROTO_DIR) && protoc * --grpc_out=../$(PROTO_COMPILE_DIR)\
--cpp_out=../$(PROTO_COMPILE_DIR)\
--plugin=protoc-gen-grpc="/usr/local/bin/grpc_cpp_plugin"\
&& cd ../
.PHONY: clean
clean:
#$(rm) -r $(OBJ_DIR)/*
#$(rm) -r $(BIN_DIR)/*
#printf "Cleanup complete!\n"

*.c not rebult when dependency x.h changed, using auto-generated *.d file

I am facing one issue while handling dependency files during compilation. I am just giving you the scenario which I faced in my project.
I have two C source files called a.c, b.c which includes one header file called c.h. I ran makefile which has instructions to compile both files. I can successfully compile the a.c file, but I have seen some failures while comping b.c which requires to do some changes in c.h to fix that issue. After I made change in c.h and trigger build (incremental build) the a.c file should compile again, too, right? Because a.c also depends on the c.h file.
I followed all dependency mechanism (creating auto dependency files & including .d files, etc)
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
-include $(DEPSALL)
$(TGTFILES)/%.o: $(TGTFILES)/%.c
mkdir -p $(#D)
$(CC64) -MT $# -MMD -MP -MF $(patsubst %,%.d,$(basename $#)) -o $(#) -c $(CFLAGS64) $<
...
...
Am I missing something here? I want to rebuild all the .c files which are including the particular header file which I changed.
Your question is incomplete: you do not really describe the problem you are facing (but we can probably guess that object files are not rebuilt while they should) and the part of the Makefile you show is not sufficient to understand what your goals are.
Anyway, first of all, this expression:
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
is uselessly complex. It is equivalent to the much simpler and easier to understand:
DEPSALL := $(wildcard $(TGTFILES)/*.d))
Similarly, in your compilation recipe you can replace:
$(patsubst %,%.d,$(basename $#))
by:
$(TGTFILES)/$*.d
But let's go back to your main problem (at least what I guess is your main problem): when modifying your header file, some object files are not rebuilt while they should.
My guess is that you think:
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
will assign to DEPSALL a list of dependency files, one per source file, like this other form would do:
DEPSALL := $(patsubst %.c,%.d,$(wildcard $(TGTFILES)/*.c))
If this is what you think, then you are wrong. Your version will assign to DEPSALL the list of dependency files that currently exist in $(TGTFILES) when you invoke make. If some (or all) are missing, some object files will not be rebuilt...
I suggest that you carefully read this excellent post about Auto-Dependency Generation. If you adapt it to your set-up, you should end up with something like:
TGTFILES := tgtfiles
SRCS := $(wildcard $(TGTFILES)/*.c)
OBJS := $(patsubst %.c,%.o,$(SRCS))
DEPS := $(patsubst %.c,%.d,$(SRCS))
INCLUDES := include
CFLAGS += -I$(INCLUDES)
.PHONY: objs clean
objs: $(OBJS)
%.o: %.c
%.o: %.c %.d
$(CC) -MT $# -MMD -MP -MF $*.Td $(CFLAGS) $(CPPFLAGS) -c -o $# $<
#mv -f $*.Td $*.d && touch $#
%.d: ;
.PRECIOUS: %.d
clean:
rm -f $(OBJS) $(DEPS)
include $(DEPS)
Several aspects may look strange, useless or even completely wrong. But if you carefully read the above mentioned post you will see that it perfectly makes sense. Demo:
$ tree
.
├── Makefile
├── include
│   └── c.h
└── tgtfiles
├── a.c
└── b.c
2 directories, 4 files
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude -c -o tgtfiles/a.o tgtfiles/a.c
$ tree
.
├── Makefile
├── include
│   └── c.h
└── tgtfiles
├── a.c
├── a.d
├── a.o
├── b.c
├── b.d
└── b.o
2 directories, 8 files
$ cat tgtfiles/a.d
tgtfiles/a.o: tgtfiles/a.c include/c.h
include/c.h:
$ make
make: Nothing to be done for 'objs'.
$ touch include/c.h
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude -c -o tgtfiles/a.o tgtfiles/a.c
wildcard function application doesn't look right. Should probably be:
DEPSALL := $(patsubst %,%.d,$(basename $(wildcard $(TGTFILES)/*.c)))

Writing a makefile for ARM project

My project structure looks like:
.
├── build
├── src
| ├── rbpi
| | └── gpio.h
| ├── boot.c
| ├── boot.s
| └── kernel.c
└── linker.ld
This is a simple raspberry pi kernel that makes a LED blink!
I currently use a simple bat file with the following content to build it:
arm-none-eabi-gcc -g -O0 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -nostartfiles -Wl,-T,linker.ld src/kernel.c src/boot.c src/boot.s -o build/kernel.elf
arm-none-eabi-objcopy build/kernel.elf -O binary build/kernel7.img
Since I will add more files to this project, I would have to append every file to my "buildscript".
If possible, I'd like to use a makefile.
How should my makefile look like if I want the following "rules"?
Before compilation, clean all *.elf and *.img files from the build directory.
Compile all *.c and *.s files from the src directory.
Output the kernel.elf file into the build directory.
Use the linker script linker.ld.
After compilation, run objcopy to generate a binary file.
A typical Makefile may look like... Wait there's a documentation about GNU Make here with a nice simple Makefile:
http://www.gnu.org/software/make/manual/make.html#Simple-Makefile
So for you a simple one to start may be:
SRC := $(wildcard src/*.c src/*.s)
CFLAGS := -g -O0 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -nostartfiles -Wl,-T,linker.ld
all: build/kernel.img
build/kernel.elf: $(SRC)
arm-none-eabi-gcc $(CFLAGS) $(SRC) -o $#
%.img: %.elf
arm-none-eabi-objcopy $< -O binary $#
clean:
rm -f build/*.elf build/*.img
(Be carefull, recipes have to start with a tab, not four spaces like here, it's important for make to understand your file, so copying-pasting won't work.)
You don't actually need to remove elf and img files before compiling, that's the GNU Make role to know if it has to rebuild or not according to file modification times.
Here it is, working:
$ tree
.
├── build
├── Makefile
└── src
├── boot.c
├── boot.s
└── kernel.c
$ make
arm-none-eabi-gcc -g -O0 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -nostartfiles -Wl,-T,linker.ld src/boot.c src/kernel.c src/boot.s -o build/kernel.elf
arm-none-eabi-objcopy build/kernel.elf -O binary build/kernel.img
$ tree
.
├── build
│   ├── kernel.elf
│   └── kernel.img
├── Makefile
└── src
├── boot.c
├── boot.s
└── kernel.c
$ make
make: Nothing to be done for 'all'.
$ touch src/boot.c # If I touch a file, make will have to rebuild evrything:
$ make
arm-none-eabi-gcc -g -O0 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -nostartfiles -Wl,-T,linker.ld src/boot.c src/kernel.c src/boot.s -o build/kernel.elf
arm-none-eabi-objcopy build/kernel.elf -O binary build/kernel.img
You should really take a look at the documentation which is really nice: http://www.gnu.org/software/make/manual/make.html you won't be able to ask on stackoverflow for any modification you'll need to do on your makefile, starting from this "bootstrap makefile" you should be able to modify it to learn step by step, with the documentation as a reference.

Makefile - move object files

After a bit of searching, I've managed to throw together the following Makefile:
CC = gcc
CFLAGS = -c -Wall
LDFLAGS =
SOURCEFILES = main.c
SOURCES = src/$(SOURCEFILES)
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = netsim
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.c.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf netsim $(OBJECTS)
I would like to be able to move my object files into another directory, but have been struggling with getting that to work. What am I missing?
The trick is to not move your objects.
You should build it and use it from where they are built.
For example you have the following directory structure:
$ tree .
├── Makefile
├── include
│   └── common_head.h
├── obj
└── src
├── foo.c
└── main.c
Manual execution:
$ gcc -o ./obj/foo.o -c ./src/foo.c -I ./include # Build Object #
$ gcc -o ./obj/main.o -c ./src/main.c -I ./include
$ gcc -o exe ./obj/foo.o ./obj/main.o # Build Executable #
Makefile to simulate the above
C_FLAGS := -g -Wall -Wextra
CC := gcc
RM := rm
LINKFLAGS := -lanylibrary
.PHONY: $(TARGET)
.PHONY: clean
VPATH:= ./src/ ./obj/ ./include/
# Path for .c , .h and .o Files
SRC_PATH := ./src/
OBJ_PATH := ./obj/
INC_PATH := -I ./include
# Executable Name
TARGET := exe
# Files to compile
OBJ1 := foo.o \
main.o
OBJ := $(patsubst %,$(OBJ_PATH)%,$(OBJ1))
# Build .o first
$(OBJ_PATH)%.o: $(SRC_PATH)%.c
#echo [CC] $<
#$(CC) $(C_FLAGS) -o $# -c $< $(INC_PATH)
# Build final Binary
$(TARGET): $(OBJ)
#echo [INFO] Creating Binary Executable [$(TARGET)]
#$(CC) -o $# $^ $(LINKFLAGS)
# Clean all the object files and the binary
clean:
#echo "[Cleaning]"
#$(RM) -rfv $(OBJ_PATH)*
#$(RM) -rfv $(TARGET)
So when you do a Make
$ make -B
[CC] src/foo.c
[CC] src/main.c
[INFO] Creating Binary Executable [exe]
To see a dry-run use make -n
$ make clean ; make -n
g++ -g -Wall -Wextra -o obj/foo.o -c src/foo.c -I ./include
g++ -g -Wall -Wextra -o obj/main.o -c src/main.c -I ./include
g++ -o exe obj/foo.o obj/main.o -lanylibrary
So after building your directory structure should look like this.
$ tree .
├── Makefile
├── exe
├── include
│   └── common_head.h
├── obj
│   ├── foo.o
│   └── main.o
└── src
├── foo.c
└── main.c
So from my previous answer.
You don't have to use any PHONY move and also no objects are recreated unnecessarily.
Something like this?
SOURCES = src/main.c
OBJECTS = obj/main.o
...
obj/%.o: src/%.c
$(CC) $(CFLAGS) $< -o $#
Once that's working, you can add further tricks, like this:
OBJECTS = $(patsubst src/%.c, obj/%.o, $(SOURCES)

Resources