Adding INCLUDE, LIB and LD_LIBRARY_PATH in Makefile - c++

I am writing a new Makefile and would like to copy my object files in obj/ folder. I tried to add OBJ directory folder but it is not picking up. I am sure I am missing something. For now I moved .o files from src/ folder to obj/ folder after compilation.
Could you please let me know how to add INCLUDES and LIB_INCLUDES in this makefile. As include path is not there in Makefile it is expecting me to specify complete (relative) path in source code while including header file.
Also, I would like to include some external libraries (LD_LIBRARY_PATH) statically in my executable, so how can I specify those in Makefile:
APPNAME := MyApp.x
SOURCE_DIR := ./src
INCLUDE_DIR := ./include
OBJECT_DIR := ./obj
BIN_DIR := ./bin
CC := g++
CCFLAGS := -g -Wall
SRCFILES := $(wildcard $(SOURCE_DIR)/*.cpp)
INCLUDES := $(INCLUDE_DIR)
LIB_INCLUDES := $(INCLUDE_DIR)
OBJECTS := $(patsubst %.cpp, %.o, $(SRCFILES))
all: $(APPNAME)
$(APPNAME): $(OBJECTS)
$(CC) $(CCFLAGS) $(LDFLAGS) -o $(BIN_DIR)/$(APPNAME) $(OBJECTS) $(LDLIBS)
\mv -f $(SOURCE_DIR)/*.o obj
depend: .depend
.depend: $(SRCFILES)
rm -f ./.depend
$(CC) -I$(INCLUDES) $(CCFLAGS) $^>>./.depend;
clean:
rm -f $(OBJECTS)
dist-clean: clean
rm -f *~ .depend
include .depend
Created separate thread for this request - lubgr.

Try this (for the sake of brevity, I stripped off the .depend part and both clean targets):
APPNAME := MyApp.x
SOURCE_DIR := src
INCLUDE_DIR := include
OBJECT_DIR := obj
BIN_DIR := bin
CC := g++
CCFLAGS := -g -Wall
SRCFILES := $(wildcard $(SOURCE_DIR)/*.cpp)
INCLUDES := $(INCLUDE_DIR)
OBJECTS := $(SRCFILES:$(SOURCE_DIR)/%.cpp=$(OBJECT_DIR)/%.o)
all: $(BIN_DIR)/$(APPNAME)
$(BIN_DIR)/$(APPNAME): $(OBJECTS)
$(CC) $(CCFLAGS) -o $# $(OBJECTS)
$(OBJECT_DIR)/%.o: $(SOURCE_DIR)/%.cpp
$(CC) $(CCFLAGS) -I$(INCLUDES) -o $# -c $<
For further static libraries, you pass them to the linker just like object files, e.g.
STATIC_LIBS = lib/libfirst.a lib/libsecond.a
$(BIN_DIR)/$(APPNAME): $(OBJECTS)
$(CC) $(CCFLAGS) -o $# $(OBJECTS) $(STATIC_LIBS)
This differs when it comes to linking against shared libraries, but as you said your libs are all compiled into static ones, this should work.

Related

Why GCC can not find the header files in includes folder?

I am trying to include glad.h in my main.cpp using #include <glad/glad.h> using this makefile ~
CC := g++
CFLAGS := -std=c++17 -Wall -Wextra -g
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
LIBRARIES := -lglad -lglfw3dll
ifeq ($(OS),Windows_NT)
EXECUTABLE := main.exe
SOURCEDIRS := $(SRC)
INCLUDEDIRS := $(INCLUDE)
LIBDIRS := $(LIB)
else
EXECUTABLE := main
SOURCEDIRS := $(shell find $(SRC) -type d)
INCLUDEDIRS := $(shell find $(INCLUDE) -type d)
LIBDIRS := $(shell find $(LIB) -type d)
endif
CINCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%))
CLIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%))
SOURCES := $(wildcard $(patsubst %,%/*.cpp, $(SOURCEDIRS)))
OBJECTS := $(SOURCES:.cpp=.o)
all: $(BIN)/$(EXECUTABLE)
.PHONY: clean
clean:
-$(RM) $(BIN)/$(EXECUTABLE)
-$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(CINCLUDES) $(CLIBS) $^ -o $# $(LIBRARIES)
but everytime i get this error...
g++ -c -o src/main.o src/main.cpp
src/main.cpp:1:10: fatal error: glad/glad.h: No such file or directory
#include <glad/glad.h>
^~~~~~~~~~~~~
compilation terminated.
mingw32-make: *** [<builtin>: src/main.o] Error 1
every header file is present in the include folder still it is not working.
please help...
how to fix this
if there any other type of errors in make file please point it out...
Thanks.
The problem is that makeis invoking a built-in rule to compile your source files to object files but that rule knows nothing about your CINCLUDES or other variables. From the documentation...
Compiling C++ programs
n.o is made automatically from n.cc, n.cpp, or n.C with a recipe of
the form ‘$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c’.
The simplest solution would be to add $(CINCLUDES) to $(CPPFLAGS)
CPPFLAGS += $(CINCLUDES)

Preprocessor macro definition via a Makefile does not work properly in c++

For my c++ code I need a custom processor macro that will be defined during compilation. According to what I have read I concluded in the following Makefile:
CC := g++
# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin
# Targets
EXECUTABLE := app
TARGET := $(TARGETDIR)/$(EXECUTABLE)
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -Dcustom_macro -g -c -Wall -std=c++14
INC := -I include
$(TARGET): $(OBJECTS)
#echo " Linking..."
$(CC) $^ -o $(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
$(CC) $(CFLAGS) $(INC) -c -o $# $<
clean:
#echo " Cleaning...";
$(RM) -r $(BUILDDIR) $(TARGET)
The build is successful but when I run my app the code inside #ifdef custom_macro #endif is not executed but only when I change it to #ifndef .
I also tried to set -Dcustom_macro=1 but I had the same behavior.
I also tried to insert this with the CPPFLAGS macro as following :
CC := g++
# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin
# Targets
EXECUTABLE := app
TARGET := $(TARGETDIR)/$(EXECUTABLE)
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g -c -Wall -std=c++14
CPPFLAGS := -Dcustom_macro
INC := -I include
$(TARGET): $(OBJECTS)
#echo " Linking..."
$(CC) $^ -o $(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
$(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c -o $# $<
clean:
#echo " Cleaning...";
$(RM) -r $(BUILDDIR) $(TARGET)
But nothing changed. The parameters that are passed to make according to compiler are:
The parameteres that are passed to make are the following:
g++ -Dcustom_macro -g -c -Wall -std=c++14 -I include -c -o build/main.o src/main.cpp
Does anyone has any idea what I'm doing wrong?
Seems like you missed a space before macro name
CPPFLAGS := -D custom_macro

Modify the makefile to include subdirectories

I'm working with a small program in c++ to learn the makefile.
The program has 2 source files (main.cpp and classf.cpp) and one header file (classf.h). All files are included in the project directory which is called "testmake". This is the generated makefile by eclipse on windlows:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJS = main.o classf.o
LIBS =
TARGET = createPddl.exe
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
I would like to modify the makefile to accept new sub-directories, e.g, when I add a folder called "testmake/src" and move the file main.cpp inside it, folder called "testmake/csource" and move the classf.cpp inside it, and create a folder called "testmake/cheader" and move the classf.h inside it.
This makefile was genereated automatically by eclipse, and does not accept any changes. There for i have created manually a make file which is working with any c++ project that has a structure as tree.
I actually use this Makefile in general
CC := g++ # This is the main compiler
SRCDIR := src
BUILDDIR := build
TARGETDIR :=bin/
TARGET := pddlcrate
DATADIR := data
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g # -Wall
#LIB := -pthread -lmongoclient -L lib -lboost_thread-mt -lboost_filesystem-
mt -lboost_system-mt
INC := -I include
$(TARGET): $(OBJECTS)
#echo " Linking..."
#echo " $(CC) $^ -o $(TARGETDIR)$(TARGET) $(LIB)"; $(CC) $^ -o
$(TARGETDIR)$(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
#echo " $(CC) $(CFLAGS) $(INC) -c -o $# $<"; $(CC) $(CFLAGS) $(INC) -c - o $# $<
clean:
#echo " Cleaning...";
#echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)
for any c++ project with this tree structure
$ tree .
├── Makefile
├── bin
>exefile
├── include
> *.h files
├── obj
> *.o files
├── src
>*.cpp

Makefile always recompiles

i am having a hard time with the Makefile below. It always recompiles because it is looking for the objects in "source/" instead of "objects/".
Since i did not write that Makefile and don't know what all those options mean i can't figure out how to tell it to look for the objects in the correct folder.
TITLE =example_title
SRC_DIR = source/
OBJ_DIR = objects/
OUTDIR = build/
SRC := $(wildcard **/*.cpp)
OBJ := $(patsubst source/%.cpp,%.o,$(SRC))
FP_OBJ := $(patsubst %,objects/%,$(OBJ))
LIB = $(wildcard *.a) $(wildcard **/*.a)
CC =g++
LD =g++
CC_FLAGS = -m32 -c -Wall -g -o
EXECUTABLE = $(TITLE)
LD_FLAGS = -m32 -L/usr/lib32 -o $(OUTDIR)$(EXECUTABLE)
$(OUTDIR)$(EXECUTABLE) : $(OBJ)
$(LD) $(LD_FLAGS) $(FP_OBJ) $(LIB)
$(OBJ) : $(SRC)
$(CC) $(CC_FLAGS)$(OBJ_DIR)$# $(SRC_DIR)$*.cpp
$(TITLE).tar.gz : **/*.h **/*.cpp Makefile **/*.txt
tar -czf $# Makefile **/*.h **/*.cpp **/*.txt
dist: $(TITLE).tar.gz
all : $(OUTDIR)$(EXECUTABLE)
clean :
rm -f $(OBJ_DIR)*.o
rm -f $(OUTDIR)$(EXECUTABLE) $(TITLE).tar.gz
This should do it:
$(OUTDIR)$(EXECUTABLE) : $(FP_OBJ)
$(LD) $(LD_FLAGS) $^ $(LIB)
$(FP_OBJ) : $(OBJ_DIR)%.o : $(SRC_DIR)%.cpp
$(CC) $(CC_FLAGS) $# $<
The basic problem was here:
$(OBJ) : $(SRC)
$(CC) $(CC_FLAGS)$(OBJ_DIR)$# $(SRC_DIR)$*.cpp
Apart from the fact that $(OBJ) : $(SRC) makes each object depend on all sources, this rule promises foo.o and delivers objects/foo.o. So every time through, Make saw that there was no foo.o, and duly tried to rebuild it and the executable that required it.
There are other problems with this makefile, like the sloppy wildcards and the obnoxious practice of including slashes in the directory names, but they're not so serious.

How do I ensure my makefile detects changes in my header and cpp files?

Currently, whenever I do make my makefile tells me
make: `some/obj/file.o' is up to date.
regardless of whether I've edited any of the files involved in generating that object file. How do I make it detect changes? Here is a simple makefile that reproduces the problem:
SHELL := /bin/bash
src := src
sources := $(shell find $(srcDir) -name "*.cpp")
objects := $(sources:%.cpp=%.o)
-include $(sources:%.cpp=%.d)
all: prog
prog: $(objects)
g++ $(objects) -o /a.out
%.o: %.cpp
$(CXX) $(CXXFLAGS) -MMD -MP -c $< -I $(srcDir) -o $#
clean:
find $(srcDir) -type f -iname "*.o" -delete
find $(srcDir) -type f -iname "*.d" -delete
currently I have to run make clean everytime to get it to recompile, which obviously isn't ideal!
EDIT: Here is my attempt based on Chnossos's answer:
EXE := a.out
SRCDIR := src
SRC := $(shell find $(srcDir) -name "*.cpp")
DIR := .obj
OBJ := $(SRC:%.cpp=$(DIR)/%.o)
DEP := $(OBJ:.o=.d)
CXXFLAGS += -std=c++11
CXXFLAGS += -I /home/arman/lib/eigen-eigen-6b38706d90a9
CXXFLAGS += -I /home/arman/lib/boost_1_55_0
CXXFLAGS += -I /home/arman/lib/lodepng/
CXXFLAGS += -L /home/arman/lib/boost_1_55_0/stage/lib
CPPFLAGS += -MMD -MP
.PHONY: all clean
-include $(DEP)
all: $(EXE)
$(EXE): $(OBJ)
$(CXX) $(OBJ) -o $#
$(DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $< -I $(SRCDIR)
clean:
$(RM) -f $(DIR)
I am now getting the following error:
src/core/file1.cpp:839:1: fatal error: opening dependency file .obj/./src/core/file1.d: No such file or directory
Note that I have the following directory structure:
/prog/makefile -> The makefile
/prog/dir1/ -> some cpp/hpp files
/prog/dir2/ -> more cpp/hpp files
/prog/ ->there are some cpp/hpp files here too
I have many folders (more than just dir1 and dir2) so I'd like to not have to specify them each time.
EXE := a.out
SRC := $(wildcard *.cpp)
OBJ := $(SRC:.cpp=.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS := -MMD -MP -I.
.PHONY: all clean
all: $(EXE)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
clean:
$(RM) $(OBJ) $(DEP)
-include $(DEP)
You can also with a little efforts compile your .o and .d files into a hidden folder like this :
EXE := a.out
SRC := $(wildcard *.cpp)
DIR := .obj
OBJ := $(SRC:%.cpp=$(DIR)/%.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS := -MMD -MP -I.
.PHONY: all clean
all: $(EXE)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(DIR)/%.o: %.cpp | $(DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
$(DIR):
#mkdir $#
clean:
$(RM) -r $(DIR)
-include $(DEP)
EDIT: Here is my attempt for your edit :
Some quick note, the $(LDLIBS) is here for your -l flags, whereas $(LDFLAGS) is meant for -L flags.
SRCDIR := src
OBJDIR := .obj
EXE := a.out
SRC := $(shell find $(SRCDIR) -name "*.cpp")
OBJ := $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS := -MMD -MP
CPPFLAGS += -I$(SRCDIR)
CPPFLAGS += -I$(HOME)/lib/eigen-eigen-6b38706d90a9
CPPFLAGS += -I$(HOME)/lib/boost_1_55_0
CPPFLAGS += -I$(HOME)/lib/lodepng/
CXXFLAGS := -std=c++11
LDFLAGS += -L$(HOME)/lib/boost_1_55_0/stage/lib
LDLIBS :=
.PHONY: all clean
all: $(EXE)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(#D)/
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
%/:
mkdir -p $#
clean:
$(RM) -r $(OBJDIR)
-include $(DEP)
Tell me if something is missing.
-M family of gcc options (-MM, -MMT) generate the makefile fragments you need. A standard technique is
DEPS := $(SOURCES:.c=.d)
.c.d:
$(CC) -o $< -MM $(CFLAGS)
-include $(DEPS)