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)
Related
I have a simple project, whose folder structure is something like:
ls -R
.:
build include makefile src
./build:
./include:
myfunc.h
./src:
main.cpp myfunc.cpp
I want to compile the .cpp sources into .o object files, which should end into ./build folder. Using the GNUmake documentation and other sources (e.g. Proper method for wildcard targets in GNU Make), I wrote this makefile:
CXX := g++
CXXFLAGS += -I./include
CXXFLAGS += -Wall
OBJDIR := ./build
SRCDIR := ./src
PROGRAM = release
DEPS = myfunc.h
SRC = $(wildcard $(SRCDIR)/*.cpp)
OBJ = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(SRC))
all: $(PROGRAM)
$(PROGRAM): $(OBJ)
$(CXX) $(CXXFLAGS) -o $(PROGRAM) $(OBJ)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(CXX) $(CXXFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm $(PROGRAM) $(OBJ)
But I get the error message: make: *** No rule to make target 'build/main.o', needed by 'release'. Stop.. I tried a lot of different ways but I cannot manage to have my .o files end up in the ./build directory. Instead, everything works if I put them in the root directory of the project. I can also make it work by specifying a rule for each object file, but I'd like to avoid that. What am I missing?
(I am using GNUmake version 4.3)
The problem is here:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(CXX) $(CXXFLAGS) -c $< -o $#
See the $(DEPS)? That expands to myfunc.h. The compiler knows where to find that file (or would if this recipe were executed), because you've given it -I./include, but Make doesn't know where to find it (so it passes over this rule).
Add this line:
vpath %.h include
P.S. If you want to be really clean, you can add a variable:
INCDIR := ./include
CXXFLAGS += -I$(INCDIR)
vpath %.h $(INCDIR)
I am learning how to use make. Recently I wrote a makefile to compile one of my projects, which structure is: src (which contains file.cpp and main.cpp) and include (which contains file.h) folders and the makefile, which is written as follows:
TARGET_EXEC := main
CC := g++
BUILD_DIR := .
SRC_DIR := src
OBJ_DIR := obj
SRC := $(shell find $(SRC_DIR) -name '*.cpp')
OBJ := $(SRC:%=$(OBJ_DIR)/%.o)
DEPS := $(OBJ:.o=.d)
INC_DIR := $(shell find $(SRC_DIR) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIR))
CPPFLAGS := $(INC_FLAGS) -MMD -MP
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJ)
$(CC) $(OBJ) -o $# $(LDFLAGS)
$(OBJ_DIR)/%.cpp.o: %.cpp
# mkdir -p $(dir $#)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -r $(OBJ_DIR) main
-include $(DEPS)
Now I want to add a new folder (test) in which I'll host a tests.cpp code with doctest code. In this case I would like to obtain two executables: main and tests (not only main as before), one for the main and one for the testing. I tried everything, but I don't understand how to modify the previous makefile in order to implement the new test folder informations.
EDIT 1
I tried adding Andreas suggestions and also an all command to create both the executables:
TARGET_EXEC := main
TEST_EXEC := tests
CC := g++
BUILD_DIR := .
SRC_DIR := src
OBJ_DIR := obj
TEST_DIR := test
SRC := $(shell find $(SRC_DIR) -name '*.cpp')
OBJ := $(SRC:%=$(OBJ_DIR)/%.o)
DEPS := $(OBJ:.o=.d)
INC_DIR := $(shell find $(SRC_DIR) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIR))
CPPFLAGS := $(INC_FLAGS) -MMD -MP
all: $(BUILD_DIR)/$(TARGET_EXEC) $(BUILD_DIR)/$(TEST_EXEC)
$(BUILD_DIR)/$(TARGET_EXEC): $(SRC_DIR)/$(TARGET_EXEC).o $(OBJ)
$(CC) $(OBJ) -o $# $(LDFLAGS)
$(BUILD_DIR)/$(TEST_EXEC): $(TEST_DIR)/$(TEST_EXEC).o $(OBJ)
$(CC) $(OBJ) -o $# $(LDFLAGS)
$(OBJ_DIR)/%.cpp.o: %.cpp
# mkdir -p $(dir $#)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $#
.PHONY: clean all
clean:
rm -r $(OBJ_DIR) main
-include $(DEPS)
Now two executables main and tests are created, but they do the same things (same of the previous main), so it is wrong. When compile my output is:
g++ -Isrc -MMD -MP -c src/osmanip.cpp -o obj/src/osmanip.cpp.o
g++ -Isrc -MMD -MP -c src/main.cpp -o obj/src/main.cpp.o
g++ obj/src/osmanip.cpp.o obj/src/main.cpp.o -o main
g++ obj/src/osmanip.cpp.o obj/src/main.cpp.o -o tests
I think that the error may be in:
$(OBJ_DIR)/%.cpp.o: %.cpp
# mkdir -p $(dir $#)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $#
What do you think?
EDIT 2
Ok, I think that I found a solution:
TARGET_EXEC := main
TEST_EXEC := tests
CC := g++
BUILD_DIR := .
SRC_DIR := src
OBJ_DIR := obj
TEST_DIR := test
SRC := $(shell find $(SRC_DIR) -name '*.cpp')
TEST := $(shell find $(TEST_DIR) -name '*.cpp')
OBJ := $(SRC:%=$(OBJ_DIR)/%.o)
TEST_OBJ := $(TEST:%=$(OBJ_DIR)/%.o)
DEPS := $(OBJ:.o=.d)
INC_DIR := $(shell find $(SRC_DIR) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIR))
CPPFLAGS := $(INC_FLAGS) -MMD -MP
.PHONY: clean all
all: $(BUILD_DIR)/$(TARGET_EXEC) $(BUILD_DIR)/$(TEST_EXEC)
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJ)
$(CC) $(OBJ) -o $# $(LDFLAGS)
$(BUILD_DIR)/$(TEST_EXEC): $(TEST_OBJ)
$(CC) $(TEST_OBJ) -o $# $(LDFLAGS)
$(OBJ_DIR)/%.cpp.o: %.cpp
# mkdir -p $(dir $#)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $#
clean:
rm -r $(OBJ_DIR) main tests
-include $(DEPS)
With this makefile the compilation is good (I think), since the obj/src and obj/test folder are created. main executable is compiled correctly and works. Also tests executable is compiled (correclty I think), but I get another error, not related to makefile:
g++ -Isrc -MMD -MP -c src/osmanip.cpp -o obj/src/osmanip.cpp.o
g++ -Isrc -MMD -MP -c src/main.cpp -o obj/src/main.cpp.o
g++ obj/src/osmanip.cpp.o obj/src/main.cpp.o -o main
g++ -Isrc -MMD -MP -c test/tests.cpp -o obj/test/tests.cpp.o
g++ obj/test/tests.cpp.o -o tests
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:29: tests] Error 1
I think this is due to the fact that my test/tests.cpp file is
#define DOCTEST_CONFIG_IMPLEMENT
#include "doctest/doctest.h"
#include <string>
I didn't give it any command for the moment. I implemented doctest without main and in fact it tells me that main function is missing (because it is implemented into the src/main.cpp file). I tried looking at this answer, but I didn't solve this problem.
Do you know how to correctly compile the doctest test.cpp file? Thanks.
EDIT 3
Thanks to Jarod42 answer I solved also this very last issue related to doctest. Now all seems working perfectly.
Many thanks to sll you guys! It is my first post on Stack Overflow and I alrealy love this site.
Have tried humble beginnings? Here is where I would start and build on, key being to separate the main.o from OBJ so that tests can have its main from tests.o:
# Adding include directories (weird way of doing it but ok)
CPPFLAGS := $(addprefix -I,$(shell find src -type d))
# object files
OBJ := src/file1.o src/file2.o
# main
main: src/main.o $(OBJ)
# the test program
tests: test/tests.o $(OBJ)
(Notice this relies on built-in recipes, should work out-of-the-box.)
From there you can re-introduce the other concepts step by step:
Out-of-tree build.
Overrated (at least for GNU Make for which it's all manual).
Glob source files.
If you know what files you have, best not glob.
Dependency file generation and inclusion.
Keep folders and such in variables.
Currently, i have a pretty cool generic C++ makefile that can make only one binary from multiple source files and headers. It's all-sufficient. I would like to know how to modify it in order to generate 2 binaries. Only the mains.cpp would be different. The headers are the same too. The source files are the same. I think for sure it's possible and I'd even wonder if a loop trough exec and binaries (EXEC files) exists to generate more than 2 binaries (with same sources file). I
don't master enough the GNU makefile language to know that. Thx a lot. I just sure that i have to add a .all rule with my 2 binaries but nothing after.
Look at this :
# sources (*.cpp)
SRC := sources
# headers (*.cpp)
INC := include
MAIN := kwic_personnel.cpp
EXEC := kwic
# second binary here
MAIN2 := other.cpp
EXEC2 := other
# main file is in current directory or in sources file but here the main files are in out of
# sources file for sure
ifneq ("$(wildcard $(MAIN))","")
sources := $(MAIN) $(wildcard $(SRC)/*.cpp)
else
sources := $(wildcard $(SRC)/*.cpp)
endif
# obj files
objects := $(sources:.cpp=.o)
# dep files
deps := $(objects:.o=.d)
CXX := g++
CXXFLAGS := -I $(INC) -MMD -MP -g -std=c++17 -Wall -pedantic -Weffc++ -Werror
# OS name
UNAME := $(shell uname -s)
# NOT SURE ABOUT THAT FOR MAC OS
# if linux
ifeq ($(UNAME), Linux)
LDFLAGS := -L/usr/lib/x86_64-linux-gnu
LDLIBS := -lcurl
# else but mac OS
else
CXXFLAGS += -D OSX
LDFLAGS := -stdlib=libstdc++
endif
# linking
$(EXEC) : $(objects)
#echo "Generation du fichier executable..."
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(RM) $(objects) $(deps)
#echo "Compilation réussie !"
# compilation of cpp files
$(SRC)/%.o: $(SRC)/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $#
# remove exec
.PHONY: clean
clean:
$(RM) $(EXEC)
# dependencies
-include $(deps)
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.
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