I'm on kubuntu using g++ 7.5.0 / GNU make for C++. My file structure:
bin
| .o files
header
|archiver.h
source
|main.cpp
|archiver.cpp
makefile
I want my source files to be able to detect header files without having to do #include "../header/archiver.h". I've tried using:
g++ -I/header
but this does not work. I get the error:
g++: fatal error: no input files.
makefile that was requested
CC = g++
CFLAGS = -c -Wall
objects = bin/main.o bin/archiver.o
all : $(objects)
$(CC) -o build $(objects)
bin/%.o : source/%.cpp
$(CC) $(CFLAGS) $?
mv *.o bin
.PHONY : clean
clean :
rm -rf all $(objects)
The command
g++ -I<header-dir>
doesn't change any default settings for the g++ include search paths with subsequent calls, as you seem to assume.
You'll need to pass that compiler flag for each individual c++ call, which are issued by make according the rules defined in your makefile.
The latter is what you need to adapt, best using a pre-defined makefile variable like CXXFLAGS or CXXINCLUDES (check the GNU-make documentation for details).
For your specific case
CFLAGS = -c -Wall -I./header
should work.
Related
I created the following makefile:
#COMPILER
CC=gcc
CFLAGS=-I./include/ -L. -Wl,-rpath=. -Wall
CORFLAGS=-I./include/ -c -ansi -pedantic-errors -Wall -Wextra -g
COFLAGS=-I./include/ -Wall -Werror -fpic -c
CSOFLAGS=-shared
#vpath
vpath %.h ./include/
vpath %.c ./test/
vpath %.c ./source/
vpath %.o ./obj/
#PATH
SOURCE=./source/
OUT=-o ./obj/$#
TEST=./test/
OBJPATH=./obj/
#LISTS
CFILESWP=$(wildcard ./source/*.c)
TFILESWP=$(wildcard ./test/*.c)
CFILES=$(notdir $(CFILESWP))
TFILES=$(notdir $(TFILESWP))
TOFILES=$(TFILES:.c=.o)
OFILES=$(CFILES:.c=.o)
OFILESWP=$(addprefix ./obj/,$(OFILES))
NAMES=$(TOFILES:_test.o=)
HFILES=$(CFILES:.c=.h)
.PHONY: clean debug release all
debug: CSOFLAGS+=-g
debug: libds.so
release: CSOFLAGS+=-O2
release: libds.so
test: $(NAMES)
all: libds.so $(NAMES)
%: %_test.c libds.so
$(CC) $(CFLAGS) -o $# $< -lds -g
#SHARED LIBRARY
libds.so: $(OFILES)
$(CC) $(CSOFLAGS) -o libds.so $(OFILES)
#OBJFILES
%.o: %.c %.h
$(CC) $(COFLAGS) -o $# $< -g
#CLEAN
clean:
rm -f *.o $(OBJPATH)*.o
rm -f $(NAMES) libds.so
My make file creates a shared library which called libds.so on make command and creates compiled executables on make test command.
it takes source files called TARGET.c from /source/ directory a.k.a stack.c, queue.c, cbuffer.c and compiles them togeher with their test files from /test/ directory aka stack_test.c, queue_test.c, TARGET_NAME_test.c.
All the .h files are located in the /include/ directory.
and there is also a /obj directory which should contains all the object files which created after running the makefile.
How can I make this makefile better?
How can I move all .o files to /obj directory after each run of make?
Is it possible to create each "project" without the need to compile ALL the targets?
I mean, can I write make, which will create the shared library, and then write create stack and it'll create only executable of stack which compiles /source/stack.c, test/stack_test, include/stack.h and all other associated .h files which appear to be inside the code of the source files.
Can I somehow force the makefile to run and compile only the projects that can be compiled and not to stop the "making", the compilation of the files just because several projets that have syntax errors inside of them or some other errors?
For example:
If I have the following projects: stack.c, queue.c, cbuffer.c
and cbuffer cannot be compiled because something is wrong with its code.
I want to be able to run make and make test and compile the other projects that can be compiled like stack and queue and just show me the compilation error of cbuffer but not to stop the make process.
Thanks.
i have make file which i try to make them generic
but it keeps to compline it missing include directory
this is the makefile :
CXX=g++
CPPFAGS= -Wall -O0 -g -std=c++14
INCLUDES = -I/home/vagrant/libuv/include -Isrc
LIBS_DIRS = -L/home/vagrant/libuv/build
LDFLAGS= -lssl -lcrypto
LIB_STATIC = -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
SOURCE = $(wildcard echo.cpp) \
$(wildcard src/*.cpp)
OBJ = $(SOURCE:.cpp=.o)
DEP = $(OBJ:.o=.d)
TARGET = myproj
$(TARGET) : $(OBJ)
$(CXX) $(CPPFLAGS) $(INCLUDES) -o $# $^ $(LIBS_DIRS) $(LDFLAGS) $(LIB_STATIC)
all: $(TARGET)
clean:
rm -f $(OBJ) $(TARGET)
cleandep:
rm -f $(DEP)
.PHONY:all clean cleandep
when i make : make -n :
make -n
g++ -c -o echo.o echo.cpp
g++ -c -o src/base64.o src/base64.cpp
g++ -c -o src/Server.o src/Server.cpp
g++ -c -o src/sha1.o src/sha1.cpp
g++ -c -o src/Client.o src/Client.cpp
g++ -I/home/vagrant/libuv/include -Isrc -o myproj echo.o src/base64.o src/Server.o src/sha1.o src/Client.o -L/home/vagrant/libuv/build -lssl -lcrypto -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
when i invoke make , im getting this error:
make
g++ -c -o echo.o echo.cpp
In file included from src/Server.h:9:0,
from echo.cpp:1:
src/Client.h:6:10: fatal error: uv.h: No such file or directory
#include <uv.h>
^~~~~~
compilation terminated.
make: *** [echo.o] Error 1
but the uv do exist in : /home/vagrant/libuv/include
You have no rule to build your object files: you've only defined a rule to link your object files into a final executable. As mentioned in the comments, adding $(INCLUDES) into that recipe is useless because header file directories are only used during compiling (creating object files) not linking (converting object files and libraries into executables).
Because you haven't defined your own rule to build object files, you're using make's built-in rule. But make's built-in rule doesn't know anything about a variable named INCLUDES, so that variable is not used during compilation. You can easily see this by looking at the compiler commands generated by make.
You need to either (a) create your own rule for compiling object files that uses your personal make variables, or (b) use the normal built-in variables that make expects to be used with its built-in rules.
For (b), as described in the manual, you should take your current CPPFAGS [sic] variable and rename it to CXXFLAGS, take your current INCLUDES variable and rename it CPPFLAGS, take your current LIBS_DIRS variable and rename it LDFLAGS, and take your current LDFLAGS variable and rename it to LDLIBS.
Also just to note, you have DEPS etc. but there is nothing in your makefile that does anything with them or to create them so they're useless.
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.
I'm trying to build a small C++ project with GNU make (version 3.81) but i must call make two times because the first run fails. This is my project directory:
project
makefile
include
lexer.hpp
src
main.cpp
lexer.l
Following is my makefile:
CC = g++
CPPFLAGS = -I include
VPATH = include src
OBJECTS = main.o lexer.o
test: $(OBJECTS)
$(CC) $(CPPFLAGS) -lfl -o $# $^
main.o: lexer.hpp main.cpp
$(CC) -c $(CPPFLAGS) $^
lexer.o: lexer.cpp
$(CC) -c $(CPPFLAGS) $^
lexer.cpp: lexer.l
flex -t $^ > src/lexer.cpp
.PHONY: clean
clean:
rm -fR $(OBJECTS) src/lexer.cpp test
The first time i run make i get the following output where make complains about not finding the lexer.cpp file. But i don't understand why make don't seek in the folders declared in VPATH.
g++ -c -I include include/lexer.hpp src/main.cpp
flex -t src/lexer.l > src/lexer.cpp
g++ -c -I include lexer.cpp
g++: error: lexer.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [lexer.o] Error 1
However if i call make again then lexer.cpp is found and the compilation works.
g++ -c -I include src/lexer.cpp
g++ -I include -lfl -o test main.o lexer.o
Why?
P.S. I apologize for poor english.
This rule is wrong:
lexer.cpp: lexer.l
flex -t $^ > src/lexer.cpp
This rule tells make that it will build a file lexer.cpp, and so that's what make is expecting it to do, and after the rule finishes make thinks that file is ready to go, and it will use that filename when other targets depend on it. But what the rule really does, is build src/lexer.cpp.
To write this rule correctly you'll need to write it as:
src/lexer.cpp: lexer.l
flex -t $^ > $#
(every make rule you write should always update the file $#, exactly).
However, in general VPATH is not good for finding generated files (object files, etc.: any file that is generated by make). It's only useful for finding source files (files make doesn't build itself).
I've strictly followed this documentation to install and use jsoncpp library in my project : jsoncpp README
But I still have this problem with my compilation:
g++ -W -Wall -Werror -c -o src/ModConnection.o src/ModConnection.cpp
src/ModConnection.cpp:15:23: fatal error: json/json.h: No such file or directory
compilation terminated.
It's happen when I'm trying to use #include <json/json.h>
Here is my Linux MAKEFILE :
CXX = g++
NAME = bin/server
SRCS = ./src/ModConnection.cpp\
./src/unixNetwork.cpp
OBJS = $(SRCS:.cpp=.o)
CXXFLAGS += -W -Wall -Werror
LDFLAGS = -L ./src/jsoncpp-src-0.5.0/buildscons/linux-gcc4.5.1/src/lib_json/libjson_linux-gcc-4.5.1_libmt.a -I src/jsoncpp-src-0.5.0/include
RM = rm -f
$(NAME) : $(OBJS)
$(CXX) $(LDFLAGS) -o $(NAME) $(OBJS)
all : $(NAME)
clean :
$(RM) $(OBJS)
fclean : clean
$(RM) $(NAME)
re : fclean all
.PHONY : all clean fclean re
Thanks for you help.
You're specifying the include directory for jsoncpp in your LDFLAGS variable, but those don't get used until you've already compiled the individual cpp files. You need to put the part -I src/jsoncpp-src-0.5.0/include somewhere in the flags which get added to the compile lines, such as CXXFLAGS.
To expand a bit, you're using implicit Make rules to build your individual .cpp files, then you have a specific target for building your application out of those objects.
See the GNU Make Catalog of Rules for more info, but the one you're using is here:
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. We encourage you to use the suffix ‘.cc’ for C++ source files instead of ‘.C’.
Edit: Now for your linking errors.
You're getting these problems because the linker can't find the actual implementations of the functions you're calling.
First, your -L directive needs to point to a folder, not a library. -L sets a search path for libraries. It should be set to the folder where the library the jsoncpp build was created. Next, you must link the library itself. That library name is gigantic, but adding -l json_linux-gcc-4.5.1_libmt to LDFLAGS should do the trick. -l (that's lower ell) sets an actual library to link.