23

Yes this question has been asked before ... I've tried everything mentioned in the previous answers. My setup is really straightforward so this shouldn't be so hard.

I just want to program against mysql using C++. My source code is taken verbatem from the 'hello world' type example here:

http://dev.mysql.com/doc/refman/5.1/en/connector-cpp-examples-complete-example-1.html

I am on Ubuntu 12.10. I am trying:

g++ -Wall -o firsttry_prog -I/usr/include/mysqlcppconn -I/usr/local/boost_1_53_0  -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18 -L/usr/lib/mysqlcppconn -lmysqlcppconn  firsttry.cpp

It compiles (if I use -c option) but won't build, giving me the infamous:

/tmp/ccn768hj.o: In function `main':
firsttry.cpp:(.text+0x3a): undefined reference to `get_driver_instance'

A few details:

  • 'firsttry.cpp' is just what I named the source code file, again taken verbatem from the official example
  • As you can see I AM linking in the mysqlclient library and the mysqlcppconn library. Many times when this question has been asked previously, the answer was to link those.
  • Some other historical answers suggest the sample source code is wrong and that the function in question needs to be in the sql::mysql namespace etc. I am pretty sure the source code is fine. Again, it compiles, and changing the namespaces in the source code just seems to make it worse.

Thank you in advance for any help you can provide.

Ray in NY
  • 351
  • 1
  • 2
  • 10
  • 1
    What's that `-l:libmysqlclient_r.so.18`? Shouldn't it be `-lmysqlclient_r`? – Alexander Shukaev Apr 14 '13 at 03:06
  • Thanks Haroogan. I got that -l: business from [link](http://stackoverflow.com/questions/335928/ld-cannot-find-an-existing-library) - I believe it's just a way of specifying a full file name when a symbolic link in the conventional naming style doesn't exist, as it didn't for me. So if I tried -lmysqlclient_r, it told me it couldn't find -lmysqlclient_r. Based on your feedback I went ahead and made the symbolic link, now I can use -lmysqlclient_r ... and I get the same error about 'get_driver_instance.' Any other thoughts? – Ray in NY Apr 14 '13 at 03:24
  • Try to compile `firsttry.cpp` to `firsttry.o` first, and then link it against those MySQL libraries into the executable. I.e. like this: `g++ -Wall -I/usr/include/mysqlcppconn -I/usr/local/boost_1_53_0 -o firsttry.o firsttry.cpp` and `g++ firsttry.o -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18 -L/usr/lib/mysqlcppconn -lmysqlcppconn -o firsttry`. – Alexander Shukaev Apr 14 '13 at 03:29
  • That's interesting ... as I noted above it still compiles into the .o file no problem. When I try to link it though (your second command, although I've now tried several variations with the same result) I get several dozen errors, all in this form: `/usr/lib/mysqlcppconn/libmysqlcppconn.so: undefined reference to mysql_stmt_execute@libmysqlclient_18'` and so on, all undefined references in libmysqlcppconn... why would that be? – Ray in NY Apr 14 '13 at 04:01
  • Change the order: `-lmysqlcppconn -l:libmysqlclient_r.so.18`. – Alexander Shukaev Apr 14 '13 at 04:03
  • thanks ... tried that, no difference. BTW I've also tried adding mysql_config --cflags --libs as suggested [link](http://stackoverflow.com/questions/13348395/resolving-undefined-references-with-mysql-c-connector?rq=1) ... doesn't work (didn't for that person either ;-)) – Ray in NY Apr 14 '13 at 04:13
  • UPDATE - okay, I can get it to run using the statically linked library `-lmysqlcppconn-static` instead of `-lmysqlcppconn` That serves my immediate need but I'm still left extremely curious why the dynamic version doesn't work, I feel like there is something fundamental I must be missing ... – Ray in NY Apr 14 '13 at 04:17
  • You might want to check whether the `get_driver_instance` is actually present in the dynamic version, i.e. does it actually export this symbol? You can do so by running `nm libmysqlcppconn.so` – Alexander Shukaev Apr 14 '13 at 04:19
  • It works for me on Mac OS with this command: `g++ firsttry.cpp -I/opt/local/include/mysql5-connector-cpp/driver -I/opt/local/include/mysql5-connector-cpp -L/opt/local/lib/mysql5-connector-cpp -lmysqlcppconn` ... if I omit `-lmysqlcppconn` then I get a similar undefined-symbol warning to what's reported here. Maybe see if your static library and dynamic one are being found in the same directory. – John Zwinck Apr 14 '13 at 07:17

4 Answers4

33

So I have now had this problem for a week now and I became very frustrated with it as well. I just now was able to finally build a program that does nothing except login to mysql and I literally squealed with joy. Here is what I have and I hope it helps.

I first compiled the c++ connector library from source but after a while I thought maybe I did something wrong so I then just used apt to get it with:

sudo apt-get install  libmysqlcppconn-dev

And here is my simple tester source file "tester.cpp"

#include <stdlib.h>
#include <iostream>
#include <mysql_connection.h>
#include <driver.h>
#include <exception.h>
#include <resultset.h>
#include <statement.h>

using namespace sql;
int main(void){
  sql::Driver *driver;
  sql::Connection *con;

  driver = get_driver_instance();
  con = driver->connect("tcp://127.0.0.1:3306","root","YOURPASSWORD");
  
  return 0;
}

And finally g++ compile command:

g++ -Wall -I/usr/include/cppconn -o testapp tester.cpp -L/usr/lib -lmysqlcppconn

This worked for me and I hope it helps you solve your problem!

273K
  • 29,503
  • 10
  • 41
  • 64
d3l
  • 346
  • 3
  • 2
  • 1
    Yes- that worked! Amazing thank you. Specifically, what worked was getting the library via `apt-get install` instead of either (A) trying to build it from the source code (didn't work for you) or even (B) downloading the libraries from the MySQL site and placing in them folders myself (didn't work for me.) Thank you so much! – Ray in NY Apr 15 '13 at 03:36
  • While this question is solved, I am still left with a burning curiosity about what I was doing wrong in the first place. Granted I am somewhat rusty on my C++ and new to linux, so maybe this was a real newby mistake. My best guess is it must have something to do with directory locations ... `apt-get install` placed the _mysqlcppconn_ right in the root of /usr/lib while I had in a subdirectory etc. But shouldn't that be okay, as long as I was specifying the full path when I built the program, which I was? Even at the compile stage, it was telling me I needed to also specify Boost, etc... – Ray in NY Apr 15 '13 at 03:42
  • Great solution, even I need to first remove existing libmysqlcppconn-dev and then followed what you said. works gread after two days of effort! I dont know what mysql people have kept on they documentation.. – Catty Sep 06 '13 at 15:01
  • @RayinNY Did you run `ldconfig` after downloading the libraries and placing them in those folders? – Chandranshu Nov 12 '13 at 11:33
  • Thankyou So much :) All I needed was the last line :P (compiling) – Severus Tux Oct 22 '16 at 10:05
  • Dude, I can't tell you how frustrating this was. Thanks so much for the notes here! – Phyllis Sutherland Nov 14 '16 at 18:08
9

For me simply swapping the order of the last two arguments fixed this problem. I don't know why but the linker is able to find the function get_driver_instance if I specify the -lmysqlcppconn option at the end after the source file.

g++ -Wall -o firsttry_prog -I/usr/include/mysqlcppconn -L/usr/lib/mysqlcppconn firsttry.cpp -lmysqlcppconn

Also note that I took out the following options as I think they are redundant

-I/usr/local/boost_1_53_0  -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18
Tarun
  • 639
  • 6
  • 3
  • 1
    Yes, this worked for me too, literally as described moving the link flag to the end of the command without removing any additional flags - Does anyone understand how? – Brizee Jun 02 '16 at 12:25
  • Same here! Super annoying, but so so happy I sorted it out, thanks to you! But now that it's working, as @Brizee asked, does anyone have any clue of why this needs to be like this? If anyone could point to some piece of documentation, that would be wonderful. – DanielM Jun 20 '18 at 20:51
7

In case you are as forgetful as me and didn't link the library in CMakeLists.txt:

target_link_libraries(<target> mysqlcppconn)
nakajuice
  • 691
  • 1
  • 11
  • 23
  • 1
    Hi, what is `` supposed to be? I am also using CMakeLists.txt, and your answer is the most likely one that could save me. – Haohan Wang Jan 25 '16 at 02:54
  • Target is the name you used after add_executable(myproj). In this case myproj. https://schneide.wordpress.com/2016/04/08/modern-cmake-with-target_link_libraries/ – user584583 Jul 28 '17 at 04:02
2

If all the paths are included throw param -I. You would see whether there is a problem if you compile like this:

g++ -g  -o0  -I/usr/local/include -I/usr/local/boost/include -c main.cpp -o main.o
g++ -g  -o0 -L/usr/local/lib -L/usr/local/mysql/lib -lmysqlcppconn  main.o  -o test  

the problem will appear:

main.o: In function `main':
/home/huangxw/workspace/public/soal/test/main.cpp:165: undefined reference to `get_driver_instance'
collect2: ld returned 1 exit status

Now you must adjust the order of -lmysqlcppconn and main.o:

g++ -g  -o0  -I/usr/local/include -I/usr/local/boost/include -c main.cpp -o main.o
g++ -g  -o0 -L/usr/local/lib -L/usr/local/mysql/lib main.o  -o test  -lmysqlcppconn

That is all!! The reason is simple. You can find out using the web or ask me to elaborate.

Chandranshu
  • 3,669
  • 3
  • 20
  • 37
  • 1
    I'm confused on two issues. 1) why does this make a difference and 2) how am I supposed to specify that it comes AFTER my "main.o" using autotools/automake ? – Discordanian Aug 29 '14 at 13:43