`
james23dier
  • 浏览: 530184 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

undefined reference to "function name" &&

阅读更多

今日使用qthread,写了个简单的例子first_qthread.cpp。。

#include <qthread/qthread.h>
#include <stdio.h>


int main(int argc, char* argv[]){

        qthread_t* me;
        int id;
        qthread_initialize();
        qthread_init(1);
        me = qthread_self();
        id = qthread_id(me);
//      cout<<id;
        printf("thread id is :%d", id);
        return 0;
}

使用g++编译: g++ -I ../include first_qthread.cpp.结果编译报错:

/tmp/ccyTG6aP.o: In function `main':
first_qthread.cpp:(.text+0x10): undefined reference to `qthread_initialize'
first_qthread.cpp:(.text+0x1a): undefined reference to `qthread_init'
first_qthread.cpp:(.text+0x1f): undefined reference to `qthread_self'
first_qthread.cpp:(.text+0x2c): undefined reference to `qthread_id'
collect2: ld returned 1 exit status

 

其中的未定义的qthread_initialize,qthread_init,qthread_self,qthread_id均为qthread中定义的函数。。然后请教同事总的牛人。。告诉我编译选项加上-L选项。

命令如下:g++ -I ../qthread-1.4/include/ first_qthread.cpp -L ../qthread-1.4/src/.libs/ -lqthread

原因大致如下: -I 选项只是引入了头文件,而没有引入相应的动态链接库等等。只有加入了动态选项之后编译才能成功。

然后编译成功。

之后运行编译成功的文件 ./a.out 继续出错。

错误信息:error while loading shared libraries:cannot open file ... or file does not exist..

当场石化。然后继续google。原来是没有设置LD_LIBRARY_PATH。遂设置。运行。结果出来。。下面转帖LD_LIBRARY_PATH问题文章一篇。。

 

库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
在 /etc/ld.so.conf 文件中添加库的搜索路径。
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
/usr/X11R6/lib

/usr/local/lib

/opt/lib
        需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。

        因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下 /sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。

        在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
前面已经说明过了,库搜索路径的设置有两种方式:

在环境变量 LD_LIBRARY_PATH 中设置

在 /etc/ld.so.conf 文件中设置。

其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:


$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH


可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:


$ echo $LD_LIBRARY_PATH


至此,库的两种设置就完成了。

 


交叉编译时候如何配置连接库的搜索路径
交叉编译的时候不能使用本地(i686机器,即PC机器,研发机器)机器上的库,但是在做编译链接的时候默认的是使用本地库,即/usr/lib,/lib两个目录。因此,在交叉编译的时候,要采取一些方法使得在编译链接的时候找到需要的库。
首先,要知道:编译的时候只需要头文档,真正实际的库文档在链接的时候用到。 (这是我的理解,假如有不对的地方,敬请网上各位大侠指教) 然后,讲讲如何在交叉编译链接的时候找到需要的库。
(1)、交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。例如:
arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include
(2)、使用ld.so.conf文档,将用到的库所在文档目录添加到此文档中,然后使用ldconfig命令刷新缓存。
(3)、使用如下命令:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib
参见《ld.so.conf 文档和PKG_CONFIG_PATH变量》这篇文章。
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(!)。
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH 的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
(4)、交叉编译时使用软件的configure参数。例如我编译minigui-1.3.3,使用如下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux \
CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include \
LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib \
--prefix=/usr/local/arm/2.95.3/arm-linux \
--enable-lite \
--disable-galqvfb \
--disable-qvfbial \
--disable-vbfsupport \
--disable-ttfsupport \
--disable-type1support \
--disable-imegb2312py \
--enable-extfullgif \
--enable-extskin \
--disable-videoqvfb \
--disable-videoecoslcd
这里我配置了CFLAGS和LDFLAGS参数,这样一来,我就不用去修改每个Makefile里-L和-I参数了,也不用再去配置LD_LIBRARY_PATH或改写ld.so.conf文档了。

Linux下动态库使用小结
1. 静态库和动态库的基本概念
静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,可以被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时需要库文件支持,如果机器里没有这些库文件就不能运行。
2. 如何使用动态库
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用 LD_LIBRARY_PATH》)。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH 的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
3.库的链接时路径和运行时路径
现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式移植时#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过- rpath(或-R )、LD_LIBRARY_PATH指定查找路径。
小问题:
1.编译时的-L选项是否影响LD_LIBRARY_PATH的值?
举一个实例:
当前文件夹结构如下:
test.c tools/
tool下有tool.c tool.h my_err.h 以及由此生成的libtool.so
tool下编译生成库文件
gcc -Wall -g -shared -o tool.so tool.c
在当前文件夹引用:
gcc -Wall -g –o test.c -Ltools -ltool
编译不报错,但是运行加载的时候就出现cannot open shared object file。
如果将该库文件拷贝到/usr/lib下就没有错误,正常运行。
说明编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库。

有关动态链接库需要注意的相关事项
1.有关动态链接库需要注意的相关事项。

如果碰到有GTK 的程序中 有 <gtk\gtk.h>

那么需要加入动态链接库的参数

$ gcc test_a.c test_b.c iptbox.c -fPIC -shared -o iptbox.so `pkg-config --cflags --libs gtk+-2.0

生成出来的.so 动态链接库 需要放在usr/lib 目录下

cp libipt.so /usr/lib

2、在运行AP时出现错误,可以使用下列方式来查找问题:

strace ./test

3、查找文件夹下路径:

find /usr/lib -name libipt.so

4、解压缩命令:

tar -zxvf 文件名

5、解RPM包的方式:

#rpm -ivh scim-1.4.7.4-1benX.src.rpm

#cd /usr/src/dorado/SPECS

#rpmbuild -bb scim.spec

6、目录权限打开:

chmod 777 root(目录名称)

7、linux 下安装软件三步骤:

a.  ./configure

b.  make

c. make install

8、更新库引用:

ldconfig

9、查找是否有安装该AP.

# whereis scim-ppenglish

转载自:http://blog.csdn.net/lwhsyit/archive/2008/08/26/2830783.aspx

分享到:
评论

相关推荐

    C生成静态库给C++调用出现undefined reference to ...解决方案_cpp

    在C++程序中调用C编译的静态库时,可能会遇到“undefined reference to ...”错误,这通常意味着链接器无法找到对应的函数定义。要解决这个问题,我们需要理解C与C++之间的互操作性以及编译和链接过程。下面将详细...

    main.cpp:(.text+0x1180): undefined reference to `cv::randn(cv::_InputOutputArray const&, cv::_InputA

    总结来说,解决"undefined reference to `cv::function_name`"的错误通常涉及到检查编译和链接步骤是否正确包含所需的库和头文件。对于OpenCV项目,确保CMakeLists.txt文件正确配置,包括`include_directories`来...

    C语言中编译相关的常见错误

    错误信息:“undefined reference to `main'”表明编译器在寻找程序的入口点`main`函数时未能找到。在C语言中,`main`函数是程序执行的起点。如果编译器找不到`main`函数,那么它将无法生成可执行文件。这通常是...

    linux php开启openssl拓展报错时候替换本机的openssl文件夹

    出现以下报错,替换/usr/local/...name_entry’:/data/src/php-5.6.23/ext/openssl/openssl.c:664: warning: ‘ASN1_STRING_data’ is deprecated (declared at /usr/local/include/openssl/asn1.h:553)/data/src/...

    eScript Language Reference

    根据提供的文件信息,“eScript Language Reference”是关于eScript语言的官方参考文档,版本为8.2,发布于2011年10月。以下是对eScript语言的一些关键知识点的总结和解析。 ### eScript语言特点 eScript语言具有...

    undefined

    2. **类型注解**:通过 `:` 后跟类型来为变量、函数参数和返回值指定类型,如 `function greet(person: string): string { return 'Hello, ' + person; }` 3. **接口(Interface)**:定义对象的结构,如 `...

    rust-call-c:尝试使用FFI实用程序使用PMDK调用自定义C函数

    在本文中,我们将深入探讨如何使用Rust编程语言通过 Foreign Function Interface (FFI) 调用自定义的C函数,并结合Persistent Memory Development Kit (PMDK) 进行存储操作。FFI允许不同的编程语言之间共享代码,...

    ARM常见的编译错误

    - **错误示例**:“undefined reference to `function_name`” - **原因**:当编译器找不到函数或变量的定义时会抛出此错误。 - **解决方法**: - 确保所有使用的函数和变量都已在代码中正确声明和定义。 - ...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Parameters to C/C++ functions are either input to the function, output from the function, or both. Input parameters are usually values or const references, while output and input/output parameters ...

    SRS 2.0-258 windows版本

    /mnt/srs-2.0-r5/trunk/src/app/srs_app_st.cpp:217: undefined reference to `st_set _eventsys' /usr/lib/gcc/i686-pc-cygwin/7.4.0/../../../../i686-pc-cygwin/bin/ld: /mnt/srs-2. 0-r5/trunk/src/app/srs_app_...

    json.js_json2.js

    a replacer function to replace those with JSON values. JSON.stringify(undefined) returns undefined. The optional space parameter produces a stringification of the value that is filled with line ...

    softap_ap6212a0_tinav2.1_验证通过_旧版本的系统_20170915_1223没有外层目录.7z

    rootroot@cm-System-Product-Name:/home/wwt$ tar zxvf tinaV2.1_wyb_20170302_patch_leo_20161102.tar.gz rootroot@cm-System-Product-Name:/home/wwt$ mv tinaV2.1 softap_ap6212a0_tinav2.1 rootroot@cm-System...

    C++错误代码详细解释

    - **错误示例:** "undefined reference to `function_name'" 链接器找不到你在代码中引用的函数或变量的定义。这可能是由于忘记包含相应的源文件,或者函数没有正确声明和实现。 4. **运行时错误** (Runtime ...

    Secrets of the JavaScript Ninja, 2nd Edition

    `const` creates a read-only reference to a value, preventing reassignment but allowing mutation: ```javascript const ninja = { name: "Yoshi" }; ninja.name = "Hanzo"; // Allowed ninja = { name: "Hanzo...

    2024前端面试通过宝典

    function Parent(name) { this.name = name; } function Child(name) { Parent.call(this, name); } ``` - **组合继承**:结合原型链继承和构造函数继承的优点,先使用构造函数继承属性,再通过原型链继承...

    php.ini-development

    You can redirect all of the output of your scripts to a function. For ; example, if you set output_handler to "mb_output_handler", character ; encoding will be transparently converted to the ...

    悟透JavaScript

    function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log("Hello, " + this.name); } let person1 = new Person("Alice"); person1.greet(); // 输出 "Hello, Alice" ``...

    JavaScript Quick Reference

    // Variables local to innerFuncA }] aName = 'ExplainThat!'; // implicit global variable creation } ``` - **函数定义**: 函数是封装了一段执行特定任务的代码块,可以通过调用该函数来重复执行这段代码。 ...

    JavaScript语言基础.pdf

    function Person(name) { this.name = name; } var person = new Person("Alice"); ``` - **访问对象属性**: - 使用点语法: ```javascript obj.key; // "value" ``` - 使用括号语法: ```javascript ...

    Flex编译错误码总结

    6. Error 1180: Call to a possibly undefined method methodName 当调用一个可能未定义的方法时,会抛出此错误。确保该方法存在于对象的类定义中,或者对象确实实现了该接口。 7. Error 1185: Duplicate ...

Global site tag (gtag.js) - Google Analytics