`

Linux下gcc编译中关于头文件与库文件搜索路径相关问题(一)

阅读更多

在交叉编译的时候我们需要用到其他的库,在 config 时候可以通过 “-I” 来指定头文件目录,但是每次都需要设置的话难免有些麻烦,找到一个简单的方法。看下文的红色部分。

有大量的环境变量可供设置以影响 GCC 编译程序的方式。利用这些变量的控制也可使用合适的命令行选项。一些环境变量设置在目录名列表中。这些名字和 PATH 环境变量使用的格式相同。特殊字符 PATH_SEPARATOR (安装编译程序的时候定义)用在目录名之间。在 UNIX 系统中,分隔符是冒号,而 Windows 系统中为分号。

C_INCLUDE_PATH

编译 C 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -isystem 选项一样。会首先查找 -isystem 指定的所有目录。
==>
也见 CPATH CPLUS_INCLUDE_PATH OBJC_INCLUDE_PATH


COMPILER_PATH
该环境变量指定一个或多个目录名列表,如果没有指定 GCC_EXEC_PREFIX 定位子程序,编译程序会在此查找它的子程序。

==>
也见 LIBRARY_PATH GCC_EXEC_PREFIX -B 命令行选项。


CPATH
编译 C C++ Objective-C 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -l 选项一样。会首先查找 -l 指定的所有目录。

==>
也见 C_INCLUDE_PATH CPLUS_INCLUDE_PATH OBJC_INCLUDE_PATH


CPLUS_INCLUDE_PATH
编译 C++ 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -isystem 选项一样。会首先查找 -isystem 指定的所有目录。
==>
也见 CPATH C_INCLUDE_PATH OBJC_INCLUDE_PATH


DEPENDENCIES_OUTPUT
为文件名设置该环境变量会让预处理程序将基于依赖关系的 makefile 规则写入文件。不会包括系统头文件名字。

如果环境变量设置为单名,被看作是文件名字,而依赖关系规则的名字来自源文件名字。如果定义中有两个名字,则第二个名字是用作依赖关系规则的目标名。 设置该环境变量的结果和使用命令行选项 -MM -MF -MT 的组合是一样的。

==>
也见 SUNPRO_DEPENDENCIES

GCC_EXEC_PREFIX
如果定义了该环境变量,它会作为编译程序执行的所有子程序名字的前缀。例如,如果将变量设置为 testver 而不是查找 as ,汇编器首先会在名字 testveras 下查找。如果在此没有找到,编译程序会继续根据它的普通名进行查找。可在前缀名中使用斜线指出路径名。


GCC_EXEC_PREFIX
的默认设置为 prefix /lib/gcc-lib/ ,这里的 prefix 是安装编译程序时 configure 脚本指定的名字。该前缀也用于定位标准连接程序文件,包含进来作为可执行程序的一部分。

如果使用 -B 命令行选项,会重写该设置。

==>
也见 COMPILER_PATH

LANG
该环境变量用于指出编译程序使用的字符集,可创建宽字符文字、串文字和注释。
定义 LANG C-JIS ,指出预处理程序将多字节字符按照 JIS (日语工业标准)字符进行解释。 C-SJIS 可用来指出 Shift -JIS 字符而 C-EUCJP 指出日文 EUC

如果没有定义 LANG ,或定义为不可识别,函数 mblen() 被用来确定字符宽度,而 mbtowc() 用来将多字节序列转换为宽字符。

LC_ALL
如果设置,该环境变量的值重写 LC_MESSAGES LC_CTYPE 的所有设置。

LC_CTYPE
该环境变量指出引用串中定义的多字节字符的字符分类。主要用于确定字符串的字符边界,字符编码需要用引号或转义符,可被错误地解释为字符串的结尾或特殊字 符串。对 Australian English ,可将它设置为 en_AU Mexican Spanish ,可将它设置为 es_MX 。如果没有设置该变量,默认为 LANG 变量的值,或如果没有设置 LANG ,那就使用 C 英语行为。也见 LC_ALL

LC_MESSAGES
该环境变量指出编译程序使用何种语言发出诊断消息。对 Australian English ,可设置为 en_AU MexicanSpanish ,可设置为 es_MX 。如果变量没有设置,使用 LANG 变量的默认值,或如果没有设置 LANG ,那就使用 C 英语行为。也见 LC_ALL

LD_LIBRARY_PATH
该环境变量不会影响编译程序,但程序运行的时候会有影响。变量指定一个目录列表,程序会查找该列表定位共享库。只有当未在编译程序的目录中找到共享库的时候,执行程序必须设置该变量。

LD_RUN_PATH
该环境变量不会影响编译程序,但程序运行的时候会有影响。该变量在运行时指出文件的名字,运行的程序可由此得到它的符号名字和地址。地址不会重新载入,因而可能符号引用其他文件中的绝对地址。这和 ld 工具使用 -R 选项完全一样。


LIBRARY_PATH
该环境变量可设置为一个或多个目录名字列表,连接程序会搜寻该目录,以查找特殊连接程序文件,和由 -l (字母 l )命令行选项指定名字的库。 -L 命令行选项指定的目录在环境变量的前面,首先被查找。

==>
也见 COMPILER_PATH

OBJC_INCLUDE_PATH
在编译 Objective-C 程序的时候使用该环境变量。一个或多个目录名的列表由环境变量指定,用来查找头文件,就好像在命令行中指定 -isystem 选项一样。所有由 -isystem 选项指定的目录会首先被查找。

==>
也见 CPATH CPLUS_INCLUDE_PATH C_INCLUDE_PATH


SUNPRO_OUTPUT
为文件名设置该环境变量会令预处理程序将基于依赖关系的 makefile 规则写入文件。会包含系统头文件名。 如果环境变量被设置为单个名字,它将会被当作文件名,依赖关系规则中的名字将由源文件的名字中获得。如果定义中有两个名字,第二个名字就是依赖关系规则中的目标名。 设置该环境变量的结果与在命令行中使用参数 -M -MF -MT 的效果一样。

==>
参见 DEPENDENCIES_OUTPUT

TMPDIR
这个变量包含了供编译程序存放临时工作文件的目录的路径名。这些文件通常在编译过程结束时被删除。这种文件的一个例子就是由预处理程序输出并输入给编译程序的文件。

linux 默认的 include 在哪 ?

#include <linux/module.h> 中的 module.h 默认是在哪个目录下呢?我在 /usr/include/linux 下并没有找到这个文件。

另外想问一下,不同内核版本的 linux 头文件是不是一样的。比如:我在 2.6.20 内核的系统上,用 2.6.10 的头文件会不会有问题。

 

网友回复 :

1

我的 module.h 是在 内核编译好了的目录下的,不是在 /usr/include/linux 下,

2

2.6.20 内核的系统上,用 2.6.10 的头文件应该会有问题,内核的头文件和 当前系统运行的内核不一致。

 

网友回复 : 你引用的是内核下的头文件 .

不在 /usr/include .

: /usr/src/kernels/2.6.18-8.el5-x86_64/include/linux/module.h 下面 ... 中间的版本号是不一样的 ... 你选你的就行了 ..

 

网友回复 : 请问楼上为什么是在 /usr/src/kernels/2.6.18-8.el5-x86_64/include/linux/module.h 呢?我查了一下环境变量,没有看到关于头文件的环境变量。 gcc 是如何知道头文件的位置的?

 

网友回复 : 这个问题很好,

你需要看看 linux kernel Makefile 文件了。在什么地方找头文件,它说了算。:)

 

网友回复 : 你的程序是驱动之类的内核层的吧?

它调用的头文件就应该是内核源码里面的 include 了。一般的系统都把内核源码放在 /usr/src 下面,假如是自己编译的内核的话,也可以放在别处的。 至于 gcc 到哪里去找头文件,就看 makefile 了,或者直接用 gcc 命令的话,要加上 -I 来指定目录。

 

网友回复 : 楼上,可是我的 makefile 里没有指定 include 呀, gcc 是怎么找到头文件的?

 

网友回复 :gcc 是怎么找到头文件的?

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

回答了这个问题, LZ 就明白了一切了, GCC 找头文件有三种策略:

1. 会在默认情况下指定到 /usr/include 文件夹 ( 更深层次的是一个相对路径, GCC 可执行程序的路径是 /usr/bin ,那么它在实际工作时指定头文件头径是一种相对路径方法,换算成绝对路径就是 /usr/include)

2.GCC 还使用了 -I 指定路径的方式,这一点大家都知道

3. 还可以使用一个参数来指示 GCC 不搜索系统默认路径,这个参数我忘了,你搜一下就知道了

 

在编译驱动模块时,由于非凡的需求必须强制 GCC 不搜索系统默认路径,也就是不搜索 /usr/include ,要自己用 -I 参数来指定内核头文件路径,这个时候必须在 Makefile 中指定两个参数,一个是内核头文件路径,一个是强制 GCC 不搜索系统默认路径。在编译内核时,必须使用一个参数 ( 强制 GCC 不搜索系统默认路径 ) ,否则就会引起混乱。

分享到:
评论

相关推荐

    Linux下gcc编译中关于头文件与库文件搜索路径相关问题.pdf

    Linux 下 gcc 编译中的头文件与库文件搜索路径相关问题 Linux 下的 gcc 编译中,头文件和库文件的搜索路径是编译器在编译过程中查找头文件和库文件的路径。编译器会在指定的目录中查找头文件和库文件,如果没有找到...

    GCC的默认头文件路径和库文件

    ### GCC的默认头文件路径和库文件 #### 概述 GCC(GNU Compiler Collection)是GNU项目的一部分,它提供了一套强大的工具链,用于多种编程语言的编译工作,其中包括C、C++、Objective-C等。本文将详细介绍Linux...

    linux下GCC编译C程序

    【GCC编译C程序】是Linux环境中开发C语言软件的核心环节。GNU编译器集(GCC),最初称为GNU C编译器,由Richard Stallman在1987年发起,旨在构建符合自由软件理念的编译器,用于构建GNU项目中的其他软件。GCC很快因...

    头文件包含及库的链接路径问题

    本文将详细介绍在Linux环境下,GCC/G++如何查找头文件和链接库文件,并提供相应的配置方法。 #### 二、头文件路径 ##### 1. 默认路径 当GCC/G++在Linux下编译C/C++程序时,默认会搜索以下路径来查找头文件: - `/...

    arm-linux-gcc编译选项.pdf

    以下是arm-linux-gcc编译选项的详细知识点说明: 1. 编译过程的四个阶段: - 预处理阶段:GCC会对源文件进行预处理,展开宏定义、处理条件编译指令、包含头文件等。 - 编译阶段:经过预处理的源文件会被转化为...

    linux中gcc4.8.5,下载解压即可直接使用,linux系统GCC编译

    Linux中的GCC(GNU Compiler Collection)是开源的、跨平台的编译器套件,用于将C、C++、Fortran、Objective-C等编程语言的源代码编译为可执行文件。GCC 4.8.5是该系列的一个稳定版本,发布于2015年,虽然不是最新版...

    arm-linux-gcc-4.4.3

    在压缩包文件"opt"中,通常包含了整个交叉编译工具链的安装目录,包括bin目录下的可执行文件(如`arm-linux-gcc`)、lib目录下的库文件以及include目录下的头文件。解压后,根据上述步骤配置好环境,即可开始进行...

    arm-linux-gcc-5.4.0交叉编译工具.rar

    - **库路径和头文件**:确保链接和包含正确的库和头文件,这些通常位于交叉编译工具链的安装目录下。 - **依赖项检查**:确保所有依赖项都适合目标系统,包括库和运行时环境。 总结来说,`arm-linux-gcc-5.4.0`是一...

    arm-linux-gcc-5.4.0.tar.gz

    在Linux系统中,交叉编译是一项重要的技能,特别是在嵌入式开发领域,因为目标设备(如ARM架构的设备)可能无法直接运行用于构建软件的完整编译环境。`arm-linux-gcc`是针对ARM架构的Linux系统进行交叉编译的GCC...

    交叉编译libvpx源码后 生成的头文件和库 android使用

    6. **集成到Android项目**:将生成的头文件和库文件添加到Android项目的jniLibs目录下,根据不同的ABI(armeabi-v7a, arm64-v8a, x86, x86_64等)放入对应的子目录。然后在Android Studio的CMake配置中引入头文件和...

    gcc编译数据库1

    GCC编译数据库并不是一个传统意义上的数据库,而是一种存储项目编译指令的数据结构或文件格式,通常用于记录编译过程中使用的命令行选项。这种数据库有助于自动化工具理解如何编译项目中的每个源文件,从而简化了...

    linux mircal静态库以及头文件

    5. **makefile**:在大型项目中,使用`Makefile`可以自动化编译过程,包括库文件和头文件的路径设置。 通过理解这些概念和操作,你就能更有效地在Linux环境下使用和管理静态库及头文件,从而提升软件开发的效率。

    Linux下如何用GCC编译动态库.docx

    总之,理解如何在Linux下使用GCC编译动态库对于软件开发者而言至关重要,因为它可以帮助我们构建可扩展、高效且易于维护的软件。通过掌握创建和使用库的技巧,开发者可以更好地利用现有的开源工具和组件,提高开发...

    mips-linux-gcc大端

    这个文件名可能是指一个包含MIPS 32位架构相关资源的压缩包,比如头文件、库文件或编译器本身。解压后,用户可以利用这些资源来构建他们的MIPS交叉编译环境,特别是对于32位MIPS架构的大端模式应用。 总结来说,...

    GD32F407-GCC编译模板,包含配置文件

    5. **头文件和库**:可能包含GD32F407的HAL(硬件抽象层)库和CMSIS(Cortex Microcontroller Software Interface Standard)库,这些库提供了访问芯片外设和功能的函数接口。 6. **源代码**:项目中的C或C++源代码...

    arm-linux-gcc交叉编译器适用 ARMV7-32

    1. **获取编译器**:从提供的压缩包`gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf`中解压,这包含了一个完整的交叉编译环境。Linaro是一个开源组织,它提供了优化过的GCC版本,以提升ARM平台的性能。 2. *...

    mipsel-linux-gcc

    压缩包中的"mipsel32"可能包含了MIPS小端模式的32位交叉编译工具链的完整组件,如库、头文件和可执行程序,可供开发者在本地环境中设置并使用。安装和使用这些工具通常涉及解压、配置路径和可能的系统调整。通过熟练...

    linux-arm-gcc-4.9.2交叉编译工具

    Linux ARM GCC 4.9.2交叉编译工具是一个针对ARM架构在Linux系统上进行编译的工具链,主要用于在非ARM平台(如x86)上构建适用于ARM设备的应用程序或操作系统。这个版本的GCC(GNU Compiler Collection)是4.9.2,是...

    aarch64-linux-gnu-gcc gcc version 7.5.0 (Linaro GCC 7.5-2019.12

    标题中的"aarch64-linux-gnu-gcc"是一个交叉编译器,用于在aarch64(也称为ARM64或AArch64)架构上构建Linux应用程序。它基于GNU工具链,是GCC(GNU Compiler Collection)的一个特定版本,这里是7.5.0,由Linaro...

Global site tag (gtag.js) - Google Analytics