List:General Discussion« Previous MessageNext Message »
From:Thimble Smith Date:April 2 1999 7:27am
Subject:Re: [MySQL]
View as plain text  
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 <header-file>.  Here's an example:

#include <mysql.h>

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<directory> 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<library-name>
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<directory> 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 <mysql.h>

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
Thread
[MySQL]Ray Yous2 Apr
  • Re: [MySQL]Thimble Smith2 Apr