linux C 头文件/库文件 FAQ

(1) 标准头文件中函数的实现

Q: linux 下只找到c头文件,但没有找到具体的实现,编译的时候gcc是从哪里找具体的stdio.c和unistd.c等文件的?

平时写代码的时候直接include ,编译器从哪里去找相对应的xxx.c?

A: 头文件只是一句函数声明,实现的代码在标准库对应的.lib或者.so或者.dll,也就是静态或动态库文件里;
    包含头文件用于编译,加上库用于链接。

实现已经编译进libc库里面了,glibc或者uclibc库。
一般可以在/lib或者/lib64下面找到libc.so.x
然后用readelf -s /lib64/libc.so.6 |grep " printf" 就可以发现这个库里面有这个编译好的函数了。链接时一般会链接到这一个printf函数上。

-------------

(2) linux 库文件(函数)的源码查看

-------------

(3) 查看 头文件搜索路径的方法

3.1)当前目录(仅双引号形式)

3.2)编译时指定的头文件目录(由gcc -I参数指定)

3.3)系统环境变量 CPLUS_INCLUDE_PATH(c++头文件)或 C_INCLUDE_PATH(c头文件)指定的目录

3.4)gcc默认目录:

/usr/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/5/include(注:最后一个路径是gcc程序的库文件地址,各个用户的系统上可能不一样)

3.5)其他:

1》默认目录路径查看:

gcc的默认目录与安装gcc时指定的–prefix有关,该值可通过 gcc -v查看;

另外 也可以通过 cpp -v 查看;

另外一种方法是用: strace 来跟踪系统调用access和open,看看是从哪里找的stdio.h和unistd.h;

比如:strace -f gcc 1.c 2>&1 | grep "stdio\.h"  (gcc 编译 1.c 时 的系统调用)

-------------

(4)库文件

头文件用于编译,库文件用于链接,编译通过了,还要链接通过。链接时库文件的查找顺序如下:

  1. 编译时指定的库文件目录(由gcc -L参数指定)
  2. 环境变量LIBRARY_PATH指定的目录
  3. 系统默认目录:/lib; /usr/lib; /usr/local/lib

一般用户安装的库会安装在/usr/local/lib,系统自带的库位于/lib; /usr/lib,用户自己编译的库可能就要使用-L参数指定了。

编译时通过了,还会有一个问题,就是运行动态库的使用。因为动态库是运行时加载的,所以还会有一个查找的顺序:

1> 编译时指定的动态库搜索路径(通过gcc 的参数"-Wl,-rpath,"指定。当指定多个动态库搜索路径时,路径之间用冒号:分隔)
2> 环境变量LD_LIBRARY_PATH指定的动态库搜索路径(路径之间用冒号:分隔)
3> 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4> 默认的动态库搜索路径/lib:/usr/lib
特别注意,库文件的查找默认是不查找当前目录的,也就是说,即使使用的库位于同一个目录内,也需要指定才能指定。

-------------

(5) 编译常见的 缺少头文件错误:no such file

A: 解决方法:

5.1)安装相关的库或者包 / 软件包升级

头文件的默认搜索路径为(cpp -v 查看):/usr/include, /usr/local/include, 

安装完后,再用 find / -type f -name "xxx" 搜索;

1》安装软件包: yum install -y xxx;

2》 软件包升级: yum update -y / apt-get update 

 

5.2)从其他地方拷贝头文件到标准路径

find / -type f -name "xxx" 在本机搜索;

其他设备上存在,则从其他设备上拷贝;(最好从相同内核版本的设备上拷贝头文件)

网络上搜索下载;

注:某些 .h 文件可能是 ./configure 或者 其他编译过程中生成的;这样会直接搜索不到;

 

 

 

 

你可能感兴趣的:(C,language,linux)