5

I have some "simple" code in C++ to connect to a MySQL database (which is localhost, btw).

#include <stdlib.h>
#include <iostream>
#include "mysql/include/mysql/jdbc.h"


using namespace sql;


int main() {

  std::cout << "Test"<< std::endl;

  try {
   sql::Driver *myDriver;
   sql::Connection *myConn;
   sql::Statement *myStmt;
   sql::ResultSet *myRes;

   myDriver = sql::mysql::get_mysql_driver_instance();
   myConn = myDriver ->connect("tcp://127.0.0.1", "root", "");
   myConn->setSchema("root");

   myStmt = myConn->createStatement();
   myRes = myStmt->executeQuery("SELECT 'Hello World' AS _message");

   while (myRes->next()) {
     std::cout << myRes->getString("_message") << std::endl;
   }
   delete myRes;
   delete myStmt;
   delete myConn;

 } catch (sql::SQLException &e) {
   std::cout << "Filed connect to Database" << std::endl;
   std::cout << "Error: " << e.what() << std::endl;
   std::cout << "Error code: " << e.getErrorCode() << std::endl;
 }
}

The file jdbc.h is just a lot of different #include for header files.

I use 2 commands to compile: g++ -c -Wall -I/usr/include/cppconn connect.cpp -o connect.o and g++ -lm -L/usr/lib/x86_64-linux-gnu -lmysqlcppconn connect.o -o connect

Which produced this linking error:

/usr/bin/ld: connect.o: in function "check_lib()':
connect.cpp:(.text+0x2c): undefined reference to `check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)"
/usr/bin/ld: connect.cpp:(.text+0x77): undefined reference to "check(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)"
/usr/bin/ld: connect.o: in function `sql::mysql::get_driver_instance_by_name(char const*)':
connect.cpp:(.text+0xfa): undefined reference to   "sql::mysql::_get_driver_instance_by_name(char const*)"
collect2: error: ld returned 1 exit status

Which I kinda resolved using this answer: https://stackoverflow.com/a/33395489/14814564 , essentially by putting #define _GLIBCXX_USE_CXX11_ABI 0 at the top of the file, which after compilation, produces this linking error:

/usr/bin/ld: connect.o: in function "check_lib()':
connect.cpp:(.text+0x2c): undefined reference to "check(std::string const&)'
/usr/bin/ld: connect.cpp:(.text+0x77): undefined reference to "check(std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > const&)'
/usr/bin/ld: connect.o: in function `sql::mysql::get_driver_instance_by_name(char const*)':
connect.cpp:(.text+0xfa): undefined reference to "sql::mysql::_get_driver_instance_by_name(char const*)'
collect2: error: ld returned 1 exit status

Why does this linking error keep popping up and how do I resolve it?

14
  • 1
    You're not linking something, that needs to be linked against. This error is avoidable by using cmake's find_package and link_libraries for example. I strongly recommend to not command line your compiling/linking manually (at least for projects which consist of more than 1 source file or use more than zero 3rd party libraries). Commented Aug 11, 2021 at 8:46
  • 1
    -lmysqlcppconn connect.o -> connect.o -lmysqlcppconn? Commented Aug 11, 2021 at 8:51
  • 1
    @KamilCuk no changes at all :/ Commented Aug 11, 2021 at 8:58
  • 2
    Are you sure -lmysqlcppconn locates at the path /usr/lib/x86_64-linux-gnu ?? Commented Aug 11, 2021 at 9:47
  • 2
    @KostasM That's why it does not always work well when you try something You need to get better. The linker will try to find the libmysqlcppconn.so in the library search path specified by -L as well as in the standard paths Commented Aug 11, 2021 at 10:43

2 Answers 2

1

I had the same problem, I solved it by building a Makefile`

 MYSQL_CONCPP_DIR = ./mysql
 CPPFLAGS=-I $(MYSQL_CONCPP_DIR)/include/mysql -L $(MYSQL_CONCPP_DIR)/lib64
 LDLIBS=-lmysqlcppconn
 CXXFLAGS=-std=c++11
 out.exe:test.cpp
     g++ test.cpp ${LDLIBS} ${CXXFLAGS} ${CPPFLAGS} -o out.exe

You have there #include "mysql/include/mysql/jdbc.h"

In my case include needs to be done like this` #include <jdbc.h>

Sign up to request clarification or add additional context in comments.

1 Comment

In this case the 'libmysqlcppconn.so' is missing (see comments to question), so the LDLIBS probably would have to be changed.
1

Compile your application program using an older GCC, if you can, or compile the Connector/C++ library with the same compiler you use for your application.

After a lot of googling, a comment in some random issue tracker prompted me to try an older compiler.

I work at an HPC site, where we have Environment Modules for GCC, so I was able to load older versions at will. GCC 5.2.0 is what finally worked for me, despite the fact that the INFO_BIN that came with MySQL Connector/C++ 8.0.29 says they compiled it with GCC 8.3.1.

Everything from (circa) gcc/5.4.0 and on is a no-go:

$ module list
Currently Loaded Modulefiles:
  1) mysql-connector-cplusplus/8.0.29

$ module load gcc/4.9.0
$ g++ -std=c++11 $CPPFLAGS $CXXFLAGS -lmysqlcppconn simple.cpp  # works

$ module unload gcc; module load gcc/5.2.0
$ g++ -std=c++11 $CPPFLAGS $CXXFLAGS -lmysqlcppconn simple.cpp  # works

$ module unload gcc; module load gcc/5.4.0
$ g++ -std=c++11 $CPPFLAGS $CXXFLAGS -lmysqlcppconn simple.cpp
/tmp/ccs8BopW.o: In function `check_lib()':
simple.cpp:(.text+0x1d): undefined reference to `check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
⋮

$ module unload gcc; module load gcc/9.3.0
$ g++ -std=c++11 $CPPFLAGS $CXXFLAGS -lmysqlcppconn simple.cpp
/tmp/cc3S5qs2.o: In function `check_lib()':
simple.cpp:(.text+0x1d): undefined reference to `check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
⋮
collect2: error: ld returned 1 exit status

My understanding of the problem is vague, but based on that issue comment, some discussions in various C++ forums, and the GCC documentation, it looks like the application binary interface for strings changed in GCC 5.1.

Maybe Oracle compiled that version of Connector/C++ with the -D_GLIBCXX_USE_CXX11_ABI=0 that you see mentioned in various places. Maybe this problem went away in the very next version of the connector library. All speculation on my part. At least I know what's going on and have a workaround, though. :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.