I am working with Opencv-2.1 on arm-linux. I am using arm-linux-g++ compiler. I ran in to a strange error during linking. Before talking about the error, I will post my make commands
CC = arm-linux-g++
COMPILEFLAGS = -Wall -fPIC -c -O2 -I./
OUT_DLL = libLensFinder.so
DLL_FLAGS = -shared -o
OBJS = SegmentRegions.o
OBJS2 = EdgeDetection.o
OBJS3 = AnalyseRegions.o
OBJS4 = global.o
LINK_FLAGS = -L./ -lLensFinder
LINK_FLAGS_2 = -L./ -lTwoX
INCPATH = -I/home/zwang/ravi/opencv_include21/opencv/ -I.
all :
$(CC) $(COMPILEFLAGS) $(INCPATH) global.cpp -o global.o
$(CC) $(COMPILEFLAGS) $(INCPATH) EdgeDetection.cpp -o EdgeDetection.o
$(CC) $(COMPILEFLAGS) $(INCPATH) SegmentRegions.cpp -o SegmentRegions.o
$(CC) $(COMPILEFLAGS) $(INCPATH) AnalyseRegions.cpp -o AnalyseRegions.o
$(CC) $(OBJS) $(OBJS2) $(OBJS3) $(OBJS4) $(DLL_FLAGS) ./$(OUT_DLL) -L/home/zwang/ravi/opencv_include21/lib -lcvaux -lcxcore -lhighgui -lcv -lml -lcxts -lrt
$(CC) $(COMPILEFLAGS) $(INCPATH) sample.cpp
#$(CC) $(LINK_FLAGS) sample.o -o sample
$(CC) $(LINK_FLAGS) $(LINK_FLAGS_2) sample.o -o sample
Everything works fine till the end. During the last command i.e., while creating executable file I am getting the following error.
arm-linux-g++ -L./ -lLensFinder -L./ -lTwoX sample.o -o sample
.//libLensFinder.so: undefined reference to `spotrs_'
.//libLensFinder.so: undefined reference to `cvGetOptimalDFTSize'
.//libLensFinder.so: undefined reference to `dgels_'
.//libLensFinder.so: undefined reference to `dgelsd_'
.//libLensFinder.so: undefined reference to `dgesdd_'
.//libLensFinder.so: undefined reference to `cvMulSpectrums'
.//libLensFinder.so: undefined reference to `sgesdd_'
.//libLensFinder.so: undefined reference to `sgetri_'
.//libLensFinder.so: undefined reference to `cvDFT'
.//libLensFinder.so: undefined reference to `dgesv_'
.//libLensFinder.so: undefined reference to `dgetrf_'
.//libLensFinder.so: undefined reference to `dsyevr_'
.//libLensFinder.so: undefined reference to `sgels_'
.//libLensFinder.so: undefined reference to `spotrf_'
.//libLensFinder.so: undefined reference to `sgetrf_'
.//libLensFinder.so: undefined reference to `dpotrf_'
.//libLensFinder.so: undefined reference to `dpotri_'
.//libLensFinder.so: undefined reference to `sgesv_'
.//libLensFinder.so: undefined reference to `ssyevr_'
.//libLensFinder.so: undefined reference to `dpotrs_'
.//libLensFinder.so: undefined reference to `sgelsd_'
.//libLensFinder.so: undefined reference to `spotri_'
.//libLensFinder.so: undefined reference to `dgetri_'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Two of the undefined references are cvMulSpectrums' andcvGetOptimalDFTSize', which I guess is due to opencv. And I have no clue on other undefined reference. I think I have linked every library. But still can't understand how to solve this. Any suggestions? FYI, the code is working on visual studio.
Those symbols are defined in the libopencv_core library file.
Notice how the command arm-linux-g++ -L./ -lLensFinder -L./ -lTwoX sample.o -o sample doesn't link sample with any opencv library, so it makes sense that the linking process complains about it.
You probably should adjust your build to do something like:
arm-linux-g++ sample.o -o sample -L./ -lLensFinder -L./ -lTwoX -L/home/zwang/ravi/opencv_include21/lib -lcvaux -lcxcore -lhighgui -lcv -lml -lcxts -lrt
Related
I am trying to compile an app with static curl and i it seems OpenSSL is not properly linked.
COMPILE CMD:
$(CXX) $(CXXFLAGS) program1.cpp /opt/curl-7.62.0/lib/libcurl.a /opt/openssl-1.1.1a/lib/libcrypto.a -o program1 -L/opt/curl-7.62.0/ -L/opt/openssl-1.1.1a/ -Wwrite-strings -fpermissive -static-libstdc++ -lcrypto -lssl -lcurl -Wl,-Bstatic -lidn2 -lrt -lz -Wl,-Bdynamic -ldl -lpthread
CURL:
rm -rf /opt/curl-7.62.0/*; ./configure --prefix=/opt/curl-7.62.0 --with-pic --disable-shared --enable-static --with-libidn=/opt/libidn2-2.0.4 --with-ssl=/opt/openssl-1.1.1a --without-librtmp --without-gnutls --without-nss --without-libssh2 --with-zlib=/opt/zlib-1.2.11 --without-winidn --disable-rtsp --disable-ldap --disable-ldaps --disable-ipv6 LIBS=-ldl; make -j 8; make install; ls -al /opt/curl-7.62.0/;
OPENSSL :
./config --prefix=/opt/openssl-1.1.1a -fPIC -static; make; make install;
Errors :
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `Curl_ossl_sha256sum':
openssl.c:(.text+0x13c): undefined reference to `EVP_MD_CTX_new'
openssl.c:(.text+0x177): undefined reference to `EVP_MD_CTX_free'
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `Curl_ossl_md5sum':
openssl.c:(.text+0x1cc): undefined reference to `EVP_MD_CTX_new'
openssl.c:(.text+0x207): undefined reference to `EVP_MD_CTX_free'
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `Curl_ossl_version':
openssl.c:(.text+0xb54): undefined reference to `OpenSSL_version_num'
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `servercert':
openssl.c:(.text+0x19d0): undefined reference to `X509_get0_notBefore'
openssl.c:(.text+0x1a2c): undefined reference to `X509_get0_notAfter'
openssl.c:(.text+0x1b29): undefined reference to `OPENSSL_sk_num'
openssl.c:(.text+0x1b7f): undefined reference to `OPENSSL_sk_value'
openssl.c:(.text+0x1c77): undefined reference to `X509_get_X509_PUBKEY'
openssl.c:(.text+0x1caf): undefined reference to `X509_get_X509_PUBKEY'
openssl.c:(.text+0x1f22): undefined reference to `OPENSSL_sk_num'
openssl.c:(.text+0x1fa9): undefined reference to `OPENSSL_sk_value'
openssl.c:(.text+0x207e): undefined reference to `X509_get_version'
openssl.c:(.text+0x21f4): undefined reference to `X509_get_X509_PUBKEY'
openssl.c:(.text+0x2272): undefined reference to `X509_get0_extensions'
openssl.c:(.text+0x227d): undefined reference to `OPENSSL_sk_num'
openssl.c:(.text+0x22f1): undefined reference to `OPENSSL_sk_num'
openssl.c:(.text+0x2303): undefined reference to `OPENSSL_sk_value'
openssl.c:(.text+0x2673): undefined reference to `X509_get0_notBefore'
openssl.c:(.text+0x26cb): undefined reference to `X509_get0_notAfter'
openssl.c:(.text+0x2755): undefined reference to `EVP_PKEY_get0_RSA'
openssl.c:(.text+0x276f): undefined reference to `RSA_get0_key'
openssl.c:(.text+0x2ac5): undefined reference to `ASN1_STRING_get0_data'
openssl.c:(.text+0x2b6c): undefined reference to `EVP_PKEY_get0_DSA'
openssl.c:(.text+0x2b8c): undefined reference to `DSA_get0_pqg'
openssl.c:(.text+0x2b9e): undefined reference to `DSA_get0_key'
openssl.c:(.text+0x2c44): undefined reference to `EVP_PKEY_get0_DH'
openssl.c:(.text+0x2c64): undefined reference to `DH_get0_pqg'
openssl.c:(.text+0x2c76): undefined reference to `DH_get0_key'
openssl.c:(.text+0x2d15): undefined reference to `ASN1_STRING_get0_data'
openssl.c:(.text+0x2d3d): undefined reference to `ASN1_STRING_get0_data'
openssl.c:(.text+0x32aa): undefined reference to `ASN1_STRING_get0_data'
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `ossl_connect_step2':
openssl.c:(.text+0x3461): undefined reference to `SSL_get_client_random'
openssl.c:(.text+0x3476): undefined reference to `SSL_SESSION_get_master_key'
/opt/curl-7.69.1/lib/libcurl.a(libcurl_la-openssl.o): In function `ossl_connect_step1':
openssl.c:(.text+0x3f51): undefined reference to `TLS_client_method'
openssl.c:(.text+0x40b3): undefined reference to `SSL_CTX_set_options'
openssl.c:(.text+0x545c): undefined reference to `OPENSSL_sk_pop_free'
openssl.c:(.text+0x55fe): undefined reference to `OPENSSL_sk_pop'
openssl.c:(.text+0x5640): undefined reference to `OPENSSL_sk_num'
openssl.c:(.text+0x566c): undefined reference to `OPENSSL_sk_pop_free'
collect2: error: ld returned 1 exit status
Makefile:11: recipe for target 'main' failed
....
What could it be?
Thank you.
I'm fairly certain that libcurl depends on the SSL/Crypto binaries, not the other way around.
And I believe the gnu linker doesn't "go back" in the library list to resolve missing symbols, only forward in the list. Hence, this order of library includes:
-lcrypto -lssl -lcurl
Should be this:
-lcurl -lssl -lcrypto
Another option - redundantly append -lcrypto -lssl and to the end of the build line. That is:
$(CXX) $(CXXFLAGS) program1.cpp /opt/curl-7.62.0/lib/libcurl.a /opt/openssl-1.1.1a/lib/libcrypto.a -o program1 -L/opt/curl-7.62.0/ -L/opt/openssl-1.1.1a/ -Wwrite-strings -fpermissive -static-libstdc++ -lcrypto -lssl -lcurl -Wl,-Bstatic -lidn2 -lrt -lz -Wl,-Bdynamic -ldl -lpthread -lcrypto -lssl
If any of the above works, you can experiment with link library order.
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.
I'm trying to compile the following c++ code that implements Context Tree Switching (More info on the download page):
Zip archive, 0.2 MB
which requires some boost libraries. I download the latest version from boost.org and built all libraries that needed building following the instructions on the website. I also modified the makefile included in the archive to add the boost lib path and boost_system, but I still get an error. Here's the makefile i'm using:
PROGRAM = cts
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CFLAGS = -Wall
LDFLAGS = -lboost_program_options -lboost_filesystem -lboost_system
$(PROGRAM): $(OBJECTS) Makefile
g++ $(CFLAGS) -L/home/users/mnembrini/opt/boost/lib $(LDFLAGS) -o $(PROGRAM) $(OBJECTS)
# Include known dependecies from -MMD
#-include $(OBJECTS:.o=.d)
%.o: %.cpp
g++ -MMD $(CFLAGS) -I/home/users/mnembrini/opt/boost/include -c $<
clean:
rm -f $(OBJECTS) *.d
.PHONY: clean
where boost is in ~/opt/boost (constains lib and include subdir). And here's the linking error:
mnembrini#meem:~/src/cts-v1 $ make
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c ac.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c cts.cpp
cts.cpp: In member function ‘virtual void SwitchingTree::update(bit_t)’:
cts.cpp:402:12: warning: variable ‘snc’ set but not used [-Wunused-but-set-variable]
cts.cpp: In member function ‘virtual double SwitchingTree::prob(bit_t)’:
cts.cpp:432:12: warning: variable ‘snc’ set but not used [-Wunused-but-set-variable]
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c ctw.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c icsilog.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c main.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c PowFast.cpp
g++ -Wall -L/home/users/mnembrini/opt/boost/lib -lboost_program_options -lboost_filesystem -lboost_system -o cts ac.o cts.o ctw.o icsilog.o main.o PowFast.o
cts.o: In function `__static_initialization_and_destruction_0(int, int)':
cts.cpp:(.text+0x1743): undefined reference to `boost::system::generic_category()'
cts.cpp:(.text+0x174f): undefined reference to `boost::system::generic_category()'
cts.cpp:(.text+0x175b): undefined reference to `boost::system::system_category()'
ctw.o: In function `__static_initialization_and_destruction_0(int, int)':
ctw.cpp:(.text+0xfcf): undefined reference to `boost::system::generic_category()'
ctw.cpp:(.text+0xfdb): undefined reference to `boost::system::generic_category()'
ctw.cpp:(.text+0xfe7): undefined reference to `boost::system::system_category()'
main.o: In function `showHelp()':
main.cpp:(.text+0x1c): undefined reference to `boost::program_options::operator<<(std::basic_ostream<char, std::char_traits<char> >&, boost::program_options::options_description const&)'
main.o: In function `initOptions(int, char**, boost::program_options::variables_map&)':
main.cpp:(.text+0x10f): undefined reference to `boost::program_options::options_description::add_options()'
main.cpp:(.text+0x129): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, char const*)'
main.cpp:(.text+0x13e): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x153): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x166): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x1d6): undefined reference to `boost::program_options::store(boost::program_options::basic_parsed_options<char> const&, boost::program_options::variables_map&, bool)'
main.cpp:(.text+0x200): undefined reference to `boost::program_options::notify(boost::program_options::variables_map&)'
main.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x1f13): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x1f1f): undefined reference to `boost::system::generic_category()'
[snip (2-3 screens like above)]
collect2: ld returned 1 exit status
make: *** [cts] Error 1
I'm using Gcc 4.6.3 on Ubuntu 12.04 64bit.
Place all the libraries after all the object files within the command line. The order is important here, unlike on some other operating systems.
You need to (just like n.m earlier wrote) make sure you have the correct order of the linking.
Basically some implementations care about what order you link object but also libraries.
If you link a library that hasnt yet been referenced by previous code it will be discarded. I remember coming up with a solution to hack in different (versions of) libraries in a program by referencing the same symbol but in an object linked after the first one and then re-link another library version:
-lyourprojwantingv1 -llibraryofv1 -lyourprojwantingv2 -llibraryofv2
Personally i think this is all just madness! (All of it!)
I'm current working on a C++ that I edit locally on my Mac but run on an Ubuntu server. I always make sure that the code compiles on my mac before uploading it to the server to compile it there, where I have to use a makefile to link with libraries that are installed in my local directory. Basically, I had edited a significant portion of my code, found that it compiled on my mac, and uploaded it to the server to compile, but it doesn't compile! Luckily, I had a backup version of the code, so I tried that on the server, and that won't compile anymore either! In between the last time I knew that my code compiled on the server and now, I know that they ran some updates, but that's all I can think of that's different. For reference, here's my make file:
LOCAL_INCLUDE = /home/schraiber/.local/include
LOCAL_LIB = /home/schraiber/.local/lib
CXXFLAGS = -I$(LOCAL_INCLUDE)
CXX_LDFLAGS = -L$(LOCAL_LIB) -lgsl -lm -lgslcblas -lpthread
CoalHMMgf: main.o IOUtilities.o parameters.o Algorithms.o Optimization.o probabilities.o RNGUtilities.o Data.o ThreadData.h
g++ $(CXXFLAGS) $(CXX_LDFLAGS) main.o IOUtilities.o parameters.o Algorithms.o Optimization.o probabilities.o RNGUtilities.o Data.o -o CoalHMMgf
main.o: main.cpp IOUtilities.h parameters.h Algorithms.h Optimization.h probabilities.h ThreadData.h Data.h
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c main.cpp
IOutilities.o: IOUtilities.h IOUtilities.cpp parameters.h data.h
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c IOUtilities.cpp
parameters.o: parameters.h parameters.cpp
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c parameters.cpp
Algorithms.o: Algorithms.h Algorithms.cpp
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c Algorithms.cpp
Optimization.o: Optimization.h Optimization.cpp Algorithms.h parameters.h probabilities.h RNGUtilities.h ThreadData.h IOUtilities.h
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c Optimization.cpp
probabilities.o: probabilities.h probabilities.cpp parameters.h
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c probabilities.cpp
RNGUtilities.o: RNGUtilities.h RNGUtilities.cpp
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c RNGUtilities.cpp
Data.o: Data.h Data.cpp
g++ $(CXXFLAGS) $(CXX_LDFLAGS) -c Data.cpp
and the error:
g++ -I/home/schraiber/.local/include -L/home/schraiber/.local/lib -lgsl -lm -lgslcblas -lpthread main.o IOUtilities.o parameters.o Algorithms.o Optimization.o probabilities.o RNGUtilities.o Data.o -o CoalHMMgf
main.o: In function `main':
main.cpp:(.text+0xbf1): undefined reference to `pthread_create'
main.cpp:(.text+0xd0e): undefined reference to `pthread_join'
Optimization.o: In function `my_df(gsl_vector const*, void*, gsl_vector*)':
Optimization.cpp:(.text+0x3149): undefined reference to `gsl_vector_alloc'
Optimization.cpp:(.text+0x316b): undefined reference to `gsl_vector_get'
Optimization.cpp:(.text+0x3180): undefined reference to `gsl_vector_set'
Optimization.cpp:(.text+0x31bc): undefined reference to `gsl_vector_get'
Optimization.cpp:(.text+0x31ec): undefined reference to `gsl_vector_set'
Optimization.cpp:(.text+0x323b): undefined reference to `gsl_vector_set'
Optimization.cpp:(.text+0x327e): undefined reference to `gsl_vector_set'
Optimization.cpp:(.text+0x32c9): undefined reference to `gsl_vector_set'
Optimization.o: In function `MHthreaded(void*)':
Optimization.cpp:(.text+0x3489): undefined reference to `gsl_rng_env_setup'
Optimization.cpp:(.text+0x3490): undefined reference to `gsl_rng_default'
Optimization.cpp:(.text+0x360b): undefined reference to `gsl_rng_uniform'
Optimization.cpp:(.text+0x3653): undefined reference to `gsl_ran_gaussian'
Optimization.cpp:(.text+0x3686): undefined reference to `gsl_ran_gaussian'
Optimization.cpp:(.text+0x377f): undefined reference to `gsl_rng_uniform'
RNGUtilities.o: In function `AllocRNG(gsl_rng*&, gsl_rng_type const*, int)':
RNGUtilities.cpp:(.text+0x9a): undefined reference to `gsl_rng_alloc'
RNGUtilities.cpp:(.text+0xba): undefined reference to `gsl_rng_set'
RNGUtilities.o: In function `FreeRNG(gsl_rng*&)':
RNGUtilities.cpp:(.text+0xe3): undefined reference to `gsl_rng_free'
collect2: ld returned 1 exit status
make: *** [CoalHMMgf] Error 1
and just to verify that gsl is installed in the local directory:
schraiber#trump:~/test_rsync$ ls ~/.local/lib
libbpp-core.a libbpp-core.so.2.0.0 libbpp-seq.so.9 libgslcblas.a libgslcblas.so.0 libgsl.so pkgconfig
libbpp-core.so libbpp-seq.a libbpp-seq.so.9.1.0 libgslcblas.la libgslcblas.so.0.0.0 libgsl.so.0 python2.7
libbpp-core.so.2 libbpp-seq.so libgsl.a libgslcblas.so libgsl.la libgsl.so.0.16.0
schraiber#trump:~/test_rsync$ ls ~/.local/include/
Bpp gsl
An interesting thing to note is that my program is also supposed to link with Bpp, and it does that just fine as far as I can tell.
Your "-lfoo" parameters should come last on your "g++" command line. So, for example, make this change in your makefile:
CoalHMMgf: main.o IOUtilities.o parameters.o Algorithms.o Optimization.o probabilities.o RNGUtilities.o Data.o ThreadData.h
g++ $(CXXFLAGS) main.o IOUtilities.o parameters.o Algorithms.o Optimization.o probabilities.o RNGUtilities.o Data.o -o CoalHMMgf $(CXX_LDFLAGS)
Libraries have to be defined on the link line such that the library containing no other references is the very last one. Libraries that depend on code from a second library need to be listed first. They must be listed after the .o files, or else the .o files are assumed to be self-contained and don't need the libraries.
I am in linux. My Makefile file is this
main2: main.cpp
g++ -c $(LIBS) $(CFLAGS) -fPIC main.cpp
g++ -shared main.o -o main.so
Where,
SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)
CC = gcc
COPTS = -g -Wall
CFLAGS = $(SDL_CFLAGS)
LIBS = -lstdc++ -lSDL $(SDL_LDFLAGS) -L/usr/X11R6/lib -lGL -lGLU
which runs
g++ -c -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -fPIC main.cpp
g++ -shared main.o -o main.so
Now, this works without error. main.o and main.so files are produced.
However, when I try to link main.os with python ctypes
from ctypes import * import os
libtest = cdll.LoadLibrary(os.getcwd()+ '/main.so') libtest.main_loop()
libtest.main_loop()
I get this error
>>> libtest = cdll.LoadLibrary(os.getcwd() + '/main.so')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/ctypes/__init__.py", line 431, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python2.6/ctypes/__init__.py", line 353, in __init__
self._handle = _dlopen(self._name, mode)
OSError: /home/atomos/DF/open_gl_client/ctypes_client/main.so: undefined symbol: glEnd
I am not sure if I am creating the linked library correctly. How do I create a linked library that I can load?
Do I have to create a .o and .os file for every library I import from main.cpp or is that taken care of automatically?
I do not understand what the compiler or linker is doing, however it works for a simple example with no imports, but for cpp files which import opengl libraries, it gives that error.
---- Update----
ldd against main.so yields
ldd main.so
linux-gate.so.1 => (0xb7755000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xaf625000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xaf5ff000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xaf4a4000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xaf485000)
/lib/ld-linux.so.2 (0xb7756000)
---- Update ----
I ran g++ without -shared flag in the second compilation step and received this error
g++ main.o -o main.so
main.o: In function `Texture_map_list::add_texture(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
main.cpp:(.text+0xf0fe): undefined reference to `glGenTextures'
main.cpp:(.text+0xf2ba): undefined reference to `glBindTexture'
main.cpp:(.text+0xf2d7): undefined reference to `glTexParameterf'
main.cpp:(.text+0xf2f4): undefined reference to `glTexParameterf'
main.cpp:(.text+0xf310): undefined reference to `glTexParameteri'
main.cpp:(.text+0xf32c): undefined reference to `glTexParameteri'
main.cpp:(.text+0xf365): undefined reference to `gluBuild2DMipmaps'
main.o: In function `init()':
main.cpp:(.text+0xf457): undefined reference to `SDL_Init'
main.cpp:(.text+0xf46d): undefined reference to `SDL_WM_SetCaption'
main.cpp:(.text+0xf472): undefined reference to `SDL_GetVideoInfo'
main.cpp:(.text+0xf480): undefined reference to `SDL_GetError'
main.cpp:(.text+0xf497): undefined reference to `SDL_Quit'
main.cpp:(.text+0xf4e2): undefined reference to `SDL_GL_SetAttribute'
main.cpp:(.text+0xf505): undefined reference to `SDL_SetVideoMode'
main.cpp:(.text+0xf513): undefined reference to `SDL_GetError'
main.cpp:(.text+0xf52a): undefined reference to `SDL_Quit'
main.cpp:(.text+0xf559): undefined reference to `glClearColor'
main.cpp:(.text+0xf565): undefined reference to `glEnable'
main.cpp:(.text+0xf571): undefined reference to `glMatrixMode'
main.cpp:(.text+0xf576): undefined reference to `glLoadIdentity'
main.cpp:(.text+0xf5a2): undefined reference to `gluPerspective'
main.o: In function `process_keypresses()':
main.cpp:(.text+0x10678): undefined reference to `SDL_PollEvent'
main.cpp:(.text+0x109a1): undefined reference to `SDL_PollEvent'
main.o: In function `main_loop':
main.cpp:(.text+0x10d76): undefined reference to `SDL_GetKeyState'
main.cpp:(.text+0x10d9f): undefined reference to `SDL_Quit'
main.o: In function `render()':
main.cpp:(.text+0x10e00): undefined reference to `SDL_GetMouseState'
main.cpp:(.text+0x10e90): undefined reference to `SDL_GetMouseState'
main.cpp:(.text+0x10f94): undefined reference to `glClear'
main.cpp:(.text+0x10fa0): undefined reference to `glMatrixMode'
main.cpp:(.text+0x10fa5): undefined reference to `glLoadIdentity'
main.cpp:(.text+0x11081): undefined reference to `gluLookAt'
main.cpp:(.text+0x11120): undefined reference to `glTranslatef'
main.cpp:(.text+0x1114d): undefined reference to `glRotatef'
main.cpp:(.text+0x1117a): undefined reference to `glRotatef'
main.cpp:(.text+0x1119e): undefined reference to `SDL_GL_SwapBuffers'
main.o: In function `draw_plane(float, float, float)':
main.cpp:(.text+0x111d8): undefined reference to `glColor3f'
main.cpp:(.text+0x111e4): undefined reference to `glBegin'
main.cpp:(.text+0x1120b): undefined reference to `glVertex3f'
....
First, note that this is easier to debug if you don't build a shared library. You are building with -shared so the linker errors don't happen until you dynamically load the library in Python. Turn off -shared while you are debugging, and you will see the errors on the command-line when you try to link:
g++ main.o -o main
main.o: In function `main':
main.cpp:(.text+0x1d): undefined reference to `glBegin'
main.cpp:(.text+0x22): undefined reference to `glEnd'
collect2: ld returned 1 exit status
Now the problem is that you are passing linker arguments to the compiler. I see that you have nicely separated CFLAGS and LIBS in the Makefile. Good. But you are passing both $(LIBS) and $(CFLAGS) on the first line, to build main.o. The LIBS will be ignored on that line, because they are link flags.
On the second line, where you are actually building the final executable, you do not pass $(LIBS), so the program is not linked with libGL or any other libraries.
Therefore, simply fix your makefile thusly:
main2: main.cpp
g++ -c $(CFLAGS) -fPIC main.cpp
g++ -shared main.o $(LIBS) -o main.so
Edit: I have since realised that in GCC, you must always put the libraries after the object files, so I have changed the last line of the makefile accordingly.
Simple:
You are passing the link flags to object compilation step.
Here is what you need:
g++ -c -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT main.cpp
g++ -lstdc++ -lSDL -L/usr/lib -lSDL -L/usr/X11R6/lib -lGL -lGLU -fPIC main.o -o main
Plus you probably don't want to create so file, but a normal executable.