Makefile doesn't understand g++ but terminal does - c++

Makefile
# Assignments
#########################################################
CC := g++
SRC := src
BUILD := build
INCLUDE := include
TARGET := bin/driver
LIB := lib
TESTS := tests
CFLAGS := -g -Wall -Wextra
PATH := -I $(INCLUDE)
#########################################################
driver: Logbook.o Entry.o main.o
g++ Logbook.o Entry.o main.o -o driver
main.o: main.cpp
g++ -c main.cpp
Logbook.o:
g++ -c $(PATH) $(LIB)/Logbook.cpp
Entry.o:
g++ -c $(PATH) $(LIB)/Entry.cpp
test:
g++ -c $(PATH) $(LIB)/Logbook.cpp
clean:
rm -f *.o *.exe driver
STDOUT
mint#mint-VirtualBox ~/Desktop/Logbook $ ls
googletest include lib main.cpp Makefile README.md src
mint#mint-VirtualBox ~/Desktop/Logbook $ make
g++ -c -I include lib/Logbook.cpp
make: g++: Command not found
Makefile:47: recipe for target 'Logbook.o' failed
make: *** [Logbook.o] Error 127
mint#mint-VirtualBox ~/Desktop/Logbook $ ls
googletest include lib main.cpp Makefile README.md src
mint#mint-VirtualBox ~/Desktop/Logbook $ g++ -c -I include lib/Logbook.cpp
mint#mint-VirtualBox ~/Desktop/Logbook $ ls
googletest include lib Logbook.o main.cpp Makefile README.md src
mint#mint-VirtualBox ~/Desktop/Logbook $
The result expected is that g++ works while being called from inside the makefile but clearly doesn't
What exactly is going on here? there are tabs where there should be and running the compilation command while in the terminal works but the Makefile just doesn't want to agree that the g++ command exists.

Don't call the variable PATH, it overrides the default environment variable that tells the Makefile where to look for binaries. Just rename it to CCFLAGS or so.
CCFLAGS := -I $(INCLUDE)
Logbook.o:
g++ -c $(CCFLAGS) $(LIB)/Logbook.cpp
More details on PATH e.g. here: https://en.wikipedia.org/wiki/PATH_(variable)

Related

Makefile: create a build directory

I have a C++ project with the source files spanning many directories, and with interdependencies in the headers (the headers of one directory include headers from other directory source).
I have a makefile looking like this :
CXX = g++
CFLAGS = -Wall -std=c++17
SRC = *.cpp ./num_utils/*.cpp ./shapes/*.cpp ./data_utils/*.cpp
all: $(SRC)
$(CXX) $(CFLAGS) $(SRC) -o main $(LDFLAGS)
I want to create a build directory where .o files get output, and modify the makefile so that I do not recompile every single file with every call to make
I get confused reading the docs, please help or point me to a beginner-friendly tutorial
This makefile is probably only dedicated to gnu-make (because of
the wildcard, patsubst, dir builtin commands and ifeq) in a unix environment (because of mkdir -p, rm -rf).
It recreates below the build directory the same directory hierarchy as the source files.
According to further questions in the comments, the ability to
choose between a debug build (opt=0 by default) and a release build
(opt=1 on the command line) has been added.
opt=0
CXX=g++
CFLAGS=-Wall -std=c++17
SRC=${wildcard *.cpp ./num_utils/*.cpp ./shapes/*.cpp ./data_utils/*.cpp}
OBJ=${patsubst %.cpp,build/%.o,${SRC}}
ifeq (${opt},0)
CFLAGS+=-g
else
CFLAGS+=-O3
endif
all: ${OBJ}
${CXX} ${CFLAGS} ${OBJ} -o main ${LDFLAGS}
build/%.o : %.cpp
mkdir -p ${dir $#}
${CXX} -o $# $< -c ${CFLAGS}
clean :
rm -rf main build
$ make clean
rm -rf main build
$ tree
.
├── data_utils
│   ├── f3.cpp
│   └── f33.cpp
├── main.cpp
├── makefile
├── num_utils
│   ├── f1.cpp
│   └── f11.cpp
└── shapes
├── f2.cpp
└── f22.cpp
3 directories, 8 files
$ make
mkdir -p build/
g++ -o build/main.o main.cpp -c -Wall -std=c++17 -g
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f1.o num_utils/f1.cpp -c -Wall -std=c++17 -g
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f11.o num_utils/f11.cpp -c -Wall -std=c++17 -g
mkdir -p build/./shapes/
g++ -o build/./shapes/f2.o shapes/f2.cpp -c -Wall -std=c++17 -g
mkdir -p build/./shapes/
g++ -o build/./shapes/f22.o shapes/f22.cpp -c -Wall -std=c++17 -g
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f3.o data_utils/f3.cpp -c -Wall -std=c++17 -g
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f33.o data_utils/f33.cpp -c -Wall -std=c++17 -g
g++ -g build/main.o build/./num_utils/f1.o build/./num_utils/f11.o build/./shapes/f2.o build/./shapes/f22.o build/./data_utils/f3.o build/./data_utils/f33.o -o main
$ make clean
rm -rf main build
$ make opt=1
mkdir -p build/
g++ -o build/main.o main.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f1.o num_utils/f1.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f11.o num_utils/f11.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./shapes/
g++ -o build/./shapes/f2.o shapes/f2.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./shapes/
g++ -o build/./shapes/f22.o shapes/f22.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f3.o data_utils/f3.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f33.o data_utils/f33.cpp -c -Wall -std=c++17 -O3
g++ -Wall -std=c++17 -O3 build/main.o build/./num_utils/f1.o build/./num_utils/f11.o build/./shapes/f2.o build/./shapes/f22.o build/./data_utils/f3.o build/./data_utils/f33.o -o main
$ ./main
in main()
in f1()
in f2()
in f3()
in f11()
in f22()
in f33()
$ make --version
GNU Make 4.3
Built for x86_64-pc-linux-gnu
...
I would start with a template like this, where a list of object files is dynamically created from the C++ source files using wildcard and patsubt. You can then use a pattern rule to build the object files automatically. Specify a dependency for default make command to check if any in $(OBJS) needs building to avoid rebuilds:
OBJ=obj/
SRC=src/
INCLUDE=include/
OBJS=$(patsubst %.cpp, %.o, $(wildcard $(SRC)*.cpp))
$(OBJ)%.o : $(SRC)%.cpp
g++ -c $(INCLUDE) $< -o $#
all: $(OBJS)
g++ main.cpp -o main

Why is my makefile not generating object files?

Here is my makefile:
LIBS = libxml2.so.2.9.4
LDFLAGS = -lstdc++ -lpthread -lxml2
vpath %.hpp ./
vpath %.cpp ./
vpath %.h ./libxml2/include/libxml
all: KeyGenerator
KeyGenerator: main.o ProjectXmlParser.o xmlparser.o
g++ ${CXXFLAGS} ${LDFLAGS} -o KeyGenerator $+ ${LIBS}
main.o: main.cpp
ProjectXmlParser.o: ProjectXmlParser.cpp ProjectXmlParser.hpp
xmlparser.o: xmlparser.cpp xmlparser.hpp global.hpp
phony: clean
clean:
rm -f *.o
The output:
/usr/bin/make -f Makefile CONF=Debug
g++ -g -Wall -std=gnu++11 -pthread -I./ -I./src -I./libxml2/include -lstdc++ -lpthread -lxml2 -o KeyGenerator main.o ProjectXmlParser.o xmlparser.o libxml2.so.2.9.4
g++: error: ProjectXmlParser.o: No such file or directory
g++: error: xmlparser.o: No such file or directory
Makefile:12: recipe for target 'KeyGenerator' failed
make: *** [KeyGenerator] Error 1
In the project directory all of my hpp and cpp files exist at the same level. I do have one additional project called libxml that I am using. When I do a build main.o is created but none of the .o files are created. I've seen other posts pose this question but so far nothing has worked for me.
Thank you.
Based on the make -d output:
Must remake target 'ProjectXmlParser.o'.
Successfully remade target file 'ProjectXmlParser.o'.
it seems that make thinks you have an empty recipe to build this target. Maybe you have some stray TAB characters in your makefile after the ProjectxXmlParser.o and xmlparser.o rules, that aren't shown in the makefile you pasted into this question?

How to compile tensorflow c_api using Makefile in linux

I'm trying to compile tensorflow c_api using Makefile. I need help to add the tensorflow libraries in the makefile. I'm running it on Ubuntu.
Here I have attached the folder structure of the project,
folder structure
I have also added the Makefile below.
CC = g++
CFLAGS = -c -Wall
INCLUDES = -I "tensorflow/c"
LIBS =-L "lib" -ltensorflow -ltensorflow_framework
all : exec
exec : simple.o
$(CC) -o exec simple.o $(INCLUDES) $(LIBS)
.cpp.o:
$(CC) $(CFLAGS) $<
clean:
rm -rf *.
The program compiles without error,
g++ -c -Wall simple.cpp
g++ -o exec simple.o -I "tensorflow/c" -L "lib" -ltensorflow -ltensorflow_framework
but when i run the exec I get the following error,
./exec: error while loading shared libraries: libtensorflow.so.1: cannot open shared object file: No such file or directory
You have to make sure that lib is on LD_LIBRARY_PATH.
export LD_LIBRARY_PATH=`pwd`/lib:${LD_LIBRARY_PATH}
./exec

Makefile for many c++ executables

I am working on a project where I constantly need to create new c++ executables. They all rely on some common headers and sources files, so I am wondering how to simplify the compilation and Makefile writing.
The best I have come up with so far is something like this:
file1: $(BUILDDIR)/$#.o $(COMMON_OBJECTS) $(COMMON_LIBS)
$(CCCOM) $(CCFLAGS) $(BUILDDIR)/$#.o $(COMMON_OBJECTS) -o $(BINDIR)/$# $(LIBFLAGS)
and then I have to copy this target for each executable I want to add. Ideally I want to define this rule once for arbitrary target and then simply call make any_file_name.
Is something like that possible?
How do people organize c++ project with lots of executables? (I am new to c++ and coming from python that is a very natural thing)
You could make it so that each executable corresponds to a single .cpp file in a directory (e.g. executables/foo.cpp, executables/bar.bpp), and then work from there -- this will save you from having to touch the Makefile every time you add another one.
You should, probably, also set up your project to create a shared library, which the (light-weight) executables link to. (The executables effectively just doing some command-line parsing, and offloading the actual work to library functions.) This way, you will not end up with the code from those $(COMMON_OBJECTS) being replicated in every executable.
To simplify everything I'm assuming you have sources file1.cpp, file2.cpp and so on, and all your files reside in the same directory. Then Makefile fragment below will do what you want:
all: $(basename $(wildcard file?.cpp))
file%: file%.cpp
To make everyhing:
make all
To make file1:
make file1
To make file1 and file2:
make file1 file2
Here is an example makefile with automatic header dependency generation for you:
BUILD := debug
BUILD_DIR := ${BUILD}
CXX := g++
cppflags.debug :=
cppflags.release := -DNDEBUG
cppflags := ${cppflags.${BUILD}} ${CPPFLAGS}
cxxflags.debug :=
cxxflags.release := -O3
cxxflags := ${cxxflags.${BUILD}} ${CXXFLAGS}
ldflags := ${LDFLAGS}
ldlibs := ${LDLIBS}
exes := # Executables to build.
### Define executables begin.
exes += exe1
exe1.obj := exe1.o
exes += exe2
exe2.obj := exe2.o
### Define executables end.
all : ${exes:%=${BUILD_DIR}/%}
.SECONDEXPANSION:
${BUILD_DIR}:
mkdir -p $#
# Rule to link all exes.
${exes:%=${BUILD_DIR}/%} : ${BUILD_DIR}/% : $$(addprefix ${BUILD_DIR}/,$${$$*.obj}) | $${#D}
${CXX} -o $# ${ldflags} $^ ${ldlibs}
# Rule to compile C sources. And generate header dependencies.
${BUILD_DIR}/%.o : %.cc | $${#D}
${CXX} -o $# -c ${cppflags} ${cxxflags} -MD -MP $<
# Include automatically generated header dependencies.
ifneq ($(MAKECMDGOALS),clean)
-include $(foreach exe,${exes},$(patsubst %.o,${BUILD_DIR}/%.d,${${exe}.obj}))
endif
clean:
rm -rf $(BUILD_DIR)
.PHONY: all clean
Usage example:
$ cat exe1.cc
#include <iostream>
int main() { std::cout << "Hello, world!\n"; }
$ cat exe2.cc
#include <iostream>
int main() { std::cout << "Hello, world!\n"; }
$ make
mkdir -p debug
g++ -o debug/exe1.o -c -MD -MP exe1.cc
g++ -o debug/exe1 debug/exe1.o
g++ -o debug/exe2.o -c -MD -MP exe2.cc
g++ -o debug/exe2 debug/exe2.o
$ make BUILD=release
mkdir -p release
g++ -o release/exe1.o -c -DNDEBUG -O3 -MD -MP exe1.cc
g++ -o release/exe1 release/exe1.o
g++ -o release/exe2.o -c -DNDEBUG -O3 -MD -MP exe2.cc
g++ -o release/exe2 release/exe2.o
$ make clean
rm -rf debug
$ make BUILD=release clean
rm -rf release

How to do makefile to compile multiple .cpp files in different directories using a single makefile?

I have the following files in my proj2 directories and need to compile them together to have one executable file.
proj2/main.cpp
proj2/model/Player.cpp
proj2/model/gameBoard.cpp
proj2/controller/TTTController.cpp
proj2/Makefile
I'm using the following command inside my makefile, but it is not working.
all:
g++ /project2_p1/main.cpp /project2_p1/controller/TTTController.cpp /model/gameBoard.cpp /model/Player.cpp -o ttt
clean:
-rm ttt
Can anybody help me please.Thank you
I strongly recommend you start learning make as it is one of the fundamental tools that programmers use. And, if you can learn C++, you can definitely learn make.
In your project you have source files buried in their own subdirectories so in order to find them all you can use the $(shell find...) command. Same with any header files in your project.
By making all: the direct target it gets executed unconditionally and you lose the benefits of using make - only compile when you change something.
Having said that the basic template I am providing here could be improved to recompile only those source files that have changed but that's an exercise for the reader.
I think this should work in your case:
# set non-optional compiler flags here
CXXFLAGS += -std=c++11 -Wall -Wextra -pedantic-errors
# set non-optional preprocessor flags here
# eg. project specific include directories
CPPFLAGS +=
# find cpp files in subdirectories
SOURCES := $(shell find . -name '*.cpp')
# find headers
HEADERS := $(shell find . -name '*.h')
OUTPUT := ttt
# Everything depends on the output
all: $(OUTPUT)
# The output depends on sources and headers
$(OUTPUT): $(SOURCES) $(HEADERS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(OUTPUT) $(SOURCES)
clean:
$(RM) $(OUTPUT)
thats my minGW project's makefile codes:
hepsi: derle calistir
Nesneler := ./lib/Hata.o ./lib/Hatalar.o ./lib/Dugum.o ./lib/ListeGezici.o ./lib/BagilListe.o
derle:
g++ -I ./include/ -o ./lib/Hata.o -c ./src/Hata.cpp
g++ -I ./include/ -o ./lib/Hatalar.o -c ./src/Hatalar.cpp
g++ -I ./include/ -o ./lib/Dugum.o -c ./src/Dugum.cpp
g++ -I ./include/ -o ./lib/ListeGezici.o -c ./src/ListeGezici.cpp
g++ -I ./include/ -o ./lib/BagilListe.o -c ./src/BagilListe.cpp
g++ -I ./include/ -o ./bin/test $(Nesneler) ./src/test.cpp
calistir:
./bin/test
In your project I think this will work;
all: compile run
Objects := ./lib/Player.o ./lib/gameBoard.o ./lib/TTTController.o
compile:
g++ -I ./include/ -o ./lib/Player.o -c ./model/Player.cpp
g++ -I ./include/ -o ./lib/gameBoard.o -c ./model/gameBoard.cpp
g++ -I ./include/ -o ./lib/TTTController.o -c .controller/TTTController.cpp
g++ -I ./include/ -o ./bin/main $(Objects) ./main.cpp
run:
./bin/main
lib folder contains .o files. You can chance it if you want.
include folder refers your header .h or .hpp files. You can change every one of them according to your headers location.
bin folder contains your .exe file called main.exe. You can change or remove it like that
run:
./main
I hope it'll work.
#Galik has right. if you want to learn C++, you should definitely learn make.