Linux平台gcc编译运行时头文件或动态链接库的查找

本文介绍了GCC编译器如何定位并使用头文件,以及如何链接动态库的过程。通过具体的示例,展示了如何通过编译命令指定头文件路径,并解释了如何创建和使用动态共享库。
 我们在写一个比较大型的程序时,总是喜欢把一些函数还有一些数据结构的声明放在一个文件中,我们把这种文件称为头文件,文件名以.h后缀结尾。在一些源文件里,我们可能要包含自己写的头文件,还有一些标准库的头文件比如说stdio.h等等。在编译的预处理阶段,预处理程序会将这些头文件的内容插到相应的include指令处,现在的问题是编译器是如何找到这些头文件的。

     1. 在编译时,我们可以用-I(i的大写)选项来指定头文件所在的目录,如:test.h

Struct student  
    {  
        int  age;  
    }; 
    main.c 内容如下
    #include<stdio.h>  
    #include<test.h>  
    int main()  
    {  
        structstudent st;  
        st.age= 25;  
        printf(“st.age=%d\n”,st.age);  
        return0;  
    }  

可以把test.h放在与main.c同一个目录下,编译命令如下:gcc -o main main.c -l ./
而如果用gcc编译的话: gcc -o main main.c     提示如下:main.c:2:19: 致命错误: test.h:没有那个文件或目录
编译中断。
现在我们把test.h文件放在include文件中,编译命令如下:
thinkpad@thinkpad:~/C_Pro/tftest$ gcc -o main main.c -I /home/thinkpad/C_Pro/tftest/include/
如此便可以找到头文件了,当然如果头文件比较多的话都可以放在include的文件夹内。
这里可以简单记一下命令:gcc -o 可执行文件 源文件 -I 路径

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

2.链接动态库
GNU gcc的编译工具用法
编写hello.的文件,

#include <stdio.h>
void print_hello() {
  printf("Hello World\n");
}  

hello.c是我们的动态共享库,在hello.c里面我们声明和实现了各种公用的函数,最后main.c可以去调用这些公用函数。首先我们要把hello.c编译成为动态共享库:
thinkpad@thinkpad:~/C_Pro/linkpath$ gcc -o libhello.so -shared -fPIC hello.c
    -fPIC参数声明链接库的代码段是可以共享的,-shared参数声明编译为共享库。请注意这次我们编译的共享库的名字叫做libhello.so,这也是Linux共享库的一个命名的惯例了:后缀使用so,而名称使用libxxxx格式。
然后编译main.c的时候,我们需要更多的参数让gcc知道如何寻找共享库:
thinkpad@thinkpad:~/C_Pro/linkpath$ gcc -o main main.c -L ./ -lhello
-L参数指定到哪个附加路径下面去寻找共享库,现在我们指定在当前目录下面寻找;----路径的意思
-l参数指定链接到哪个共享库上面,我们传的参数hello,那么gcc就会自动链接到libhello.so这个共享库上面(注意我们上面说的libXXXX.so命名规则);----l链接到某个文件的意思。
-I参数指定到哪个附加路径下面去寻找h文件,这个我们没有使用。-----这个是寻找头文件的时候使用的。
最后我们成功编译好了main,执行一下,报错:
./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
为什么会这样呢 ?
找不到libhello.so这个共享库,怎么回事?这是因为libhello.so并不在操作系统默认的共享库的路径下面,我们可以临时指定一下链接路径:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 也可以直接修改环境变量
这样就成功了。我们用ldd main看一下: 

linux-gate.so.1 =>  (0xb77a4000)
	libhello.so => ./libhello.so (0xb779f000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75e5000)
	/lib/ld-linux.so.2 (0xb77a5000)




<think>我们正在配置aarch64-linux-gnu-gcc交叉编译器的动态库和头文件搜索路径。在交叉编译,我们需要确保编译器能够找到目标架构(aarch64)的头文件和库,而不是宿主机的(x86_64)。通常,我们可以通过环境变量(如LIBRARY_PATH、C_INCLUDE_PATH)编译选项(如-I、-L)来指定。 根据引用[3],我们知道交叉编译工具链的典型路径为: /usr/bin/aarch64-linux-gnu-gcc /opt/toolchains/aarch64-linux-gnu/bin/aarch64-none-linux-gnu-gcc 在Ubuntu中,通过安装`gcc-aarch64-linux-gnu`包,我们可以得到aarch64-linux-gnu-gcc。通常,相关的头文件和库会安装在`/usr/aarch64-linux-gnu`目录下。 但是,有我们可能需要使用自定义路径(比如自己编译的库)。因此,配置方法有两种: 1. 通过环境变量设置(全局会话级) 2. 在编译命令中通过选项指定(针对每次编译) 步骤: 1. 确定交叉编译工具链的安装路径和对应的库路径、头文件路径。 在Ubuntu中,默认安装的aarch64交叉编译器,其库和头文件通常位于: 头文件:/usr/aarch64-linux-gnu/include 库文件:/usr/aarch64-linux-gnu/lib 如果使用自定义路径(如引用[2]中提到的`--prefix`指定),则路径可能不同。 2. 配置环境变量(可选,方便多次编译): 在`~/.bashrc`当前shell中设置: export CROSS_COMPILE=aarch64-linux-gnu- export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ # 头文件搜索路径 export C_INCLUDE_PATH=/usr/aarch64-linux-gnu/include:$C_INCLUDE_PATH export CPLUS_INCLUDE_PATH=/usr/aarch64-linux-gnu/include:$CPLUS_INCLUDE_PATH # 库搜索路径(链接) export LIBRARY_PATH=/usr/aarch64-linux-gnu/lib:$LIBRARY_PATH # 运行动态库路径(可选,用于运行在目标板上的程序,在宿主机上交叉编译一般不需要设置) export LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib:$LD_LIBRARY_PATH 注意:如果使用自定义路径(如自己编译的glib库放在/home/zk/1111/bluez/glib_install),则需要将自定义路径加入上述环境变量。 3. 在编译命令中显式指定(推荐,避免污染环境): 使用`-I`指定头文件路径,`-L`指定库文件路径,`-Wl,-rpath`指定运行库路径(如果需要)。 例如: aarch64-linux-gnu-gcc -I/home/zk/1111/bluez/glib_install/include -I/usr/aarch64-linux-gnu/include \ -L/home/zk/1111/bluez/glib_install/lib -L/usr/aarch64-linux-gnu/lib \ -Wl,-rpath=/home/zk/1111/bluez/glib_install/lib \ -o my_program my_program.c -lglib-2.0 4. 验证配置: 可以通过以下命令查看编译器默认搜索路径: aarch64-linux-gnu-gcc -print-search-dirs aarch64-linux-gnu-gcc -print-sysroot 注意:如果使用了`--sysroot`选项(如引用[2]中提到的配置),则可以通过`-sysroot`指定一个根目录,该目录下包含目标系统的头文件和库。例如: aarch64-linux-gnu-gcc --sysroot=/mincom/minicomlibAarch64/ ... 5. 如果使用pkg-config,可以设置PKG_CONFIG_PATH环境变量来指定交叉编译库的.pc文件路径。 例如,如果自定义的glib库安装在/home/zk/1111/bluez/glib_install,则: export PKG_CONFIG_PATH=/home/zk/1111/bluez/glib_install/lib/pkgconfig:$PKG_CONFIG_PATH 然后使用: aarch64-linux-gnu-gcc `pkg-config --cflags --libs glib-2.0` -o my_program my_program.c 6. 注意:交叉编译,可能需要使用目标系统的头文件,而不是宿主机的。因此,确保安装有aarch64架构的库和头文件。在Ubuntu中,可以通过安装`lib<name>-dev:arm64`包来获取。例如: sudo apt install libglib2.0-dev:arm64 这样,头文件和库就会安装在`/usr/aarch64-linux-gnu`下。 总结: 配置交叉编译环境的关键是让编译器找到目标架构的头文件和库。我们可以通过环境变量编译选项来指定路径。推荐在编译命令中显式指定,以避免环境变量带来的意外影响。 相关问题: 1. 如何安装aarch64-linux-gnu交叉编译工具链? 2. 在交叉编译,如何管理多个库的依赖关系? 3. 如何为交叉编译环境创建sysroot?</think>### 配置 aarch64-linux-gnu-gcc 的动态库和头文件路径 在 Ubuntu 中为 aarch64-linux-gnu-gcc 交叉编译器配置动态库和头文件路径,需要解决两个核心问题: 1. **头文件搜索路径**:编译查找头文件的位置 2. **动态库搜索路径**:链接器和运行加载器查找共享库的位置 --- ### 解决方案 #### 1. **永久配置路径(推荐)** 在系统级配置文件中添加路径,适用于所有项目: ```bash # 编辑链接器配置文件 sudo nano /etc/ld.so.conf.d/aarch64-linux-gnu.conf # 添加以下内容(根据实际路径修改): /usr/aarch64-linux-gnu/lib /opt/toolchains/aarch64-linux-gnu/lib # 自定义路径[^3] # 更新动态链接器缓存 sudo ldconfig # 设置头文件路径(添加到bashrc) echo 'export C_INCLUDE_PATH="/usr/aarch64-linux-gnu/include:$C_INCLUDE_PATH"' >> ~/.bashrc echo 'export CPLUS_INCLUDE_PATH="/usr/aarch64-linux-gnu/include:$CPLUS_INCLUDE_PATH"' >> ~/.bashrc source ~/.bashrc ``` #### 2. **临配置路径(单次编译)** 在编译命令中直接指定路径: ```bash aarch64-linux-gnu-gcc your_program.c -o output \ -I/usr/aarch64-linux-gnu/include \ # 头文件路径 -L/usr/aarch64-linux-gnu/lib \ # 库文件路径[^1] -Wl,-rpath=/usr/aarch64-linux-gnu/lib \ # 运行库路径 -l<your_library> # 链接的库名 ``` #### 3. **验证配置** 检查路径是否生效: ```bash # 查看头文件搜索路径 aarch64-linux-gnu-gcc -xc -E -v - # 查看库搜索路径 aarch64-linux-gnu-gcc -print-search-dirs # 验证动态库路径 aarch64-linux-gnu-readelf -d your_program | grep RPATH ``` --- ### 关键路径说明 | 路径类型 | 默认路径 | 说明 | |---------|---------|------| | **头文件** | `/usr/aarch64-linux-gnu/include` | ARM64架构标准头文件 | | **静态库** | `/usr/aarch64-linux-gnu/lib` | 静态链接库位置 | | **动态库** | `/usr/aarch64-linux-gnu/lib` | 共享库位置[^3] | | **工具链** | `/usr/bin/aarch64-linux-gnu-gcc` | 默认交叉编译器路径 | > **注意**:自定义安装的工具链路径可能为 `/opt/toolchains/aarch64-linux-gnu/bin/aarch64-none-linux-gnu-gcc`[^3],需相应调整上述路径 --- ### 常见问题处理 1. **找不到库文件** 添加 `-L` 指定库路径: ```bash -L/your/custom/lib/path -lyourlib ``` 2. **运行加载失败** 编译添加 `-Wl,-rpath`: ```bash -Wl,-rpath=/target/runtime/lib/path ``` 3. **头文件缺失** 使用 `-I` 指定路径: ```bash -I/your/custom/include/path ``` --- ### 配置示例 ```mermaid graph LR A[源文件] --> B[编译器] B --> C[头文件路径 -I] B --> D[库文件路径 -L] D --> E[链接阶段] E --> F[可执行文件] F --> G[运行路径 -rpath] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值