Error when linking CGI (C programming ) with Mysql
Hi I'm using CGI which is written with C and MySql.
Here is my sample page.
// save user
void saveUser(char *name, char *pwd,char *role)
{
char query[500];
memset(query,0,500);
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
/* send SQL query */
sprintf(query,"insert into userTbl(name,password,role) values (\'%s\',\'%s\',\'%s\'); ",name,pwd,role);
if (mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit(2);
}
/* close connection */
mysql_close(conn);
}
I got this error whenever I put the page in my CGI folder.
undefined reference to `mysql_init'
undefined reference to `mysql_connect'
undefined reference to `mysql_select_db' and other mysql related errors. When I search the solution on the web It says that I've to link my page with mysql client library like that
gcc -o a $(mysql_config --cflags) saveUser.c $(mysql_config --libs)
First Question Does it mean I can't use saveUser.c in my CGI directly?
It shows the same error whenever I put saveuser.c in the CGI folder. I can only put the a script I created. So I decide to call the a script from the CGI by using system("a %s %s %s",arg[0],arg[1],arg[2]) Then I can save the user . Everything is ok.
But I got another problem when I try to retrieve the data from the database. I don't know how to get the data from the database using a generated script. I've to show the lists of users on my web site. Here is my code for retrieval.
// get users
void getAll()
{
char query[500];
char result[1024];
memset(result,0,1024);
memset(query,0,500);
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
/* send SQL query */
sprintf(query,"select * from userTbl");
if (mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit(2);
}
res = mysql_use_result(conn);
/* output table name */
system("clear");
sprintf(result,"ID\t Name\t Password\t Role\n");
while ((row = mysql_fetch_row(res)) != NULL)
{
//printf("%s \n", row[0]);
//strcpy(id,row[0]);
sprintf(query,"%s\t %s\t %s\t\t %s\n",row[0], row[1], row[2], row[3]);
strcat(result,query);
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
printf(result);
}
Second Question What's the best way to overcome this problem. Can I use the script like a in my CGI or How can I use getAll.c in my CGI directly.
Can anybody help me with my problem? I just learn CGI 1.5 months ago and C just 2.5 months ago. Sorry about my ignorance.
Thanks in advance.
Update :
here is my top level Makefile
ROOT=.
CURDIR=$开发者_运维技巧(shell /bin/pwd)
JITCOMM_INSTALL=$(ROOT)/install
include $(ROOT)/Makefile.basic
#set root directory
SUB_DIRS = cgi_src
SUB_DIRS += check_update
SUB_DIRS += loadconfig
SUB_DIRS += keepalive
SUB_DIRS += script
SUB_DIRS += server
SUB_DIRS += startproxy
SUB_DIRS += net_stats
#SUB_DIRS += ../sniffer_gui
#SUB_DIRS += java
all:
ifneq ($(SUB_DIRS), )
@for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif
clean:
@rm -f $(ROOT)/lib/*
@rm -rf $(JITCOMM_INSTALL)
ifneq ($(SUB_DIRS), )
@for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif
install: all
@rm -rf $(JITCOMM_INSTALL)
@mkdir $(JITCOMM_INSTALL)
@mkdir $(JITCOMM_INSTALL)/etc
@mkdir $(JITCOMM_INSTALL)/etc/acpro
@mkdir $(JITCOMM_INSTALL)/etc/syslog-ng
@mkdir $(JITCOMM_INSTALL)/etc/apache2
@mkdir $(JITCOMM_INSTALL)/etc/apache2/sites-available
@mkdir $(JITCOMM_INSTALL)/var
@mkdir $(JITCOMM_INSTALL)/var/www
@mkdir $(JITCOMM_INSTALL)/var/www/cgi-bin
Here is my Makefile in cgi-src folder
ROOT=../
CURDIR=$(shell /bin/pwd)
include $(ROOT)/Makefile.basic
#set root directory
SUB_DIRS = util
SUB_DIRS += cgi_util
SUB_DIRS += cgi_module
#Must be last
SUB_DIRS += cgi_main
all:
ifneq ($(SUB_DIRS), )
@for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif
clean:
ifneq ($(SUB_DIRS), )
@for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif
install:
ifneq ($(SUB_DIRS), )
@for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make install || exit; cd $(CURDIR); done
endif
Here is my Makefile.basic
CC=/usr/bin/gcc
#CC=powerpc-linux-gcc
CP=/usr/bin/cp
CFLAGS=-g -Wall $(shell mysql_config --cflags) $(shell mysql_config --libs)
www=/var/www
htdocs=/htdocs
cgi_bin=/cgi-bin
config=/etc/apache2/sites-available/default
INSTALL_DIR=$(pwd)/.install
Here is part of my error
/usr/bin/gcc -c -g -Wall -I/usr/include/mysql -DBIG_JOINS=1 -fPIC fno-strict- aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -I../include -o cgi_func.o cgi_func.c
/usr/bin/gcc -c -g -Wall -I/usr/include/mysql -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -I../include -o cgic.o cgic.c
/usr/bin/gcc -g -Wall -I/usr/include/mysql -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -static -o cgi_main cgi_func.o cgic.o -lcgi_util -lcgi_module -lutil -L../../lib -lm
../../lib/libcgi_module.a(users.o):(.data.rel.local+0x8): multiple definition of `password'
../../lib/libcgi_module.a(password.o):/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/password.c:292: first defined here
/usr/bin/ld: Warning: size of symbol `password' changed from 193 in ../../lib /libcgi_module.a(password.o) to 4 in ../../lib/libcgi_module.a(users.o)
/usr/bin/ld: Warning: type of symbol `password' changed from 2 to 1 in ../../lib/libcgi_module.a(users.o)
../../lib/libcgi_module.a(users.o): In function `save':
/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/users.c:17: multiple definition of `save'
../../lib/libcgi_module.a(mode.o):/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/mode.c:56: first defined here
../../lib/libcgi_module.a(users.o): In function `saveUser':
users.c:(.text+0x1cb): undefined reference to `mysql_init'
users.c:(.text+0x22d): undefined reference to `mysql_real_connect'
users.c:(.text+0x241): undefined reference to `mysql_error'
users.c:(.text+0x2bd): undefined reference to `mysql_query'
users.c:(.text+0x2d1): undefined reference to `mysql_error'
users.c:(.text+0x30d): undefined reference to `mysql_close'
You have answered your own question, if you get undefined references to MySQL, you are not linking it correctly. You need to compile with:
gcc -o a $(mysql_config --cflags) saveUser.c $(mysql_config --libs)
This has nothing to do with how your code looks/works, only how the compiler/linker combines the source files into an executable. If you post a part of your Makefile instead of your code maybe you could get more pointers on the issue.
EDIT: Ok, can you add $(mysql_config --cflags) $(mysql_config --libs)
to your CFLAGS declaration in Makefile.basic and see what happens?
EDIT2: The line causing the error seems to be:
/usr/bin/gcc -g -Wall -I/usr/include/mysql -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -static -o cgi_main cgi_func.o cgic.o -lcgi_util -lcgi_module -lutil -L../../lib -lm
A bit odd, since (I assume) the correct libraries are linked (-lmysqlclient
)... double check that you don't have multiple versions of the mysql library installed, or that these functions are defined in a different library. The easiest way to go about it would be to create a minimal project with just these mysql-functions and try to link it. If that doesn't work there is your problem. If it does work I'm not sure where to go next.
You should look into these multiple definitions warnings by the way, looks nasty... check if you have global variables defined in a header file somewhere. The project you are working on seems to partition all it's code in different libraries and link these at the end, maybe you need to clean all of it (remove .o and .a files) and run make again?
精彩评论