I have been scratching my head since yesterday trying to make gtest work but I just can't fix it after reading the links below.
undefined reference to `pthread_key_create' (linker error)
error during making GTest
The compilation error displayed is this:
g++ main.o tests.o var.o -L ../gmock/lib/.libs -L ../gmock/gtest/lib/.libs
-lgtest -lgmock -lpthread -o test
../gmock/gtest/lib/.libs/libgtest.so: undefined reference to `pthread_key_create'
../gmock/gtest/lib/.libs/libgtest.so: undefined reference to `pthread_getspecific'
../gmock/gtest/lib/.libs/libgtest.so: undefined reference to `pthread_key_delete'
../gmock/gtest/lib/.libs/libgtest.so: undefined reference to `pthread_setspecific'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
My Makefile is:
CXXFLAGS=-I ../gmock/include -I ../gmock/gtest/include
test:main.o tests.o var.o
g++ $^ -L ../gmock/lib/.libs -L ../gmock/gtest/lib/.libs -lgtest -lgmock -lpthread -o $#
I am still in the process of learning Linux, compiling and linking source files.
The Error is about linking error on pthread.
You have to make the pthread flag to -pthread and the follow CXX should do the trick.
LDLIBS = -L../gmock/lib/.libs -L../gmock/gtest/lib/.libs -lgtest -lgmock
test:main.o tests.o var.o
g++ -isystem $(LDLIBS) -pthread $^ -o $#
This link have a good Makefile which addresses all your problems and it follows general standards on creating a Makefile
Related
Actually, I am working with the well-known SVM-struct project (http://www.cs.cornell.edu/people/tj/svm_light/svm_struct.html)on Ubuntu 16.04. I followed the instructions in http://www.cs.cornell.edu/people/tj/svm_light/svm_multiclass.html to use SVM-multiclass, downloaded the source code and make. But I met some errors when building the project:
$ make
cd svm_light; make svm_learn_hideo_noexe
make[1]: Entering directory '/home/parallels/CLionProjects/svm_multiclass/svm_light'
make[1]: Nothing to be done for 'svm_learn_hideo_noexe'.
make[1]: Leaving directory '/home/parallels/CLionProjects/svm_multiclass/svm_light'
cd svm_struct; make svm_struct_noexe
make[1]: Entering directory '/home/parallels/CLionProjects/svm_multiclass/svm_struct'
make[1]: Nothing to be done for 'svm_struct_noexe'.
make[1]: Leaving directory '/home/parallels/CLionProjects/svm_multiclass/svm_struct'
gcc -O3 -lm -Wall svm_struct/svm_struct_learn.o svm_struct_learn_custom.o svm_struct_api.o svm_light/svm_hideo.o svm_light/svm_learn.o svm_light/svm_common.o svm_struct/svm_struct_common.o svm_struct/svm_struct_main.o -o svm_multiclass_learn
svm_light/svm_learn.o: In function `estimate_sphere':
svm_learn.c:(.text+0x6e88): undefined reference to `sqrt'
svm_light/svm_learn.o: In function `estimate_r_delta':
svm_learn.c:(.text+0x7053): undefined reference to `sqrt'
svm_light/svm_learn.o: In function `estimate_r_delta_average':
svm_learn.c:(.text+0x7b04): undefined reference to `sqrt'
svm_light/svm_learn.o: In function `length_of_longest_document_vector':
svm_learn.c:(.text+0x7b86): undefined reference to `sqrt'
svm_light/svm_learn.o: In function `incorporate_unlabeled_examples':
svm_learn.c:(.text+0x89eb): undefined reference to `sqrt'
svm_light/svm_learn.o:svm_learn.c:(.text+0xc952): more undefined references to `sqrt' follow
svm_light/svm_common.o: In function `classify_example':
svm_common.c:(.text+0x38f): undefined reference to `tanh'
svm_common.c:(.text+0x42d): undefined reference to `exp'
svm_common.c:(.text+0x4a7): undefined reference to `pow'
svm_light/svm_common.o: In function `kernel':
svm_common.c:(.text+0x870): undefined reference to `tanh'
svm_common.c:(.text+0x90d): undefined reference to `exp'
svm_common.c:(.text+0x988): undefined reference to `pow'
svm_light/svm_common.o: In function `model_length_s':
svm_common.c:(.text+0x2c8d): undefined reference to `sqrt'
svm_light/svm_common.o: In function `model_length_n':
svm_common.c:(.text+0x2f5c): undefined reference to `sqrt'
svm_light/svm_common.o: In function `cholesky_matrix':
svm_common.c:(.text+0x3c6f): undefined reference to `sqrt'
svm_light/svm_common.o: In function `find_indep_subset_of_matrix':
svm_common.c:(.text+0x3f41): undefined reference to `sqrt'
svm_light/svm_common.o: In function `single_kernel':
svm_common.c:(.text+0xc0c): undefined reference to `tanh'
svm_common.c:(.text+0xc84): undefined reference to `pow'
svm_common.c:(.text+0xcfb): undefined reference to `exp'
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target 'svm_multiclass_learn' failed
make: *** [svm_multiclass_learn] Error 1
I think the Makefile has already included -lm.
# Makefile for SVM-multiclass, 03.07.04
#Use the following to compile under unix or cygwin
CC = gcc
LD = gcc
#Call 'make' using the following line to make CYGWIN produce stand-alone Windows executables
# make 'SFLAGS=-mno-cygwin'
CFLAGS = $(SFLAGS) -O3 -fomit-frame-pointer -ffast-math -Wall
LDFLAGS = $(SFLAGS) -O3 -lm -Wall
#CFLAGS = $(SFLAGS) -pg -Wall
#LDFLAGS = $(SFLAGS) -pg -lm -Wall
all: svm_multiclass_learn svm_multiclass_classify
.PHONY: clean
clean: svm_light_clean svm_struct_clean
rm -f *.o *.tcov *.d core gmon.out *.stackdump
#-----------------------#
#---- SVM-light ----#
#-----------------------#
svm_light_hideo_noexe:
cd svm_light; make svm_learn_hideo_noexe
svm_light_clean:
cd svm_light; make clean
#----------------------#
#---- STRUCT SVM ----#
#----------------------#
svm_struct_noexe:
cd svm_struct; make svm_struct_noexe
svm_struct_clean:
cd svm_struct; make clean
#-------------------------#
#---- SVM MULTICLASS ----#
#-------------------------#
svm_multiclass_classify: svm_light_hideo_noexe svm_struct_noexe svm_struct_api.o svm_struct/svm_struct_classify.o svm_struct/svm_struct_common.o svm_struct/svm_struct_main.o
$(LD) $(LDFLAGS) svm_struct_api.o svm_struct/svm_struct_classify.o svm_light/svm_common.o svm_struct/svm_struct_common.o -o svm_multiclass_classify $(LIBS)
svm_multiclass_learn: svm_light_hideo_noexe svm_struct_noexe svm_struct_api.o svm_struct_learn_custom.o svm_struct/svm_struct_learn.o svm_struct/svm_struct_common.o svm_struct/svm_struct_main.o
$(LD) $(LDFLAGS) svm_struct/svm_struct_learn.o svm_struct_learn_custom.o svm_struct_api.o svm_light/svm_hideo.o svm_light/svm_learn.o svm_light/svm_common.o svm_struct/svm_struct_common.o svm_struct/svm_struct_main.o -o svm_multiclass_learn $(LIBS)
svm_struct_api.o: svm_struct_api.c svm_struct_api.h svm_struct_api_types.h svm_struct/svm_struct_common.h
$(CC) -c $(CFLAGS) svm_struct_api.c -o svm_struct_api.o
svm_struct_learn_custom.o: svm_struct_learn_custom.c svm_struct_api.h svm_light/svm_common.h svm_struct_api_types.h svm_struct/svm_struct_common.h
$(CC) -c $(CFLAGS) svm_struct_learn_custom.c -o svm_struct_learn_custom.o
The linker collects dependencies first (svm_light/svm_learn.o) and fills them in when it sees a definition (-lm).
You seem to already have a $(LIBS) at the end of your ld invocation, so just:
LIBS += -lm
should fix it.
Other tips:
you can replace the pattern cd X; make TARGET with make -C X TARGET
you can refer to the target as $# and the first prerequisite in the dependency list as $<, so your last rule can be written as:
svm_struct_learn_custom.o: svm_struct_learn_custom.c svm_struct_api.h svm_light/svm_common.h svm_struct_api_types.h svm_struct/svm_struct_common.h
$(CC) -c $(CFLAGS) $< -o $#
where the recipe redefinition of the built-in recipe for compiling .c files, so it suffices to simply list the headers as (extra) prerequisites:
svm_struct_learn_custom.o: svm_struct_api.h svm_light/svm_common.h svm_struct_api_types.h svm_struct/svm_struct_common.h
There are a couple similar problems to this but they all seem to have answers that don't work.
I've installed opencv4 onto an image of Ubuntu and I know the opencv files are install correctly
$ pkg-config --cflags opencv
-I/usr/include/opencv
and have a proper .cp file
/usr/local/lib/pkgconfig$ ls
gpr.pc grpc++.pc grpc++_unsecure.pc protobuf-lite.pc
grpc.pc grpc_unsecure.pc opencv4.pc protobuf.pc
But even though it's all installed correctly it's giving me this error.
~/neuralink/neuralink-image-service-prompt/proto$ make g++ -std=c++11 `pkg-config --cflags opencv protobuf grpc` -L/usr/local/lib `pkg-config --libs opencv protobuf grpc++` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl foo.cpp -o foo
/tmp/ccnfoOEl.o: In function `main':
foo.cpp:(.text+0x48): undefined reference to `cv::imread(cv::String const&, int)'
/tmp/ccnfoOEl.o: In function `cv::String::String(char const*)':
foo.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x4d): undefined reference to `cv::String::allocate(unsigned long)'
/tmp/ccnfoOEl.o: In function `cv::String::~String()':
foo.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccnfoOEl.o: In function `cv::String::operator=(cv::String const&)':
foo.cpp:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
/tmp/ccnfoOEl.o: In function `cv::Mat::~Mat()':
foo.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/tmp/ccnfoOEl.o: In function `cv::Mat::release()':
foo.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'foo' failed
make: *** [foo] Error 1
Some people have already tried answering similar questions (such as Undefined reference to cv::imread(cv::String const&, int) and linking opencv libraries with g++) however these don't help, as the user didn't add opencv to their makefile and I have.
Here is my make makefile
LDFLAGS = -L/usr/local/lib `pkg-config --libs opencv protobuf grpc++`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
CXX = g++
CPPFLAGS += `pkg-config --cflags opencv protobuf grpc`
CXXFLAGS += -std=c++11
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
all: foo
client: image.pb.o image.grpc.pb.o client.o
$(CXX) $^ $(LDFLAGS) -o $#
server: image.pb.o image.grpc.pb.o server.o
$(CXX) $^ $(LDFLAGS) -o $#
%.grpc.pb.cc: %.proto
protoc --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
%.pb.cc: %.proto
protoc --cpp_out=. $<
clean:
rm -f *.o *.pb.cc *.pb.h client server
And I wrote a simple program that still throws the error
#include <opencv2/opencv.hpp>
#include <stdio.h>
int main() {
cv::Mat frame = cv::imread("sylvania.png", cv::IMREAD_UNCHANGED);
printf("Image size is %i x %i\n", frame.rows, frame.cols);
}
Everything seems to compile fine but I keep getting this linker issue. I don't seem to get the issue when I compile it on another computer (my mac) for what it's worth. Also I have the gRPC and Protoc files because I need them for the project, I just didn't use those file as an example since they're quite long.
I agree with Micka, here is a Makefile of one of my projects:
CPPFLAGS=-g -Wall -I. -DDEBUG
LDFLAGS=-g
LDLIBS=-lopencv_core -lopencv_calib3d -lopencv_highgui -lopencv_imgproc -lopencv_stitching -lopencv_video
main: main.o AffineKalmanLP.o
g++ $(LDFLAGS) -o main main.o AffineKalmanLP.o $(LDLIBS)
main.o: main.cpp main.h
g++ $(CPPFLAGS) -c main.cpp
AffineKalmanLP.o: AffineKalmanLP.cpp AffineKalmanLP.h
g++ $(CPPFLAGS) -c AffineKalmanLP.cpp
clean:
rm main main.o AffineKalmanLP.o
You need to add it to LDLIBS.
If I remove that line, I get undefined reference for various things as well.
I am programming a module for my Alderbaran Nao V5 robot. Alderbaran recommends using qibuild to compile a module, and I was able to successfully do so, but now I am trying to migrate towards writing my own makefile and using g++.
I am encountering the following error:
/usr/lib/gcc/i686-pc-linux-gnu/4.5.3/../../../../lib/crt1.o: In function
`_start':
(.text+0x18): undefined reference to `main'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqimessaging.so: undefined reference to `std::__detail::_List_node_base::swap(std::__detail::_List_node_base&, std::__detail::_List_node_base&)#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqi.so: undefined reference to `std::invalid_argument::~invalid_argument()#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqitype.so: undefined reference to `std::out_of_range::~out_of_range()#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqitype.so: undefined reference to `std::__detail::_List_node_base::_M_transfer(std::__detail::_List_node_base*, std::__detail::_List_node_base*)#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqimessaging.so: undefined reference to `std::__detail::_List_node_base::_M_unhook()#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqimessaging.so: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)#GLIBCXX_3.4.15'
/home/nao/naoqi-sdk-2.1.3.3-linux32/lib/libqi.so: undefined reference to `posix_spawnp#GLIBC_2.15'
collect2: ld returned 1 exit status
make: *** [shm.so] Error 1
Here is the makefile I am using:
#Variables
CXXFLAGS=-Wall -g
CXX = g++
NaoQi_INC = /home/nao/naoqi-sdk-2.1.3.3-linux32/include
NaoQi_LIB = -L/home/nao/naoqi-sdk-2.1.3.3-linux32/lib -lalcommon -lalerror -lalproxies -lalvalue -lqimessaging -lqitype -lqi
#Object Targets
main.o: main.cpp shm.h
$(CXX) $(CXXFLAGS) -c -I$(NaoQi_INC) main.cpp
shm.o: shm.cpp shm.h $(NaoQi_INC)/alcommon/alproxy.h $(NaoQi_INC)/alcommon/albroker.h $(NaoQi_INC)/alcommon/almodule.h
$(CXX) $(CXXFLAGS) -c -I$(NaoQi_INC) shm.cpp
#Library Targets
shm.so: main.o shm.o
$(CXX) $(CXXFLAGS) -o shm.so main.o shm.o -L/usr/local/lib -lm $(NaoQi_LIB)
clean:
rm -f *o main
rm -f *o shm
all: shm.o main.o shm.so
I noticed that the gentoo operating system I am compiling on has up to GLIBCXX_3.4.14 but does not have GLIBCXX_3.4.15. How can I fix this issue? Why would this issue not present itself when I build the module using qibuild?
Interestingly, the problem was that my .so linking command was missing a -shared flag. Not sure why that gave all of the errors I ran into, however.
(Hello, this is my first post, and I am using Dev C++ IDE 5.11)
I included the header, SOIL.h and the linker: -lSOIL.
This program compiles with no problem and runs correctly, but when I add any function into my code from the SOIL library, I receive a linker error.
'recipe for target 'Project1.exe' failed'
Here is the code from SOIL that causes the linker error:
unsigned char* image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB);
(There is probably an easy explanation and answer for this, but I have searched everywhere as I cannot find it.)
Note: I am following a tutorial from the website learnopengl
Here is my makefile.win:
# Project: Project1
# Makefile created by Dev-C++ 5.11
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = Untitled2.o
LINKOBJ = Untitled2.o
LIBS = -L"D:/Dev-Cpp/MinGW32/lib" -L"D:/Dev-Cpp/MinGW32/mingw32/lib" -static-libstdc++ -static-libgcc -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32 -lopengl32 -lopengl32 -lmingw32 -lSOIL
INCS = -I"D:/Dev-Cpp/MinGW32/include" -I"D:/Dev-Cpp/MinGW32/lib/gcc/mingw32/4.7.2/include"
CXXINCS = -I"D:/Dev-Cpp/MinGW32/include" -I"D:/Dev-Cpp/MinGW32/lib/gcc/mingw32/4.7.2/include" -I"D:/Dev-Cpp/MinGW32/lib/gcc/mingw32/4.7.2/include/c++"
BIN = Project1.exe
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
Untitled2.o: Untitled2.cpp
$(CPP) -c Untitled2.cpp -o Untitled2.o $(CXXFLAGS)
Compilation log:
Compiling project changes...
--------
- Project Filename: D:\Desktop Files\Programming Stuff\C++\C++ Projects\project examples\etchasketch\Project1.dev
- Compiler Name: MinGW GCC 4.7.2 32-bit Release
Building makefile...
--------
- Filename: D:\Desktop Files\Programming Stuff\C++\C++ Projects\project examples\etchasketch\Makefile.win
Processing makefile...
--------
- Makefile Processor: D:\Dev-Cpp\MinGW32\bin\mingw32-make.exe
- Command: mingw32-make.exe -f "D:\Desktop Files\Programming Stuff\C++\C++ Projects\project examples\etchasketch\Makefile.win" all
g++.exe Untitled2.o -o Project1.exe -L"D:/Dev-Cpp/MinGW32/lib" -L"D:/Dev-Cpp/MinGW32/mingw32/lib" -static-libstdc++ -static-libgcc -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32 -lopengl32 -lmingw32 -Bstatic -lSOIL
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x3e): undefined reference to `glGetString#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x72): undefined reference to `glGetString#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0xbe): undefined reference to `glGetString#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0xf2): undefined reference to `glGetString#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x115): undefined reference to `glGetString#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x15e): more undefined references to `glGetString#4' follow
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x1d1): undefined reference to `wglGetProcAddress#4'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x5e2): undefined reference to `glTexImage2D#36'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x66a): undefined reference to `glTexImage2D#36'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x84f): undefined reference to `glDeleteTextures#8'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0xdf8): undefined reference to `glReadPixels#28'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x100d): undefined reference to `glGetIntegerv#8'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x1427): undefined reference to `glTexImage2D#36'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x15a8): undefined reference to `glTexImage2D#36'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x161a): undefined reference to `glTexImage2D#36'
D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o):SOIL.c:(.text+0x188c): undefined reference to `glTexImage2D#36'
d:/dev-cpp/mingw32/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: D:/Dev-Cpp/MinGW32/lib/libSOIL.a(SOIL.o): bad reloc address 0x0 in section `.data'
d:/dev-cpp/mingw32/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
D:\Desktop Files\Programming Stuff\C++\C++ Projects\project examples\etchasketch\Makefile.win:25: recipe for target 'Project1.exe' failed
mingw32-make.exe: *** [Project1.exe] Error 1
Compilation results...
--------
- Errors: 1
- Warnings: 0
- Compilation Time: 0.25s
Thank you so much Patrick Stewart for helping me figure this out.
Oddly enough, when I didn't have the -Bstatic, there was the only one error. When I followed what you said about the compilation log, it gave more errors that I did not know were there. I Googled it and found out an answer from this site: http://www.gamedev.net/topic/614336-soil-linker-errors/
that the -lSOIL had to be before the -lopengl32.
This is weird in my opinion, but it is a solution.
This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 6 years ago.
I have a project with several .cpp and .h files, and I am trying to split the source into core / generic stuff, and application specific code. Based on that, I separated the code files into a Common folder and compiled it as a library. Below is the Makefile for that lib:
CFLAGS=-std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
OUTPUTFILE=libcommon.a
all: $(OUTPUTFILE)
$(OUTPUTFILE): $(OBJECTS)
ar rcs $(OUTPUTFILE) $(OBJECTS)
.cpp.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $# $(GPROF)
clean:
rm -f $(OBJECTS) $(OUTPUTFILE)
Then I created a sample main file just to try out the compilation of an app using that library.
Here is the code of the main source file:
#include "../Common/Functions.h"
#include "../Common/Logger.h"
int main() {
Logger::Init(false, false);
Logger::Debug("Test");
string path = Functions::GetAppPath();
Logger::Debug("App Path: ", path.c_str());
return 0;
}
The functions file that is being referenced uses boost, and here is the makefile for this app that uses the library:
CC=g++
CFLAGS=-Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
LDFLAGS=-I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common
LIBS=-lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=testApp
GPROF=-pg
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $# $(LIBS) $(GPROF)
.cpp.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $# $(GPROF)
clean:
rm -rf *o $(OBJECTS)
When I try to compile, I get the following errors, complaining about undefined references to boost:
g++ -Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib main.cpp -o main.o -pg
g++ -I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common main.o -o testApp -lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon -pg
../Common/libcommon.a(Functions.o): In function `Functions::GetAppPath()':
/media/software/Robots/Common/Functions.cpp:43: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::initial_path()':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:583: undefined reference to `boost::filesystem::detail::initial_path(boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::system_complete(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:655: undefined reference to `boost::filesystem::detail::system_complete(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `unsigned short boost::date_time::month_str_to_ushort<boost::gregorian::greg_month>(std::string const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/date_time/date_parsing.hpp:67: undefined reference to `boost::gregorian::greg_month::get_month_map_ptr()'
../Common/libcommon.a(Logger.o): In function `Logger::Cleanup()':
/media/software/Robots/Common/Logger.cpp:84: undefined reference to `boost::thread::interrupt()'
../Common/libcommon.a(Logger.o): In function `Logger::InitFile(std::string, bool, std::_Ios_Openmode)':
/media/software/Robots/Common/Logger.cpp:186: undefined reference to `boost::filesystem::path::parent_path() const'
/media/software/Robots/Common/Logger.cpp:187: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Logger.o): In function `Logger::Process()':
/media/software/Robots/Common/Logger.cpp:241: undefined reference to `boost::this_thread::interruption_point()'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data_base::thread_data_base()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/pthread/thread_data.hpp:143: undefined reference to `vtable for boost::detail::thread_data_base'
../Common/libcommon.a(Logger.o): In function `boost::thread::start_thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:179: undefined reference to `boost::thread::start_thread_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::thread::~thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:254: undefined reference to `boost::thread::detach()'
../Common/libcommon.a(Logger.o): In function `boost::thread::get_id() const':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:741: undefined reference to `boost::thread::native_handle()'
../Common/libcommon.a(Logger.o): In function `boost::thread::join()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:767: undefined reference to `boost::thread::join_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::exists(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:404: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::create_directories(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:523: undefined reference to `boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data<void (*)()>::~thread_data()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:90: undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
../Common/libcommon.a(Logger.o):(.rodata._ZTIN5boost6detail11thread_dataIPFvvEEE[_ZTIN5boost6detail11thread_dataIPFvvEEE]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
collect2: error: ld returned 1 exit status
Needless to say that the project as a whole compiles with no issue.
This is my first attempt at building a c++ linux library and using it in another application, so I might be doing a rookie mistake, so bear that in mind.
Help is very much appreciated.
Thank you.
The order of libraries on the command line is significant to the linker. It processes libraries from left to right, resolving as-yet unresolved references already known to it against any functions provided by the current library.
Moreover, and particularly relevant here, if a given library contains references to functions that it does not itself provide then the linker does not resolve those against libraries it has already processed. That's why you have unresolved references: you have -lcommon last among your libraries, so function references therein will be resolved against only the C standard library.
It is valid to list libraries more than once in the link command, and sometimes that is needed, but in this case I think it makes sense simply to put -lcommon as the first library instead of the last. That will resolve the issue. You can even conceptualize this as putting the library most closely related to the main program closest to it in the link command.