Toolchain
GCC
- -ffunction-sections
用于生成具有函数级别粒度的目标文件,并在链接过程中对这些函数进行分组。这个选项的主要作用是在优化和链接阶段提供更多的灵活性和控制,以减小最终可执行文件的大小和提高执行效率.未使用的函数不会被包括在最终的可执行文件中. 通常需要结合使用 -Wl,--gc-sections 链接器选项
-fno-jump-tables 用于控制编译器是否生成跳转表(jump tables).编译器会根据条件语句的情况(例如switch语句)生成跳转表,以提高条件分支的效率
**-fno-common ** 是一个用于改变全局变量内存分配行为的编译选项,它可以提高代码的可维护性、可移植性和清晰度,但可能需要对现有代码进行一些调整。
-fdata-sections
用于将全局和静态变量分配到单独的数据节中,以提高可维护性、减小可执行文件大小,并提供更多的灵活性。这个选项通常在嵌入式系统开发和对代码大小敏感的应用中非常有用
-fsigned-char C语言标准规定char类型可以是有符号或无符号的,具体取决于编译器实现。用于显式指定char类型为有符号字符,以提高代码的可移植性和消除不同编译器的行为差异
-fmessage-length=0 用于指定在编译过程中生成的错误和警告消息的最大长度。设置为0表示不限制消息的长度,即允许生成任意长度的错误和警告消息。 通常,编译器生成的错误和警告消息是根据代码中的问题或警告而生成的,以便程序员能够更容易地理解和解决这些问题。限制消息的长度有助于确保消息不会变得过长,但可能会导致信息不完整或不清晰。
**-Wall **
选项启用了一系列常见的编译警告,这些警告通常涵盖了一些常见的编程错误、潜在的问题和不良实践。一些常见的警告包括但不限于以下内容: 未使用的变量:警告您是否声明了但未使用的变量。 类型不匹配:警告关于不匹配的类型转换或参数类型不匹配的问题。 未声明的函数:警告您是否调用了未声明的函数。 编译器扩展:警告您是否使用了编译器特定的扩展。 不可达的代码:警告不可达的代码块或语句。 签名不匹配:警告符号或函数的签名不匹配问题。
- -Wchar-subscripts
这个警告的目的是提醒开发人员使用char类型作为数组下标可能会导致以下问题: 符号扩展问题:char类型可能是有符号的,当用作数组下标时,如果值小于零,可能会发生符号扩展。这可能导致访问数组的错误位置。 范围问题:char类型的范围通常很小,通常为-128到127或0到255,这可能无法表示大型数组的索引。 可移植性问题:不同平台上的char类型的有符号性质可能不同,因此代码的行为可能会因编译器和平台的不同而有所不同。 例如使用int或size_t类型作为数组下标,以确保正确性和可移植性。
- **-Wformat ** 用于生成关于格式化字符串和参数的警告。这个选项有助于检测和预防在C和C++代码中常见的格式化字符串错误。帮助识别可能导致运行时错误或安全漏洞的格式化字符串错误。这对于编写健壮和安全的C和C++代码非常重要,尤其是在处理用户输入时。 警告的类型通常包括以下内容:
格式化字符串不匹配参数:编译器检测到格式化字符串中的格式说明符与实际传递给函数的参数不匹配。例如,如果格式字符串中要求整数,但参数是字符串,将生成警告。
格式化字符串中的参数过多或过少:编译器检测到格式化字符串中的格式说明符的数量与实际传递给函数的参数数量不匹配。这可能导致未定义的行为。
潜在的格式化字符串漏洞:编译器可以检测到潜在的格式化字符串漏洞,如使用不安全的%s格式说明符和缺少参数的情况。
可变参数函数的使用错误:警告可能涉及使用printf和scanf等可变参数函数时的错误用法,因为这些函数对于格式化字符串和参数数量非常敏感。
- -Wignored-qualifiers 用于生成警告,指出在变量、指针或函数返回类型中忽略了限定符(qualifiers)。限定符包括const、volatile、restrict等,它们用于描述变量或指针的属性或限制对它们的操作。
忽略const限定符:编译器检测到代码中存在忽略const限定符的情况,即尝试修改被声明为const的数据。
忽略volatile限定符:编译器检测到代码中存在忽略volatile限定符的情况,即尝试执行可能被编译器优化的操作,而不考虑volatile修饰的数据可能会在外部更改。
忽略restrict限定符:编译器检测到代码中存在忽略restrict限定符的情况,即可能存在多个指针操作同一块内存区域,而没有考虑restrict的要求。
- **-fstrict-volatile-bitfields ** 用于启用严格的volatile位字段访问规则。volatile关键字通常用于告知编译器不要对带有volatile修饰的变量进行优化,以确保对这些变量的访问是准确的,而不会被编译器优化掉。
-fstrict-volatile-bitfields 选项的目的是确保对带有volatile修饰的位字段(bitfields)的访问是严格的,不会受到编译器的非预期优化影响。这对于一些嵌入式系统或对内存布局有特殊要求的应用可能非常有用。
在C语言中,位字段允许您将多个字段打包到一个单独的整数中,以节省内存。然而,当使用volatile修饰位字段时,编译器需要确保对这些字段的访问是原子的,不会被优化掉。使用-fstrict-volatile-bitfields 可以强制编译器遵循这些规则。
-fvisibility=hidden 用于指定代码的符号(函数和变量)的可见性,以便在共享库和动态链接时控制符号的可见性。使用 -fvisibility=hidden 选项时,通常还需要在需要外部访问的符号上使用特殊的修饰符(例如 attribute((visibility("default"))))来明确指定它们的可见性,以便它们仍然可以被外部代码访问
-nostartfiles
通过使用 选项,您告诉编译器不链接标准的启动文件,从而禁用了默认的启动过程。这意味着您需要提供自己的启动代码或者确保程序的启动和初始化是在其他方式下进行的。这对于一些特定的开发场景非常有用,但需要小心处理,因为它需要开发人员自己负责管理启动过程。
- -fshort-enums
是GCC(GNU Compiler Collection)编译器的一个编译选项,用于将枚举类型的存储大小限制为较小的整数类型。默认情况下,GCC会将枚举类型的存储大小与int类型相同,但使用 -fshort-enums 可以将其减小到较小的整数类型,以减小内存占用。
-Wno-error=unused-variable 用于取消针对未使用变量的警告的严格错误(error)。默认情况下,GCC 会将未使用的变量标记为警告,并将这些警告视为编译错误,这意味着编译过程会失败。使用 -Wno-error=unused-variable 可以将这些警告取消,使它们不再被视为错误,而只是警告。
-Wno-error=format= 是GCC(GNU Compiler Collection)编译器的一个编译选项,用于取消与格式化字符串和参数相关的警告作为错误的设置。格式化字符串和参数的警告通常用于检测潜在的格式化字符串错误,例如格式说明符与参数不匹配等问题。默认情况下,这些警告被视为错误,这意味着编译过程将失败。使用 -Wno-error=format= 可以将这些警告取消,以便它们只作为警告而不是错误。
-Wno-unused-function 是GCC(GNU Compiler Collection)编译器的一个编译选项,用于取消与未使用函数相关的警告。默认情况下,GCC会将未使用的函数标记为警告,并将这些警告视为编译错误,这意味着编译过程会失败。使用 -Wno-unused-function 可以将这些未使用函数的警告取消,使它们只作为警告而不是错误。
-Wunused-but-set-variable 是GCC(GNU Compiler Collection)编译器的一个编译选项,用于生成与被设置但未使用的变量相关的警告。这个选项通常用于检测在代码中存在的设置变量,但后续未使用这些变量的情况。默认情况下,这些警告被视为警告级别,而不是错误。
-Wuninitialized 是GCC(GNU Compiler Collection)编译器的一个编译选项,用于生成与未初始化变量相关的警告。未初始化的变量可能包含不确定的值,这可能导致未定义的行为或编程错误。这个选项的目的是帮助开发人员发现未初始化变量的问题。
TIP
-Wall:启用所有常见的警告。这是一个综合性的选项,用于启用多种警告,以帮助识别潜在的问题。 -Wextra:启用额外的警告,包括一些比较特定的警告。通常与 -Wall 一起使用。 -Werror:将警告视为错误,这意味着编译过程会在生成警告时失败。 -Wno- 是要禁用的警告名称或选项。 -Wformat:生成与格式化字符串和参数相关的警告,以检测潜在的格式化字符串错误。 -Wuninitialized:生成与未初始化变量相关的警告,以帮助发现可能导致未定义行为的问题。 -Wunused:生成与未使用的变量、函数或参数相关的警告,以帮助识别不必要的代码。 -Wshadow:生成与变量遮蔽(shadowing)相关的警告,以帮助发现可能导致混淆的问题。 -Wconversion:生成与类型转换相关的警告,以检测可能导致数据丢失或不正确行为的情况。 -Wswitch:生成与switch语句相关的警告,以确保所有情况都被覆盖。 -Wunused-parameter:生成与未使用的函数参数相关的警告。 -Wno-error:用于取消特定警告作为错误的设置,允许它们只作为警告而不是错误。 -Wl,--cref GNU链接选项。
具体来说,-Wl 选项允许将参数传递给链接器(ld)。在这种情况下,--cref 是链接器(ld)的一个选项,而不是编译器的选项。--cref 选项用于生成交叉引用(cross-reference)报告,以便您可以查看可执行文件中的符号之间的引用关系。
与位置无关的代码
- compile_options
-fpic -msingle-pic-base -mpic-register=9 -fno-jump-tables -ffreestanding
-fpic -msingle-pic-base -mpic-register=9 -fno-jump-tables -ffreestanding
- link_options
-nostartfiles -fpic -msingle-pic-base -mpic-register=9
-nostartfiles -fpic -msingle-pic-base -mpic-register=9
架构
-march
是GCC(GNU Compiler Collection)编译器的一个编译选项,用于指定目标架构或目标处理器的体系结构。这个选项允许您生成与特定架构兼容的代码,以优化代码的性能和执行效率。
-march
后面通常会跟随特定的目标架构名称,例如:
-march=armv7-a
:指定生成针对 ARMv7-A 架构的代码。-march=x86-64
:指定生成针对 x86-64(64位 x86)架构的代码。-march=power9
:指定生成针对 IBM POWER9 处理器架构的代码。
通过选择适当的目标架构,编译器可以生成与该架构兼容的代码,以充分利用该架构的特性和性能优势。这可以提高代码的执行效率,特别是在嵌入式系统、服务器应用和高性能计算等领域。
需要注意的是,选择正确的 -march
选项通常需要考虑目标硬件平台的支持。不同的硬件平台可能具有不同的支持架构,因此在选择 -march
选项时,需要确保它与目标硬件兼容。
此外,GCC 还提供其他相关选项,如 -mtune
,用于指定优化代码以适应特定处理器型号的选项。-march
通常用于选择整体的目标架构,而 -mtune
用于更具体的微体系结构优化。
ABI
-mabi
是GCC(GNU Compiler Collection)编译器的一个编译选项,用于指定目标架构的二进制接口(ABI,Application Binary Interface)。ABI 定义了不同的软件组件如何协同工作,包括函数调用约定、寄存器使用、数据结构布局和其他与二进制兼容性相关的规则。
通过使用 -mabi
选项,您可以告诉编译器生成与特定 ABI 兼容的代码,以确保代码与目标平台上的其他组件正确协同工作。
一些常见的 -mabi
选项和示例包括:
-mabi=aapcs
:指定使用 ARM 架构的 AAPCS(ARM Architecture Procedure Call Standard)ABI。-mabi=sysv
:指定使用 x86 架构的 System V ABI。-mabi=eabi
:指定使用嵌入式系统的 EABI(Embedded Application Binary Interface)ABI。-mabi=64
:指定使用 64 位架构的默认 ABI。
选择正确的 ABI 取决于目标架构和操作系统。不同的架构和操作系统可能使用不同的 ABI,因此在编译时指定正确的 ABI 是非常重要的。否则,将会导致二进制不兼容性,代码无法正确地与其他组件协同工作。
链接器规范文件(linker specification)。`nosys.specs)
- --specs=nosys.specs
嵌入式系统和无操作系统环境:
nosys.specs
主要用于嵌入式系统开发,链接器不会默认链接标准C库,以便在没有标准C库(如libc)支持的情况下进行链接,特别是在没有标准操作系统支持的情况下。在这些环境中,通常需要精确控制程序的启动和初始化过程,需要自己提供适当的启动代码中断处理例程和低级硬件驱动程序。而无需依赖标准C库。
- --specs=nano.specs
是使用 newlib-nano .这个规范文件有助于减小程序的内存占用和提供更轻量级的运行时支持旨在提高嵌入式系统和小型设备的内存效率。它采用了一种精简的运行时库,并仅包括最基本的C库功能。这有助于减小生成的可执行文件的大小。