I want to compile 2 classes into .o file and include them in Test.exe file created from avl.cpp main file.
I use the MinGW tool while doing this, but Nothing happens when I type the command mingw32-make into CMD. When I did this with only 1 class, there was no problem.
The content of the makefile file is as follows:
all: compile execute
compile:
g++ -I ./include/ -o ./lib/AVLClass.o -c ./src/AVLClass.cpp
g++ -I ./include/ -o ./lib/PersonsClass.o -c ./src/PersonsClass.cpp
g++ -I ./include/ -o ./bin/Test ./lib/PersonsClass.o ./lib/AVLClass.o ./src/avl.cpp
execute:
./bin/Test
Makefile uses dependancies to determine what gets built in which order.
So the line execute: should really be execute: compile to tell make to do the execute step after the compile step completed.
But you should really split compilation an linking into steps to use the dependancy resolving qualities of make.
Here's how I would do it:
BINEXT=.exe
CXX=g++
MKDIR=mkdir -p
RM=rm -f
all: bin/Test$(BINEXT) test
lib/%.o: src/%.cpp
$(MKDIR) lib
$(CXX) -c -o $# $^
bin/Test$(BINEXT): lib/AVLClass.o lib/PersonsClass.o lib/avl.o
$(MKDIR) bin
$(CXX) -o $# $^
test: bin/Test$(BINEXT)
bin/Test$(BINEXT)
clean:
$(RM) lib/*.o bin/Test$(BINEXT)
Note that the indents must be tabs, not spaces.
Actually I wouldn't add test to the all target. It's better to leave it up to the user if they want to run make test.
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 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.
C++ newbie here my command is g++ main.cpp -o main gives me linking errors like the following
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
if i pass c++ files g++ main.cpp myfile.cpp -o main everything is correct
any ideas how to compile multiple c++ files without passing everything in command line.
Thanks
any ideas how to compile multiple c++ files without passing everything in command line.
To build an application you need all object files, so you have to pass all cpp files to compiler.
But for simple cases when all cpp-files stay at single folder, you can
use command (simple, but slow method):
g++ *.cpp -o main
any ideas how to compile multiple c++ files without passing everything in command line.
First create object files:
g++ -c main.cpp -o main.o
g++ -c myfile.cpp -o myfile.o
Then pass them to the linker:
g++ main.o myfile.o -o main
Though there is a fairly large learning curve for Make, a make file is the preferred solution. On SO, I have also noticed significant use of CMake.
Additional ideas for your Makefile:
The following two rules handle 90% of my simpler unit test executables:
R01 handles files with both .cc and .hh
R02 handles files with only .cc
# pattern rule R01
# when any ARCHIVE changes, trigger a rebuild
% : %.cc %.hh $(LIB_ARCHIVEs)
#echo
#echo R01: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
# pattern rule R02
# when any ARCHIVE changes, trigger a rebuild
% : %.cc $(LIB_ARCHIVEs)
#echo
#echo R02: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
Occasionally, I will add specific LIB names and directories ... directly to the LIB_DIRs and LIB_NMs definition in the Makefile. For example, here I have added -lrt and -pthread:
LIB_NMs += -lbag_i686 -lposix_i686 -lrt -pthread
bag_i686 and posix_i686 are libraries I built ... simple C++ class wrappers around the linux and posix functions. Most of my unit tests do not use much of posix stuff, but I get no grief including it.
With C++ std::thread, I seldom use -pthread. However, I occasionally use posix semaphore.
My compile command line access (in emacs on Ubuntu) provides a history, so the occasional change or addition to the command line is only a 'bother' one time. From then on, the newer command is available in history.
The emacs I launch is configured with an 'embedded' pre-defined compile command:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' -j 2 -k
This command shows up the 1st time I launch the compiler from within emacs. Emacs presents it as if the command is already in 'compile-command history'.
I manually shorten this if I'm not rebuilding all, usually I only build a single ut:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64'
So, for example, when I am ready to compile dumy431.cc, I invoke:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' dumy431
The next build I launch (from within emacs compile) starts with the previous command, and up/down arrow roll through any other versions of the command.
With this form of the command, I can trivially change from g++ to clang++ by inserting "clan" at the appropriate place:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='clang++ -m64'
clang++ often provides additional diagnostics that g++ does not report. To roll back to g++, I can up-arrow in the compiler command panel (or edit the command).
Here is a small example where my unit test code has multiple src files. Often, the non-main files (such as eng_format.*) are code that I plan to capture to one of my libraries for future use:
FMssb.o : FMssb.cc FMssb.hh
#echo
#echo R_FMssb.o: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $#
FMssb_ut : FMssb_ut.cc eng_format.o FMssb.o $(LIB_ARCHIVEs)
#echo
#echo R_FMssb_ut: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# eng_format.o FMssb.o $(LIB_DIRs) $(LIB_NMs)
eng_format.o : eng_format.cpp eng_format.hpp $(LIB_ARCHIVEs)
#echo
#echo R_EF: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $# $(LIB_DIRs) $(LIB_NMs)
I have a Makefile that works for how I'm using it, but will anyone tell me if what I'm doing is good practice? Or if there is a better, cleaner or more efficient way to achieve the goal I am reaching?
Here is my Makefile Code.
# Object files to either reference or create
OBJECTS = Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
# The executable file that will be created
EXEC = Proj2.out
# The c++ flags to use for compilation
CXXFLAGS = -Wall
# The c++ compiler to use for compilation
CXX = g++
# This section is called on 'make'
# Will call compile, and then call clean
all: compile clean
# Perform action on all object files (May or may not exist)
# The makefile will implicitly compile all .o files needed
# Will also compile them into the EXEC file listed
compile: $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(EXEC) $(OBJECTS)
# This section is called after compilation is completed
# This will clean all existing .o files listed in the directory
clean:
rm -f *.o
Here is the terminal output when I call make.
g++ -Wall -c -o Proj2.o Proj2.cpp
g++ -Wall -c -o Blackjack.o Blackjack.cpp
g++ -Wall -c -o Deck.o Deck.cpp
g++ -Wall -c -o Card.o Card.cpp
g++ -Wall -c -o Hand.o Hand.cpp
g++ -Wall -c -o Player.o Player.cpp
g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
rm -f *.o
Is it good practice to use a Makefile like this? Specifically, am I doing the cleaning part of my Makefile correctly?
You should not make all depend on clean at all. By doing this you are ensuring that every time you run make, you have to recompile everything. If you want to do that then using make is itself useless: just write a shell script that compiles and links your code.
The clean target should be a separate target and if you want to clean your workspace you run make clean explicitly.
The other problem with your makefile is that the link rule lists compile as the target, but it builds $(EXE). It's almost never a good idea to have a rule create a file which is not exactly the target you told make it would build. To ensure this, always use $# as the target to generate. Rewrite it like this:
compile: $(EXE)
$(EXE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $^
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).