Chinaunix首页 | 论坛 | 博客
  • 博客访问: 299484
  • 博文数量: 76
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-20 20:38
文章分类
文章存档

2016年(20)

2015年(56)

分类: 嵌入式

2015-08-30 12:32:59

在编译第一个项目中电子书触摸屏的应用程序时,用到了tslib库,编译安装以后,还是提示以下的错误:
built-in.o: In function `TouchScreenGetInputEvent':
/home/ybx/project/09.show_file_Makefile/input/touchscreen.c:65: undefined reference to `ts_read'
built-in.o: In function `TouchScreenDevInit':
/home/ybx/project/09.show_file_Makefile/input/touchscreen.c:21: undefined reference to `ts_open'
/home/ybx/project/09.show_file_Makefile/input/touchscreen.c:29: undefined reference to `ts_config'
明明已经安装好了tslib库,而且这几个函数在tslib.h中定义,可以在交叉编译链中找到这个文件,奇了怪了~~
后来在网上看到一篇文章:
http://blog.csdn.net/jiaweizou/article/details/8153897

1. 为什么会出现undefined reference to 'xxxxx'错误?

首先这是链接错误,不是编译错误,也就是说如果只有这个错误,说明你的程序源码本身没有问题,是你用编译器编译时参数用得不对,你没有指定链接程序要用到得库,比如你的程序里用到了一些数学函数,那么你就要在编译参数里指定程序要链接数学库,方法是在编译命令行里加入-lm

2.-l参数和-L参数

-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了

-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest另外,大部分libxxxx.so只是一个链接

3. -include-I参数

-include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现-include参数很少用。-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加你会得到一个"xxxx.h: No such file or directory"的错误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定

4.几个相关的环境变量

PKG_CONFIG_PATH:用来指定pkg-config用到的pc文件的路径,默认是            /usr/lib/pkgconfigpc文件是文本文件,扩展名是.pc,里面定义开发包的安装路径,Libs参数和Cflags参数等等。

CC:用来指定c编译器。

CXX:用来指定cxx编译器。

LIBS:跟上面的--libs作用差不多。

CFLAGS:跟上面的--cflags作用差不多。

CCCXXLIBSCFLAGS手动编译时一般用不上,在做configure时有时用到,一般情况下不用管。

环境变量设定方法:export ENV_NAME=xxxxxxxxxxxxxxxxx

==========================================================================

[相关介绍]

应用程序(Applications)

应用程序通常都有固定的文件夹,系统通用程序放在/usr/bin,日后系统管理员在 本地计算机安装的程序通常放在/usr/local/bin或者/opt文件夹下。除了系统程序外,大部分个人用到的程序都放在/usr /local下,所以保持/usr的整洁十分重要。当升级或者重装系统的时候,只要把/usr/local的程序备份一下就可以了。


一些其他的程序有自己特定的文件夹,比如X Window系统,通常安装在/usr/X11中,或者/usr/X11R6。GNU的编译器GCC,通常放置在/usr/bin或者/usr/local/bin中,不同的Linux版本可能位置稍有不同。


头文件(Head Files)

在C语言和其他语言中,头文件声明了系统函数和库函数,并且定义了一些常量。对于C语 言,头文件基本上散落于/usr/include和它的子文件夹下。其他的编程语言的库函数分布在编译器定义的地方,比如在一些Linux版本中,X Window系统库函数分布在/usr/include/X11,GNU C++的库函数分布在/usr/include/g++。这些系统库函数的位置对于编译器来说都是“标准位置”,即编译器能够自动搜寻这些位置。


如果想引用位于标准位置之外的头文件,我们需要在调用编译器的时候加上-I标志,来显式的说明头文件所在文件夹。比如,

        $ gcc -I/usr/openwin/include hello.c

会告诉编译器除了标准位置外,还要去/usr/openwin/include看看有没有所需的头文件。详细情况见编译器的使用手册(man gcc)。


库函数(Library Files)

库函数就是函数的仓库,它们都经过编译,重用性不错。通常,库函数相互合作,来完成特定的任务。比如操控屏幕的库函数(cursers和ncursers库函数),数据库读取库函数(dbm库函数)等。


系统调用的标准库函数一般位于/lib以及/usr/lib。C编译器(精确点说,连接器)需要知道库函数的位置。默认情况下,它只搜索标准C库函数。


库函数文件通常开头字母是lib。后面的部分标示库函数的用途(比如C库函数用c标识, 数学库函数用m标示),小数点后的后缀表明库函数的类型:

  • .a 指静态链接库
  • .so 指动态链接库

去/usr/lib看一下,你会发现,库函数都有动态和静态两个版本。

查看动态库函数工具: ldd  *.so

与头文件一样,库函数通常放在标准位置,但我们也可以通过-L标识符,来添加新的搜索文件夹,-l指定特定的库函数文件。比如

        $ gcc -o x11fred -L/usr/openwin/lib x11fred.c -lX11

上述命令就会在编译期间,链接位于/usr/openwin/lib文件夹下的libX11函数库,编译生成x11fred。

静态链接库(Static Libraries)

最简单的函数库就是一些函数的简单集合。调用库函数中的函数时,需要在调用函数中include定义库函数的头文件。我们用-l选项添加标准函数库之外的函数库。

静态函数库,也称为archives ,通常以后缀.a结尾。

************************************************************************************************************
可以在编译个时候,通过-I来添加链接选项,注意,不是在make的时候,在make后面添加,这个需要是编译命令如gcc以后添加,而通过阅读这篇文章,也就知道了,安装好的tslib库是在/usr/local/arm/4.3.2/arm-none-linux-gnueabi/lib下面有一个 libts.so的东西,这个库名就是ts,所以在Makefile中LDFLAGS := -lm -lfreetype -lts
中添加-lts这一项,编译就可以通过~~~


  

阅读(4253) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~