LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2160|回复: 18

编译OCI的程序出现的问题,请教

[复制链接]
发表于 2003-8-28 14:33:34 | 显示全部楼层 |阅读模式
编译了一个oci的demo,可是却出现了/usr/bin/ld: cannot find -lclntsh
这个错误,可是我查过,$ORACLE_HOME/lib里有文件libclntsh.so libclntsh.so.9.0 ,不知怎么是好了,大哥大姐帮忙下


[root@BillingServer oci_demo]# make oracle
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -c -o dbcom.o dbcom.c
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -c -o dbfunc.o dbfunc.c
ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -o test1 test1.c -L. -ldb -L/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [oracle] Error 1

Makefile文件内容如下:

CC=gcc
MAKE=make
CFLAGS=-I$(ORACLE_HOME)/precomp/public -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/rdbms/demo -g
LIBS=-L. -ldb -L$(ORACLE_HOME)/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt

all : oracle

oracle : dbcom.h dbfunc.h dbcom.c dbfunc.c
        $(CC) $(CFLAGS) -c -o dbcom.o dbcom.c
        $(CC) $(CFLAGS) -c -o dbfunc.o dbfunc.c

        ar -crl libdb.a dbcom.o dbfunc.o
        chmod 644 libdb.a

test :
        $(CC) $(CFLAGS) -o test1 test1.c $(LIBS)
        chmod 744 test1
        $(CC) $(CFLAGS) -o test2 test2.c $(LIBS)
        chmod 744 test2

clean :
        rm -f core* *.o libdb.a test1 test2
 楼主| 发表于 2003-8-28 16:26:29 | 显示全部楼层
不知是什么样的错误造成了这样的提示呢
发表于 2003-8-28 19:26:04 | 显示全部楼层
看看你的/etc/ld.so.conf中有没有$ORACLE_HOME/lib,如果没有,就加上。然后再执行ldconfig。
 楼主| 发表于 2003-8-28 19:43:49 | 显示全部楼层
的确是没有,试试

实验了下

make的时候可以,因为make只运行到test:就停止了
再运行make test的时候就出现了下面的错误

[root@BillingServer oci_demo]# make test
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -o test1 test1.c -L. -ldb -L/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [test] Error 1
发表于 2003-8-28 20:35:18 | 显示全部楼层
make过了,说明修改/etc/ld.so.conf是起作用的。
test没过,是因为gcc没有找到-lclntsh。我注意到在makefile中的这句:
LIBS=-L. -ldb -L$(ORACLE_HOME)/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
其中-L后面应该跟的是$(ORACLE_HOME)/lib,但是从make test的错误提示中,就是下面这句:
[root@BillingServer oci_demo]# make test
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -o test1 test1.c -L. -ldb -L/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
其中-L后面跟的是-L/lib。好象$(ORACLE_HOME)没有被替换成相应的目录。一般oracle安装,不会把库文件放到/lib目录下的,所以你自己在命令行echo ORACLE_HOME看看这个环境变量是否设置正确。
 楼主| 发表于 2003-8-29 09:27:57 | 显示全部楼层
的确,我以oracle用户敲入了echo ORACLE_HOME
出现下面
[oracle@BillingServer oracle]$ echo ORACLE_HOME
ORACLE_HOME

可是我在装oracle的时候在.bash_profile文件中设置了这个基本变量啊
下面是我的.bash_profile文件,位置位于/home/oracle/.bash_profile

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATHHOME/bin

export PATH
unset USERNAME

umask 022
TERM=xterm; export TERM
TMPDIR=/tmp; export TMPDIR
export ORACLE_SID=ora9
export ORACLE_BASE=/oracle
export ORACLE_HOME=/oracle/product/9.2.0
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/lib
export TNS_ADMIN=$ORACLE_HOME/network/admin
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export ORACLE_TERM=xterm
PATH=$ORACLE_HOME/bin:/opt/bin:/bin
PATH=$PATH:/usr/bin:/usr/local/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/java/bin:.
export PATH
export JAVA_HOME=/usr/local/java
CLASSPATH=$CLASSPATHORACLE_HOME/jdbc/lib/classes12.zip
CLASSPATH=$CLASSPATHORACLE_HOME/jlibORACLE_HOME/rdbms/jlib
CLASSPATH=$CLASSPATH:network/jlib
export CLASSPATH
export LD_ASSUME_KERNEL=2.4.1


我更改了ld.so.conf文件的目录,变更成了绝对路径
/oracle/product/9.2.0/lib
结果就是下面的情况:

[root@BillingServer etc]# vi ld.so.conf
/usr/kerberos/lib
/usr/X11R6/lib
/usr/lib/sane
/usr/lib/qt-3.1/lib
/usr/lib/mysql
/usr/lib/qt2/lib
/oracle/product/9.2.0/lib

[root@BillingServer etc]# ldconfig
ldconfig: /oracle/product/9.2.0/lib/libagtsh.so is not a symbolic link

ldconfig: /oracle/product/9.2.0/lib/libnk59.so is not a symbolic link

ldconfig: /oracle/product/9.2.0/lib/libnrad9.so is not a symbolic link

看来还是没有设置好库联接啊

发表于 2003-8-29 13:02:21 | 显示全部楼层
不好意思,应该是echo $ORACLE_HOME,打字时少打了一个$,自然得不到正确的结果了。
执行ldconfig后出现的结果应该没有关系。你再make test看看,如果还不能过,就把makefile中的($ORACLE_HOME)换成绝对路径。
 楼主| 发表于 2003-8-30 10:43:14 | 显示全部楼层
echo $ORACLE_HOME
以oracle用户运行可以得到正确结果,以root用户运行得不到正确的目录

还有,我想知道,-lclntsh到底是什么,是编译器gcc的一个选项而已,还是其他的什么?

依你的方法,我更改了$ORACLE_HOME变量为绝对路径,下面把我这两天的调试过程写了下来,贴出来以供后来者解惑吧

oci_demo调试手记

出现/usr/bin/ld: cannot find -lclntsh错误
-lclntsh是gcc编译的一个选项
[root@BillingServer oci_demo]# make oracle
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -c -o dbcom.o dbcom.c
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -c -o dbfunc.o dbfunc.c
ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -o test1 test1.c -L. -ldb -L/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [oracle] Error 1



如果采用下面的Makefile文件
// Makefile
CC=gcc
MAKE=make
CFLAGS=-I$(ORACLE_HOME)/precomp/public -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/rdbms/demo -g
LIBS=-L. -ldb -L$(ORACLE_HOME)/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt

all : oracle

oracle : dbcom.h dbfunc.h dbcom.c dbfunc.c
$(CC) $(CFLAGS) -c -o dbcom.o dbcom.c
$(CC) $(CFLAGS) -c -o dbfunc.o dbfunc.c

ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a

test :
$(CC) $(CFLAGS) -o test1 test1.c $(LIBS)
chmod 744 test1
$(CC) $(CFLAGS) -o test2 test2.c $(LIBS)
chmod 744 test2

clean :
rm -f core* *.o libdb.a test1 test2

那么会在make的时候过关,make test的时候出现/usr/bin/ld: cannot find -lclntsh错误
[root@BillingServer oci_demo]# make test
gcc -I/precomp/public -I/rdbms/public -I/rdbms/demo -g -o test1 test1.c -L. -ldb -L/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [test] Error 1

我们开始修改Makefile文件
(1)试着运行echo $ORACLE_HOME来检测ORACLE_HOME是否生效
以root用户运行后没有任何结果
[root@BillingServer oci_demo]# echo $ORACLE_HOME

以oracle用户运行后出现正确结果,看来是.bash_profile文件起的作用,这个文件位于/home/oracle/.bash_profile下。
[oracle@BillingServer oracle]$ echo $ORACLE_HOME
/oracle/product/9.2.0

(2)Makefile文件中有(ORACLE_HOME),试着取消括号,看看是否有用,结论是没有任何用处
[root@BillingServer oci_demo]# make oracle
gcc -IRACLE_HOME/precomp/public -IRACLE_HOME/rdbms/public -IRACLE_HOME/rdbms/demo -g -c -o dbcom.o dbcom.c
gcc -IRACLE_HOME/precomp/public -IRACLE_HOME/rdbms/public -IRACLE_HOME/rdbms/demo -g -c -o dbfunc.o dbfunc.c
ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a
[root@BillingServer oci_demo]# make test
gcc -IRACLE_HOME/precomp/public -IRACLE_HOME/rdbms/public -IRACLE_HOME/rdbms/demo -g -o test1 test1.c -L. -ldb -LRACLE_HOME/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
/usr/bin/ld: cannot find -lclntsh
collect2: ld returned 1 exit status
make: *** [test] Error 1

(3)既然ORACLE_HOME只能够在oracle用户下使用,那么我们如果想在root下运行make,就必须更改目录
Makefile文件改成下面的样子:
// Makefile
CC=gcc
MAKE=make
CFLAGS=-I /oracle/product/9.2.0/precomp/public -I /oracle/product/9.2.0/rdbms/public -I /oracle/product/9.2.0/rdbms/demo -g
LIBS=-L. -ldb -L /oracle/product/9.2.0/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt

oracle : dbcom.h dbfunc.h dbcom.c dbfunc.c
$(CC) $(CFLAGS) -c -o dbcom.o dbcom.c
$(CC) $(CFLAGS) -c -o dbfunc.o dbfunc.c

ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a

test :
$(CC) $(CFLAGS) -o test1 test1.c $(LIBS)
chmod 744 test1
$(CC) $(CFLAGS) -o test2 test2.c $(LIBS)
chmod 744 test2

clean :
rm -f core* *.o libdb.a test1 test2

对Makefile文件做了修改,更改了$ORACLE_HOME目录为绝对路径/oracle/product/9.2.0

结果为

[root@BillingServer oci_demo]# make
gcc -I /oracle/product/9.2.0/precomp/public -I /oracle/product/9.2.0/rdbms/public
-I /oracle/product/9.2.0/rdbms/demo -g -c -o dbcom.o dbcom.c
gcc -I /oracle/product/9.2.0/precomp/public -I /oracle/product/9.2.0/rdbms/public
-I /oracle/product/9.2.0/rdbms/demo -g -c -o dbfunc.o dbfunc.c
ar -crl libdb.a dbcom.o dbfunc.o
chmod 644 libdb.a

[root@BillingServer oci_demo]# make test
gcc -I /oracle/product/9.2.0/precomp/public -I /oracle/product/9.2.0/rdbms/public
-I /oracle/product/9.2.0/rdbms/demo -g -o test1 test1.c -L. -ldb -L /oracle/product/9.2.0/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
chmod 744 test1
gcc -I /oracle/product/9.2.0/precomp/public -I /oracle/product/9.2.0/rdbms/public
-I /oracle/product/9.2.0/rdbms/demo -g -o test2 test2.c -L. -ldb -L /oracle/product/9.2.0/lib -lclntsh -lpthread -lm -lnsl -lresolv -lrt
chmod 744 test2

[root@BillingServer oci_demo]# make clean
rm -f core* *.o libdb.a test1 test2

PS:注意,版主,我make过了以后不知如何运行我的程序呢,生成的dbcom.o,dbfunc.o和libdb.a不知是干什么用的啊,尤其是libdb.a,有些文章里甚至写它是库文件,我都不知如何运行我自己编译出来的程序了
下面是我的目录列表
[root@BillingServer oci_demo]# ls
dbcom.c  dbcom.o   dbfunc.h  db.sql   Makefile      test1.c
dbcom.h  dbfunc.c  dbfunc.o  libdb.a  Makefile.bak  test2.c

发表于 2003-8-30 14:10:26 | 显示全部楼层
从makefile来看,这个软件本来就是作为库文件使用,因此它不是直接提供给用户使用的,而是提供给程序员作用的。
btw:make test没有问题,就说明库文件能够正常连接。你在make clean之前,应该运行一下test1和test2,看看有没有段错误之类的。
发表于 2003-8-31 00:17:11 | 显示全部楼层
这个是oracle自己的库

开发oci或是proc时要link它

顶上的FAQ应该有写

另外使用oracle用户时环境变量与root不一样
所以可以在oracle用户下成功

在root下不成功
其它oracle命令很多也是这样的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表