makefile for cppunit - makefile

this is my makefile :
#Makefile
CC=g++
CFLAGS=-lcppunit
OBJS=Money.o MoneyTest.o
all : $(OBJS)
$(CC) $(OBJS) -o TestUnitaire
#création des objets
Money.o: Money.cpp Money.hpp
$(CC) -c Money.cpp $(CFLAGS)
MoneyTest.o: MoneyTest.cpp Money.hpp MoneyTest.hpp
$(CC) -c MoneyTest.cpp $(CFLAGS)
clean:
rm *.o $(EXEC)
when i run this makefile, i get errors like those :
g++ Money.o MoneyTest.o -o TestUnitaire
Money.o: In function main':
Money.cpp:(.text+0x3c): undefined reference toCppUnit::TestFactoryRegistry::getRegistry(std::basic_string, std::allocator > const&)'
Money.cpp:(.text+0x78): undefined reference to CppUnit::TextTestRunner::TextTestRunner(CppUnit::Outputter*)'
Money.cpp:(.text+0x8c): undefined reference toCppUnit::TestRunner::addTest(CppUnit::Test*)'
Money.cpp:(.text+0x98): undefined reference to CppUnit::TextTestRunner::result() const'
Money.cpp:(.text+0xec): undefined reference toCppUnit::CompilerOutputter::CompilerOutputter(CppUnit::TestResultCollector*, std::basic_ostream >&, std::basic_string, std::allocator > const&)'
Money.cpp:(.text+0xfc): undefined reference to CppUnit::TextTestRunner::setOutputter(CppUnit::Outputter*)'
Money.cpp:(.text+0x168): undefined reference toCppUnit::TextTestRunner::run(std::basic_string, std::allocator >, bool, bool, bool)'
Money.cpp:(.text+0x1a5): undefined reference to CppUnit::TextTestRunner::~TextTestRunner()'
Money.cpp:(.text+0x233): undefined reference toCppUnit::TextTestRunner::~TextTestRunner()'
It's seems to be that there no link between my class. What's the trouble ?

The -lcppunit flag is not correct in CFLAGS, which is where you put C compiler flags. You are (a) compiling C++ programs, not C programs, and (b) the -l flag is a linker flag, not a compiler flag. Also, the CC variable holds the C compiler. You should use the CXX variable for the C++ compiler. Your makefile should look something like:
#Makefile
CXX = g++
LDLIBS = -lcppunit
OBJS = Money.o MoneyTest.o
all : TestUnitaire
TestUnitaire: $(OBJS)
$(CXX) $^ -o $# $(LDFLAGS) $(LDLIBS)
#création des objets
%.o : %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
Money.o: Money.hpp
MoneyTest.o: Money.hpp MoneyTest.hpp
clean:
rm *.o $(EXEC)

Related

Undefined references in hand-built Makefile

I have a problem with this Makefile, I get a strange gtkmm error.
CXX=g++
MYSQL_DIR=C:/Program\ Files/MySQL/Connector\ C++\ 1.1/
# -W -Wall -Wextra -Werror
CXXFLAGS=-Wall -std=c++11 $(shell pkg-config --cflags gtkmm-3.0) -I$(MYSQL_DIR)/include -IC:/local/boost_1_72_0
OBJECTS= main.o
LDLIBS=$(shell pkg-config --libs gtkmm-3.0) -LC:/local/boost_1_72_0/libs -L$(MYSQL_DIR)/lib -LC:/Program\ Files/MySQL/Connector\ C++\ 1.1/lib/opt -lmysqlcppconn -lmysqlcppconn-static
AffittiApp: $(OBJECTS)
$(CXX) $(OBJECTS) -o AffittiApp
main.o: MainWindow.h MainWindow.cpp Affitto.h Affitto.cpp Conguaglio.h Conguaglio.cpp Inquilino.h Inquilino.cpp Stabile.h Stabile.cpp
$(CXX) $(CXXFLAGS) $(LDLIBS) -c main.cpp MainWindow.cpp Affitto.cpp Conguaglio.cpp Inquilino.cpp Stabile.cpp
clean :
rm -f AffittiApp
rm *.o
echo "pulizia completata"
With this g++ command all works fine
g++ -Wall -std=c++11 Conguaglio.h Conguaglio.cpp Stabile.h Stabile.cpp Inquilino.h Inquilino.cpp Affitto.h Affitto.cpp MainWindow.h MainWindow.cpp main.cpp `pkg-config gtkmm-3.0 --cflags --libs` -IC:/Program\ Files/MySQL/Connector\ C++\ 1.1/include -LC:/Program\ Files/MySQL/Connector\ C++\ 1.1/lib -IC:/local/boost_1_72_0 -LC:/local/boost_1_72_0/libs -LC:/Program\ Files/MySQL/Connector\ C++\ 1.1/lib/opt -lmysqlcppconn -lmysqlcppconn-static
The errors that I get are those:
main.o:main.cpp:(.text+0x35): undefined reference to `Glib::ustring::ustring(char const*)'
main.o:main.cpp:(.text+0x67): undefined reference to `Gtk::Application::create(int&, char**&, Glib::ustring const&, Gio::ApplicationFlags)'
main.o:main.cpp:(.text+0x76): undefined reference to `Glib::ustring::~ustring()'
main.o:main.cpp:(.text+0x82): undefined reference to `MainWindow::MainWindow()'
main.o:main.cpp:(.text+0xa0): undefined reference to `Gtk::Application::run(Gtk::Window&)'
main.o:main.cpp:(.text+0xb1): undefined reference to `MainWindow::~MainWindow()'
main.o:main.cpp:(.text+0xd6): undefined reference to `Glib::ustring::~ustring()'
main.o:main.cpp:(.text+0xf0): undefined reference to `MainWindow::~MainWindow()'
exe: error: ld returned 1 exit status
make: *** [Makefile:11: AffittiApp] Error 1
What I wrong in the Makefile? Can somebody help me please? Thanks!
So, I found the problem...I have to put $(LDLIBS) in the AffittiApp section. Like this (the complete code)
CXX=g++
MYSQL_DIR=C:/Program\ Files/MySQL/Connector\ C++\ 1.1/
CXXFLAGS=-Wall -std=c++11 $(shell pkg-config --cflags gtkmm-3.0) -I$(MYSQL_DIR)/include -IC:/local/boost_1_72_0
OBJECTS= main.o MainWindow.o Affitto.o Inquilino.o Stabile.o Conguaglio.o
LDLIBS=$(shell pkg-config --libs gtkmm-3.0) -LC:/local/boost_1_72_0/libs -L$(MYSQL_DIR)/lib -L$(MYSQL_DIR)/lib/opt -lmysqlcppconn -lmysqlcppconn-static
AffittiApp: $(OBJECTS)
$(CXX) $(OBJECTS) $(LDLIBS) -o AffittiApp
main.o: MainWindow.h MainWindow.cpp Affitto.h Affitto.cpp Conguaglio.h Conguaglio.cpp Inquilino.h Inquilino.cpp Stabile.h Stabile.cpp
$(CXX) $(CXXFLAGS) -c main.cpp
I wrote this answer in case somebody have the same problem.

Mac: Variant of make file made by Codelite IDE can't find gsl

I'm trying to add function iceemdan() to the open source library libeemd.c. I'm trying to debug it with an IDE. The make file's first call to clang result's in clang's inability to find the gsl library, even though it is present and the make file upon which the IDE's make file is based has no trouble linking to gsl.
Here's the make file output (gsl errors and context only) using the Codelite IDE make file:
Executing Pre Build commands ...
Done
make[1]: Leaving directory '/Users/Common/iceemdan-dev/iceemdan-dev/iceemdan-clang'
make[1]: Entering directory '/Users/Common/iceemdan-dev/iceemdan-dev/iceemdan-clang'
clang -o ./Debug/iceemdan-clang #"iceemdan-clang.txt" -L.
Undefined symbols for architecture x86_64:
"_gsl_linalg_solve_tridiag", referenced from:
_emd_evaluate_spline in main.c.o
"_gsl_poly_dd_eval", referenced from:
_emd_evaluate_spline in main.c.o
"_gsl_poly_dd_init", referenced from:
_emd_evaluate_spline in main.c.o
"_gsl_ran_gaussian", referenced from:
_iceemdan in main.c.o
_eemd in main.c.o
_ceemdan in main.c.o
"_gsl_rng_alloc", referenced from:
_allocate_eemd_workspace in main.c.o
"_gsl_rng_free", referenced from:
_free_eemd_workspace in main.c.o
"_gsl_rng_mt19937", referenced from:
_allocate_eemd_workspace in main.c.o
"_gsl_rng_set", referenced from:
_set_rng_seed in main.c.o
"_gsl_set_error_handler_off", referenced from:
_iceemdan in main.c.o
_eemd in main.c.o
_ceemdan in main.c.o
_emd_evaluate_spline in main.c.o
"_gsl_sf_sin", referenced from:
_main in main.c.o
"_gsl_stats_sd", referenced from:
_iceemdan in main.c.o
_eemd in main.c.o
_ceemdan in main.c.o
"_gsl_strerror", referenced from:
_emd_evaluate_spline in main.c.o
"_gsl_vector_view_array", referenced from:
_emd_evaluate_spline in main.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [iceemdan-clang.mk:82: Debug/iceemdan-clang] Error 1
make[1]: Leaving directory '/Users/Common/iceemdan-dev/iceemdan-dev/iceemdan-clang'
make: *** [Makefile:5: All] Error 2
This make file, a modification of the package make file to run on the Mac, works:
.PHONY: all clean install uninstall
version := 1.4.1
gsl_flags := $(shell pkg-config --libs --cflags gsl)
ifeq ($(gsl_flags),)
$(error Failed to query GSL complilation flags from pkg-config)
endif
gsl_flags += -DHAVE_INLINE
commonflags := -Wall -Wextra -std=c99 -pedantic -Wno-unknown-pragmas -Wshadow -Wpointer-arith
commonflags += $(CFLAGS)
commonflags += -g -DEEMD_DEBUG=0
#commonflags += -fopenmp
commonflags += -DCLANG
PREFIX ?= /usr
SONAME = -soname
ifeq ($(shell uname -s),Darwin)
SONAME = -install_name
endif
define uninstall_msg
If you used $(PREFIX) as the prefix when running `make install`,
you can undo the install by removing these files:
$(PREFIX)/include/eemd.h
$(PREFIX)/lib/libeemd.a
$(PREFIX)/lib/libeemd.so
$(PREFIX)/lib/libeemd.so.$(version)
endef
export uninstall_msg
all: libeemd.so.$(version) libeemd.a eemd.h
clean:
rm -f libeemd.so libeemd.so.$(version) libeemd.a eemd.h obj/eemd.o
rm -rf obj
install:
install -d $(PREFIX)/include
install -d $(PREFIX)/lib
install -m644 eemd.h $(PREFIX)/include
install -m644 libeemd.a $(PREFIX)/lib
install libeemd.so.$(version) $(PREFIX)/lib
cp -Pf libeemd.so $(PREFIX)/lib
uninstall:
#echo "$$uninstall_msg"
obj:
mkdir -p obj
obj/eemd.o: src/eemd.c src/eemd.h | obj
clang $(commonflags) -c $< $(gsl_flags) -o $#
libeemd.a: obj/eemd.o
$(AR) rcs $# $^
libeemd.so.$(version): src/eemd.c src/eemd.h
clang $(commonflags) $< -fPIC -shared -Wl,$(SONAME),$# $(gsl_flags) -o $#
ln -sf $# libeemd.so
eemd.h: src/eemd.h
cp $< $#
The Codelite second level make file is here. (The first level merely calls it.) I'm running in a different directory to avoid overwriting my good code.
##
## Auto Generated makefile by CodeLite IDE
## any manual changes will be erased
##
## Debug
ProjectName :=iceemdan-clang
ConfigurationName :=Debug
WorkspacePath :=/Users/Common/iceemdan-dev/iceemdan-dev
ProjectPath :=/Users/Common/iceemdan-dev/iceemdan-dev/iceemdan-clang
IntermediateDirectory :=./Debug
OutDir := $(IntermediateDirectory)
CurrentFileName :=
CurrentFilePath :=
CurrentFileFullPath :=
User :=Coleman Family
Date :=08/08/2018
CodeLitePath :="/Users/Common/Library/Application Support/CodeLite"
LinkerName :=clang
SharedObjectLinkerName :=clang -shared -fPIC
ObjectSuffix :=.o
DependSuffix :=
PreprocessSuffix :=.o.i
DebugSwitch :=-gstab
IncludeSwitch :=-I
LibrarySwitch :=-l
OutputSwitch :=-o
LibraryPathSwitch :=-L
PreprocessorSwitch :=-D
SourceSwitch :=-c
OutputFile :=$(IntermediateDirectory)/$(ProjectName)
Preprocessors :=
ObjectSwitch :=-o
ArchiveOutputSwitch :=
PreprocessOnlySwitch :=-E
ObjectsFileList :="iceemdan-clang.txt"
PCHCompileFlags :=
MakeDirCommand :=mkdir -p
LinkOptions :=
IncludePath := $(IncludeSwitch). $(IncludeSwitch).
IncludePCH :=
RcIncludePath :=
Libs :=
ArLibs :=
LibPath := $(LibraryPathSwitch).
##
## Common variables
## AR, CXX, CC, AS, CXXFLAGS and CFLAGS can be overriden using an environment variables
##
AR := ar rcus
CXX := clang++
CC := clang
CXXFLAGS := -g -O0 -Wall $(Preprocessors)
CFLAGS := $(commonflags) $< -fPIC -shared -Wl $# $(gsl_flags) -o $# $(Preprocessors)
ASFLAGS :=
AS := llvm-as
##
## User defined environment variables
##
CodeLiteDir:=/Applications/codelite.app/Contents/SharedSupport/
PATH:=/Users/Common/usr/local/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/opt/local/bin:/opt/local/sbin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/TeX/texbin:/opt/local/include
Srcs=main.c
Objects0=$(IntermediateDirectory)/main.c$(ObjectSuffix)
Objects=$(Objects0)
##
## Main Build Targets
##
.PHONY: all clean PreBuild PrePreBuild PostBuild MakeIntermediateDirs
all: $(OutputFile)
$(OutputFile): $(IntermediateDirectory)/.d $(Objects)
#$(MakeDirCommand) $(#D)
#echo "" > $(IntermediateDirectory)/.d
#echo $(Objects0) > $(ObjectsFileList)
$(LinkerName) $(OutputSwitch)$(OutputFile) #$(ObjectsFileList) $(LibPath) $(Libs) $(LinkOptions)
MakeIntermediateDirs:
#test -d ./Debug || $(MakeDirCommand) ./Debug
$(IntermediateDirectory)/.d:
#test -d ./Debug || $(MakeDirCommand) ./Debug
PreBuild:
#echo Executing Pre Build commands ...
$(eval gsl_flags = -L/opt/local/lib -lgsl -lgslcblas -lm -I/opt/local/include -DHAVE_INLINE)
$(eval commonflags := -Wall -Wextra -std=c99 -pedantic -Wno-unknown-pragmas -Wshadow -Wpointer-arith)
$(eval commonflags += $(CFLAGS))
$(eval commonflags += -g -DEEMD_DEBUG=0)
$(eval commonflags += -DCLANG)
$(eval PREFIX ?= /usr)
#echo Done
# all
Debug/main.c.o: main.c
#src/eemd.h | Debug
clang $(commonflags) -c $< $(gsl_flags) -o $#
Debug/main.c.a: Debug/main.c.o
$(AR) rcs $# $^
eemd: main.c src/eemd.h
clang $(commonflags) $< -fPIC -shared -Wl, ,$# $(gsl_flags) -o $#
My apologies for the length of this post. In the past, I've only run unmodified make files, not debug them. So, a lot of this is new and not transparent to me. I'd appreciate any help.
I had to trick the command for building main.c.o using global variables.

Make error: commands commence before first target

Makefile:
CC = gcc
CFLAGS = -D__XMLSEC_FUNCTION__=__FUNCTION__ -DXMLSEC_NO_XSLT=1 -DXMLSEC_NO_XKMS=1 -I/usr/include/libxml2 -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1 -DXMLSEC_CRYPTO=\"openssl\" -DUNIX_SOCKETS -DXML_SECURITY -DDEBUG
LDFLAGS= -lcrypto -I/usr/include/libxml2 -lxml2 -I/usr/local/include/xmlsec1 -lxmlsec1
$(CC) $(CFLAGS) $(LDFLAGS) src/aadhaar.c src/uid_auth.c -o AuthClient
I'm getting this error: error: commands commence before first target
You seem to miss the target definition:
AuthClient : src/aadhaar.c src/uid_auth.c
$(CC) $(CFLAGS) $(LDFLAGS) src/aadhaar.c src/uid_auth.c -o $#

Makefile: Adding 2nd directory for .h and .cpp files

I am adapting my Makefile to look into 4 directories, rather than 2 (it had one for source files and one for header files, but I've added a new folder for common source and include). I have something like follows:
CC = g++
FLAGS = -g -c
BUILDDIR = build
INCLUDEDIR = -Icode/inc -I../common/code/inc -I/usr/include/libxml2
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(SOURCEDIR)/*.cpp)
OBJECTS = $(patsubst $(SOURCEDIR)/%.cpp,$(BUILDDIR)/%.o,$(SOURCES))
EXECUTABLE = Exec
all: $(BUILDDIR)/$(EXECUTABLE)
$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o $# -lpthread -lxml2
$(OBJECTS): $(BUILDDIR)/%.o : $(SOURCEDIR)/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
I tried to add one entry to INCLUDEDIR as follows:
-I../common/code/inc
And added ../common/code/src to SOURCEDIR:
SOURCEDIR = code/src ../common/code/src
This is not currently working and I am wondering how to fix it please. I am getting the error:
Makefile:27: target `code/src' doesn't match the target pattern
but I cannot find how to fix it so far. Any help would be appreciated.
EDIT: After following MadScientist response below, I am getting the following output:
g++ -c -o code/src/Client.o code/src/Client.cpp
code/src/Client.cpp:1:20: fatal error: Client.h: No such file or directory
compilation terminated.
make: *** [code/src/Client.o] Error 1
Updated Makefile:
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR)))
OBJECTS = $(SOURCES:%.cpp=%.o)
$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o $# -lpthread -lxml2
$(BUILDDIR)/%.o : ../common/code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
$(BUILDDIR)/%.o : code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
PS:
I was able to fix it using the following:
SOURCEDIR = code/src ../common/code/src
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR)))
TEMP_OBJ = $(SOURCES:%.cpp=%.o)
NOT_DIR = $(notdir $(TEMP_OBJ))
OBJECTS = $(addprefix $(BUILDDIR)/, $(NOT_DIR))
Sure, because now your static pattern rule expands to:
$(OBJECTS): build/%.o : code/src ../common/code/src/%.cpp
which is illegal syntax. If you avoid using static pattern rules, and instead use pattern rules, then it will just work. Replace your single static pattern rule with two pattern rules:
$(BUILDDIR)/%.o : code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
$(BUILDDIR)/%.o : ../common/code/src/%.cpp
$(CC) $(FLAGS) $< $(INCLUDEDIR) -o $# -Wno-write-strings
EDIT: you also need to change other uses of SOURCEDIR:
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR))
OBJECTS = $(patsubst %.cpp,$(BUILDDIR)/%.o,$(notdir $(SOURCES)))

undefined reference static library makefile

I am trying to link a static library while creating my program executable using the below makefile..
IDIR =../inc
CC=g++ -g
CFLAGS=-I$(IDIR)
WFLAGS=-Wall -W
OFLAGS=-O3
DLINUX=-D_LINUX
ODIR=obj
LDIR =../lib
LIBS=-lm
_OBJ = testclient.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/testclient.o: testclient.c
$(CC) -c $< $(CFLAGS) -o $#
$(ODIR)/file2.o: file2.c
$(CC) -c $< $(CFLAGS) -o $#
testclient: $(OBJ)
$(CC) -o $# $^ $(LIBS) -lccn -pthread
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
I have tried everything available from changing the order of the '-lccn' parameter to checking whether the function exists in the library (nm libccn.a gives the required function ccn_create() in it). The error returned is :
obj/testclient.o: In function `main':
/root/testClient/src/testclient.c:91: undefined reference to `ccn_create()'
The library libccn.a is in /usr/local/lib. I have also tried changing the directory path and then using -L flag to look in that location. Doesn't work either. :( ..Any ideas as to how can i make it work ?
My guess is that libccn.a is a C library and the header that you use are not designed to be imported by a C++ compiler (there is no extern "C" { } block surrounding the function definition).
C++ supports function overloading by mangling name of function. When you put a function in a extern "C" { } block, C++ disable name mangling (and thus disable overloading). Here, in your error message, the function mentioned is ccn_create(). Notice the (), this means that the function type is known, and thus the named looked up was a mangled name.
When you do nm libccn.a you see the real name, and it is ccn_create. That is not a mangled name. So to fix this, you'll need to surround the function definition in a export "C" { } block. The easiest way to do that is to surround the #include in such a block.
BTW, you can reproduce the error by doing this.
$ echo 'void ccn_create();' > ccn.h
$ echo '#include "ccn.h"
void ccn_create() { }' > ccn.c
$ echo '#include "ccn.h"
int main () {
ccn_create();
return 0;
}' > main.cc
$ gcc -o ccn.o -c ccn.c
$ g++ -o main main.cc ccn.o
Undefined symbols for architecture x86_64:
"ccn_create()", referenced from:
_main in cc8XnYRq.o
ld: symbol(s) not found for architecture x86_64
$ echo 'extern "C" {
#include "ccn.h"
}
int main () {
ccn_create();
return 0;
}' > main.cc
$ g++ -o main main.cc ccn.o

Resources