最近有个项目需要生成静态编译的可执行文件,以便在其它linux的机器中运行,开始以为非常简单,直接在编译中加个-static选项不就是了,结果却和我想的太不一样了,下面说下我遇到的问题以及解决的方法。
开始按照设想应该只要在编译中加个-static选项就可以了,不过却报下面的错误:
cc -g -static -o test_server main_server.o main_db.o err_me.o -L/usr/lib/mysql/ -lmysqlclient -lpthread -ldl -lcrypt /usr/bin/ld: cannot find -lmysqlclient /usr/lib/gcc/i686-redhat-linux/4.6.2/http://www.cnblogs.com/../libpthread.a(libpthread.o): In function `sem_open': (.text+0x6917): warning: the use of `mktemp' is dangerous, better use `mkstemp' collect2: ld returned 1 exit status make: *** [test_server] Error 1
说是没有找到-lmysqlclient,应该是没有找到libmysqlclient.a库,然后我到目录/usr/lib/mysql/下去找,只有libmysqlclient.so的动态链接库,因为加了-static后要使用静态库才能编译成功,然后就在网上搜看看有没有libmysqlclient.a的静态库下载。搜了好几个小时一无所获,偶然看到一个也是编译与mysql库有关的程序的选项,发现里面库的路径居然是/usr/local/mysql/lib/,然后我也到这个目录去看了下,libmysqlclient.a文件真的在这里面,汗!!!这才想起自己以前是用源代码安装的mysql和mysql-dev的。
有了libmysqlclient.a库文件,我立马加入编译选项中重新编译,本以为万事大吉了,结果还是报下面的错:
cc -g -static -o test_server main_server.o main_db.o err_me.o -L/usr/local/mysql/lib/ -lmysqlclient -lpthread -ldl -lcrypt /usr/local/mysql/lib//libmysqlclient.a(mf_pack.c.o): In function `unpack_dirname': mf_pack.c:(.text+0x6dd): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/local/mysql/lib//libmysqlclient.a(libmysql.c.o): In function `read_user_name': libmysql.c:(.text+0x2f21): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/local/mysql/lib//libmysqlclient.a(mf_pack.c.o): In function `unpack_dirname': mf_pack.c:(.text+0x6ed): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/local/mysql/lib//libmysqlclient.a(client.c.o): In function `mysql_real_connect': client.c:(.text+0x34b6): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/i686-redhat-linux/4.6.2/http://www.cnblogs.com/../libpthread.a(libpthread.o): In function `sem_open': (.text+0x6917): warning: the use of `mktemp' is dangerous, better use `mkstemp' /usr/local/mysql/lib//libmysqlclient.a(libmysql.c.o): In function `mysql_server_init': libmysql.c:(.text+0x2a4a): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/local/mysql/lib//libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)': dh.cpp:(.text+0x1a8): undefined reference to `pow' dh.cpp:(.text+0x1b8): undefined reference to `log' dh.cpp:(.text+0x1ca): undefined reference to `pow' collect2: ld returned 1 exit status make: *** [test_server] Error 1
先不管前面的警告,和面说明定义pow,然后再网上搜了下,必须在编译选项中加-lm,然后再编译下,终于是生成了可执行文件了。但是前面的警告是怎么回事,”warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking“,使用getpwnam的应用程序需要运行时共享库glibc来链接。在网上找了很久也没有找到怎么把警告去掉的方法,不过有个折中的方面,貌似也正是解决这个问题的方法,就是libmysqlclient.a库用静态连接,一些常用的库用动态连接,因为程序是运行在linux中的,常用库系统默认都会有的。一部分静态连接,一部分动态连接的方法是:-Wl,-dn后面是静态链接-Wl,-dy后面是动态连接,具体如下:
cc -g -o test_server main_server.o main_db.o err_me.o -Wl,-dn -L/usr/local/mysql/lib/ -lmysqlclient -Wl,-dy -lpthread -lm -ldl -lcrypt
总结:gcc很强大,自己学的只有皮毛,以后还要多用才行。