linux 编译指定库、头文件的路径问题(转)
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/pkgconfig,pc文件是文本文件,扩展名是.pc,里面定义开发包的安装路径,Libs参数和Cflags参数等等。
CC:用来指定c编译器。
CXX:用来指定cxx编译器。
LIBS:跟上面的--libs作用差不多。
CFLAGS:跟上面的--cflags作用差不多。
CC,CXX,LIBS,CFLAGS手动编译时一般用不上,在做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看一下,你会发现,库函数都有动态和静态两个版本。
与头文件一样,库函数通常放在标准位置,但我们也可以通过-L标识符,来添加新的搜索文件夹,-l指定特定的库函数文件。比如
$ gcc -o x11fred -L/usr/openwin/lib x11fred.c -lX11
上述命令就会在编译期间,链接位于/usr/openwin/lib文件夹下的libX11函数库,编译生成x11fred。
静态链接库(Static Libraries)
最简单的函数库就是一些函数的简单集合。调用库函数中的函数时,需要在调用函数中include定义库函数的头文件。我们用-l选项添加标准函数库之外的函数库。
静态函数库,也称为archives ,通常以后缀.a结尾。
我们也可以创建维护自己的静态链接库函数。下面就介绍一下:
我们创建的库函数包括两个函数,然后在后面的实例中调用其中之一。两个库函数名字分别是fred和bill,仅仅是输出字符串。
- 首先,我们分别编写两个源文件(fred.c和bill.c),源文件如下:
- /* fred.c */
- #include <stdio.h>
- void fred(int arg)
- {
- printf(“fred: you passed %d\n”, arg);
- }
- /* bill.c */
- #include <stdio.h>
- void bill(char *arg)
- {
- printf(“bill: you passed %s\n”, arg);
- }
/* fred.c */ #include
<stdio.h> void fred(int arg) { printf(“fred: you passed %d\n”,
arg); } /* bill.c */ #include <stdio.h> void bill(char *arg) {
printf(“bill: you passed %s\n”, arg); }
2. 接下来,我们将这两个源文件编译为两个独立的目标文件。这里要用到GCC的-c选项。命令如下所示:
$ gcc -c fred.c bill.c
$ ls *.o
bill.o fred.o
3.
然后,写一个调用bill的测试函数,在此之前,最好为库函数建立一个头文件。头文件中有对库函数的声明。如果其他函数要调用库函数,必须在其代码中包含
头文件。也可以在fred.c 和bill.c中包含该头文件,有利于编译器发现错误。头文件lib.h的内容如下所示:
- /*
- This is lib.h. It declares the functions fred and bill for users
- */
- void bill(char *);
- void fred(int);
/* This is lib.h. It declares the functions fred and bill for users */ void bill(char *); void fred(int);
4. 测试函数program.c比较简单,代码如下:
- #include “lib.h”
- int main()
- {
- bill(“Hello World”);
- exit(0);
- }
#include “lib.h” int main() { bill(“Hello World”); exit(0); }
5. 现在我们可以编译测试一下程序了:
$ gcc -c program.c
$ gcc -o program program.o bill.o
$ ./program
bill: we passed Hello World
6. 接下来,我们要创建一个函数库。利用ar函数建立归档文件(archive),然后将目标文件加入其中。
$ ar crv libfoo.a bill.o fred.o
a - bill.o
a - fred.o
7. 现在可以使用函数库中的函数了。我们用-l指定函数库的名字。因为该函数库没有在标准文件夹中,我们还需要用-L将当前文件夹"."添加到搜索路径中。编译命令如下所示:
$ gcc -o program program.o -L. -lfoo
共享链接库(Shared Libraries)
静态链接库的一个缺点是,如果我们同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一库函数。这样,就会浪费很多珍贵的内存和存储空间。使用了共享链接库的Linux就可以避免这个问题。
共享函数库和静态函数在同一个地方,只是后缀有所不同。比如,在一个典型的Linux系统,标准的共享数序函数库是/usr/lib/libm.so。
当一个程序使用共享函数库时,在连接阶段并不把函数代码连接进来,而只是链接函数的一个引用。当最终的函数导入内存开始真正执行时,函数引用被解
析,共享函数库的代码才真正导入到内存中。这样,共享链接库的函数就可以被许多程序同时共享,并且只需存储一次就可以了。共享函数库的另一个优点是,它可
以独立更新,与调用它的函数毫不影响。
原文出处:http://blog.chinaunix.net/uid-26959037-id-3542739.html
linux 编译指定库、头文件的路径问题(转)的更多相关文章
- GCC编译默认的头文件搜索路径
对于c语言来说: gcc -xc -E -v - 截图: 对于c++来说: gcc -xc++ -E -v - 截图: gcc的arg和opt解释: 后面一干啥作用暂时不知道
- linux下c,c++头文件的路径
一. C语言包含的目录: 二. C++包含的目录
- Linux C语言头文件搜索路径
本文介绍在linux中头文件的搜索路径,也就是说你通过include指定的头文件,linux下的gcc编译器它是怎么找到它的呢.在此之前,先了解一个基本概念. 头文件是一种文本文件,使用文本编辑器将代 ...
- Linux下的头文件搜索路径
对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执 ...
- Linux 中C/C++ search path(头文件搜索路径)
https://blog.csdn.net/BjarneCpp/article/details/76135980 起因 我拿到了一套Linux下的C++代码,代码中有这个头文件#include < ...
- 指定g++ 头文件路径的方法
问题: 尝试引用Python.h 这个头文件 g++ -o main main.cpp main.:: 错误:Python.h:没有那个文件或目录 由些可以看出是g++ 找不到指定的头文件 解决方式: ...
- gcc和arm-linux-gcc 头文件寻找路径【转】
原文地址:http://blog.chinaunix.net/uid-29145190-id-3867605.html 在LINUX程序设计当中,经常会遇到头文件包含的问题,那么这些头文件到底在哪个路 ...
- C和C++中include 搜索路径的一般形式以及gcc搜索头文件的路径
C和C++中include 搜索路径的一般形式 对于include 搜索的路径: C中可以通过 #include <stdio.h> 和 #include "stidio.h&q ...
- Linux驱动开发常用头文件
头文件目录中总共有32个.h头文件.其中主目录下有13个,asm子目录中有4个,linux子目录中有10个,sys子目录中有5个.这些头文件各自的功能如下: 1.主目录 <a.out.h> ...
随机推荐
- log4j日志记录到数据库
log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...
- SpringBoot2.0拦截器 与 1.X版本拦截器 的实现
1.5 版本 先写个拦截器,跟xml配置方式一样,然后将拦截器加入spring容器管理 .接着创建 配置文件类 继承 WebMvcConfigurerAdapter 类,重写父类方法addInter ...
- React-Native 指定模拟器RUN-IOS
react-native run-ios --simulator "iPhone 7”
- springMVC的数据封装
编写实体类: package cn.mepu.domain; /** * @User 艾康 * @create 2019-11-12 13:56 */ public class User { priv ...
- 一、基础项目构建,引入web模块,完成一个简单的RESTful API
一.Spring Boot的主要优点: 为所有Spring开发者更快的入门 开箱即用,提供各种默认配置来简化项目配置 内嵌式容器简化Web项目 没有冗余代码生成和XML配置的要求 二.使用maven构 ...
- 游戏game
1.log4cxx 日志 2.protobuf 数据交互(类似json 3.boost.asio 网络库 4.boost.python 脚本支持 5.语法树 + c++处理excel资源
- 前端学习(七)less(笔记)
less---处理器:koala_2.0.4_portable 属于css预处理语言,可以让你的css语言更有逻辑性! 编译css的! 准备工作: 1.项目: js ...
- 【Luogu】【关卡2-11】简单数学问题(2017年10月)【还差三道题】
火星人 麦森数 P1403 [AHOI2005]约数研究 f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和. 解答:有几个1做约数的个数 = n /1; 有几个2做约数的个数 = ...
- vue指令系统
一.vue基础 使用vue需在官网上先下载vue.js,网址:https://cn.vuejs.org/v2/guide/installation.html.然后: 在project中引入vue.js ...
- macOS免费的NTFS读写软件
Mounty for Mac brew cask install mounty