From: Thimble Smith Date: April 2 1999 7:27am Subject: Re: [MySQL] List-Archive: http://lists.mysql.com/mysql/1311 Message-Id: <19990402002759.B15512@desert.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii This is definitely a FAQ, and there are many answers to this in the (recent) mailing list archive. Also, if you don't know what the libmysqlclient.a file is for, you really need to be reading some basic books, reading documentation for your C compiler, or something like that. If you're *learning* C, probably you should start with something more basic than a database application! If you're familiar with C but not with Unix, then I suppose you have a prayer. I'm sorry if I sound a bit burned out on this question, but every time it's asked (that I can remember), the person asking has done no work on his/her own to find the answer, has known nothing about the tools he/she is using, and has not listened to any of the good answers given. So I urge you to break away from your fellows and put forth a good effort - you will be deeply rewarded. That being said, here's an attempt to answer your question. If you need further clarifications, please do ask - as long as you've done your part to understand. On Unix systems, C libraries are typically named libXXXXX.a or libXXXXX.so. A library is a collection of object code modules (typically .o files generated by a C compiler) that is created by an archiver program like 'ar'. You don't need to know that, but I thought it might interest you. Libraries that end in '.a' are static. Libraries that end in '.so' are shared, and are like the DLL files found on lesser systems. Static libraries must be linked into an executable at link time; shared libraries can be loaded and linked into an executable at run time. A benefit of this is that many different executables can link the same shared library, decreasing the size of the executables. OK. So, the libmysqlclient.a file is a static library. It has the definitions for all of the functions you'll need to use to work with the MySQL server. In your programs you will call many MySQL functions, e.g. mysql_init(), mysql_real_connect(), etc. You do not have to write the definitions for those functions (I think that's probably a good thing, wouldn't you agree?). But they have to have definitions! The compiler certainly can't infer what a function should do just from its declaration! So you link your program with the mysqlclient library. Your test.c file (for example) tells the compiler what MySQL functions you want to use. The mysqlclient library tells the compiler what to do when you use those functions. You have two copies of the static mysqlclient library. One is in the work directory of the 'ports' distribution of mysql. It would be good for you to read up on the ports system (FreeBSD has pretty good docs on that). You should not be using things that are under the ports directory - those are files used in building software packages. When you run 'make install' inside the ports/category/app directory for the application you are installing, it copies whatever it needs out of the ports directory into the final installation directory (usually /usr/local/* or /usr/X11R6/*). SO, that explains your two copies - one is a work copy, one is the final installed copy. I usually run 'make clean' after I've run 'make install'; that will remove the work copies so my disk space isn't wasted and so that everything is nice and tidy. Okay, how do we compile our MySQL program? Here's an example: $ ls $ cc -g -Wall test.c -o test test.c: In function `main': test.c:4: `MYSQL' undeclared (first use in this function) test.c:4: (Each undeclared identifier is reported only once test.c:4: for each function it appears in.) test.c:4: `mysql' undeclared (first use in this function) test.c:4: warning: statement with no effect test.c:6: warning: implicit declaration of function `mysql_init' $ Huh? Why is everything undeclared? Well, let's look at the source code to find out. Here it is: $ cat test.c int main() { MYSQL *mysql; mysql_init(mysql); return 0; } $ You need to tell the compiler what the different MySQL symbols mean. You do that by including the MySQL header file, using the standard C preprocessor directive, #include . Here's an example: #include Now let's try to compile again. test.c $ cc -g -Wall test.c -o test test.c:1: mysql.h: No such file or directory $ You need to tell the C compiler where to find the MySQL header file. Every C compiler I know of uses the -I flag to do this. Here's an example: $ cc -g -Wall -I/usr/local/mysql/include/mysql test.c -o test test.c:8: Undefined symbol `_mysql_init' referenced from text segment $ You need the definitions found in the mysqlclient library! In order to use the mysqlclient library with your test.c program, you need to tell your compiler to link your program with the library. Every C compiler I know of uses the -l flag to do this. For example: $ cc -g -Wall -I/usr/local/mysql/include/mysql test.c -lmysqlclient -o test ld: -lmysqlclient: no match $ Oops! What happened? Well, the C compiler needs to be able to read the library in order to use the definitions that are stored in it. AND it needs to find the library in order to read it. It looks in some standard places to find libraries - /usr/lib, /lib, /usr/local/lib, etc. But usually the mysqlclient library is not stored in one of those places. It is usually stored in the same place you have yours stored - in the /usr/local/lib/mysql directory. So you have to tell the compiler to look in that directory for libraries, too. Every C compiler I know of uses the -L flag to do this. Here's an example: $ cc -g -Wall -I/usr/local/mysql/include/mysql test.c -L/usr/local/mysql/lib/mysql -lmysqlclient -o test $ ls test test.c $ Hey, it compiled and linked [see footnote.]! Let's try running it: $ ./test Bus error (core dumped) Ouch! What's that mean? We need to look at the source code (test.c) again. Here it is: $ cat test.c #include int main() { MYSQL *mysql; mysql_init(mysql); return 0; } $ What could be wrong with that? WELL, the problem is that the 'mysql' variable is declared as a pointer to a MYSQL object. But it's never told what MYSQL object it should point at! It's a "garbage" pointer. And then I am using it in the call to mysql_init() - and that function tries to write to the MYSQL object that *should* be reference by the 'mysql' variable. So it tries to write to a "garbage dump" in some unknown part of memory, which in this case causes a bus error and a core dump. I can't help you fix this one. The reason I can't help you is because you need to know the C language in order to understand why the above code is blatantly wrong. You need to know C pretty well in order to write anything more than the simplest of programs. And the only way to learn C is to READ and TRY, READ and TRY. You can NOT learn C by asking how to do something and then cut-and-pasting the answers you get. I can recommend that you read through the C FAQ thoroughly, and that you go through a good book on C programming. Do NOT buy any book that has void main() { ... } anywhere in it - there are more bad C books than good ones, so stick with one of the standards, and make sure you have a relatively recent edition. I sincerely hope this has helped. If not, please do your homework and then ask again. You can see that I've spent a LOT of time writing this answer. It's not just for your benefit - I hope that it might be read by others new to Unix and MySQL, and that it will help you (plural) over the initial learning hump. But the truth is that all of the information I've collected in this message is available through the list archives, the on-line MySQL manual, and other on-line information sources. With a little bit of work anyone can find these things out. So in the future, please do the work instead of making me (and others like me) do it for you. Finally, if you do need assistance in the future, please try to file a complete problem report. There are detailed instructions in the on-line manual for how to do this. The URL of the manual is given at the bottom of every message sent to this list! Thanks, Tim Footnote: on some systems you'll need to link against the math library (-lm) as well as the mysqlclient library. Here's an example: $ cc -g -Wall -I/usr/local/mysql/include/mysql test.c -L/usr/local/mysql/lib/mysql -lmysqlclient -lm -o test $ It is significant that the math library is listed AFTER the mysqlclient library. The order in which objects are linked makes a difference! On Thu, Apr 01, 1999 at 08:58:54PM -0800, Ray Yous wrote: > Hello, > What is the mysqlclient file and what does it do for my programs that > will access mysql? How do I use it? I found the file at these two > paths: > > /usr/local/lib/mysql/libmysqlclient.a > > /usr/ports/databases/mysql321/work/mysql-3.21.33b/client/libmysqlclient.a > > Is there a difference in the files? Which Should I use? How would I > link to this file with my program called test.c in another directory? > Do I have to use this file to access mysql from a C program? > > Thank, > Roger