当前位置: 首页 > news >正文

GCC编译/连接/优化等选项

1. GCC编译/连接/优化等选项

  • 1. GCC编译/连接/优化等选项
    • 1.1. 简介
    • 1.2. 常用选项
      • 1.2.1. -c -E -S -o
      • 1.2.2. -L<path> -l<library>
      • 1.2.3. -D<macro>
      • 1.2.4. -I<path>
    • 1.3. 代码生成和优化
      • 1.3.1. -std=<standard>
      • 1.3.2. -shared
      • 1.3.3. -fPIC
      • 1.3.4. -static
      • 1.3.5. -O0 -O1 -O2 -O3 -Os
      • 1.3.6. -ffunction-sections-fdata-sections
    • 1.4. 调试与警告选项
      • 1.4.1. -g -ggdb
      • 1.4.2. -Wall -Werror -Wextra
      • 1.4.3. -Wno-pointer-sign
      • 1.4.4. -fno-strict-aliasing -fstrict-aliasing
    • 1.5. 安全与连接选项
      • 1.5.1. -z noexecstack -z relro -z now
      • 1.5.2. -Wl,option
      • 1.5.3. -Wl,--strip-all,--gc-sections,--as-needed
      • 1.5.4. -Wl,--verbose,-soname,<name>
      • 1.5.5. -Wl,-T,<script>,-Ttext,<address>,-Tdata,<address>
    • 1.6. 高级选项
      • 1.6.1. -pedantic
      • 1.6.2. -fsanitize=<type>
      • 1.6.3. -rpath <path>

1.1. 简介

GCC 编译流程分为四个阶段:预处理、编译、汇编、链接,这里讲解gcc用到的一些参数

  • GCC 原生选项:直接由 GCC 处理,如:

    • -o(输出文件名)
    • -lm(链接数学库 libm)
    • -Wall(启用警告)
    • -O2(优化级别)
  • 链接器专属选项:需通过 -Wl, 传递给链接器(如 ld),如:

    • –gc-sections(移除未使用的节)
    • -soname(设置共享库运行时名称)
    • -T(使用自定义链接脚本)

1.2. 常用选项

1.2.1. -c -E -S -o

-E 仅进行预处理,输出预处理后的代码。
gcc -E source.c -o source.i

-c 只进行编译,不进行链接,生成目标文件(.o)
gcc -c source.c # 生成 source.o

-S 生成汇编代码(.s)。
gcc -S source.c # 生成 source.s

-o 指定输出文件的名称
gcc source.c -o program

1.2.2. -L<path> -l<library>

-l 链接指定的库(如-lm链接数学库)。
-L 指定库文件的搜索路径。
gcc source.c -L/path/to/lib -lmylib

1.2.3. -D<macro>

定义宏(等价于在代码中使用#define)。

1.2.4. -I<path>

指定头文件的搜索路径。

1.3. 代码生成和优化

1.3.1. -std=<standard>

指定 C/C++ 标准(如-std=c99、-std=c++17)。

1.3.2. -shared

生成共享库(.so)

1.3.3. -fPIC

生成位置无关代码(用于共享库)。

1.3.4. -static

静态链接所有库(生成独立可执行文件)。
gcc -static source.c

1.3.5. -O0 -O1 -O2 -O3 -Os

选项优化目标编译时间代码体积运行性能典型场景
-O0无优化(调试)最快最大最慢开发调试
-O1平衡性能与时间较快较小一般日常开发的 release 版本
-O2优化性能较长中等生产环境默认
-O3最高性能最长最大最快高性能计算
-Os最小代码体积较长最小接近- O2 嵌入式系统、固件

1.3.6. -ffunction-sections-fdata-sections

-ffunction-sections:将每个函数放在独立的 ELF 节(section)中。
-fdata-sections:将每个全局变量放在独立的节中。
目的:配合链接器选项 -Wl,--gc-sections(垃圾回收),在最终二进制文件中移除未使用的函数和变量,减小文件体积。

1.4. 调试与警告选项

1.4.1. -g -ggdb

-g 生成调试信息,用于 GDB 调试。
-ggdb 生成更详细的 GDB 调试信息。

一般配合 -O0 使用, 优化选项(如 -O2)可能会改变代码结构,导致调试信息与实际执行不匹配。

选项调试信息格式适用调试器文件大小调试体验
-g标准 DWARF通用较小基本调试
-ggdbGDB 扩展GDB 专用较大高级调试

1.4.2. -Wall -Werror -Wextra

-Wall 启用常见的编译警告(如未使用的变量、隐式转换等)。
-Werror 将所有警告视为错误,强制修复警告。
-Wextra 启用额外的警告(如未初始化的变量、冗余代码等)。一般用的比较少

1.4.3. -Wno-pointer-sign

-Wno-pointer-sign 是 GCC 编译器的一个警告选项,用于禁用关于指针符号不匹配的警告
禁用警告:通过 -Wno-pointer-sign 可以关闭这类警告,避免编译时产生干扰信息。
相反选项:对应的启用警告选项是 -Wpointer-sign,但通常通过 -Wall 或 -Wextra 自动启用。

1.4.4. -fno-strict-aliasing -fstrict-aliasing

-fstrict-aliasing(默认启用):严格遵循别名规则,进行激进优化。
-fno-strict-aliasing:禁用规则,允许不同类型指针别名,可能导致显著的性能损失。

  • 禁用 GCC 的严格别名规则优化,允许不同类型指针指向同一块内存。
  • 禁用优化会降低性能,建议优先修改代码以符合严格别名规则(如使用 union)。
  • 适用于遗留代码或依赖类型双关(type punning)的场景(如底层硬件访问)。
int a = 1;
float* f = (float*)&a;  // 违反规则
*f = 3.14f;
printf("%d\n", a);  // 可能输出 1(而非预期的修改后的值)

解决方案:

  • 使用 union 实现类型双关,确保类型兼容。
  • 使用字符指针转换
  • 使用 memcpy

1.5. 安全与连接选项

1.5.1. -z noexecstack -z relro -z now

  • -z noexecstack
    • 现代操作系统(如 Linux)支持内存区域的 NX 位(No-eXecute),通过该选项将栈标记为不可执行。
    • 若攻击者尝试在栈上执行恶意代码,会触发内存访问异常。
    • 某些动态链接库(如使用 setjmp/longjmp 的库)可能需要可执行栈,此时需谨慎使用。
    • 现代 Linux 发行版默认启用 NX 保护,但通过 -z execstack 可禁用(不推荐)。
  • -z relro (Relocation Read-Only)
    • 功能:启用只读重定位(Relocation Read-Only)。
    • 防御机制:将全局偏移表(GOT,Global Offset Table)和动态符号表标记为只读,防止攻击者修改这些表中的函数地址。
  • -z now
    • 功能:强制链接器立即绑定所有符号(而非延迟绑定)。
    • 防御机制:减少动态加载时的符号表修改机会,增强 RELRO 的安全性。

1.5.2. -Wl,option

-Wl,option 是 GCC 编译器用于将参数传递给链接器(如 ld)的语法。通过 , 分隔多个选项,例如 -Wl,–gc-sections,-Map=output.map

gcc source.c -Wl,-o,program.out       # -o 选项,指定输出文件名,等价于 gcc source.c -o program.out
gcc source.c -Wl,-e,my_entry_point    # -e 选项,指定入口点,代替 main 函数,等价于 gcc source.c -emy_entry_point
gcc source.c -Wl,-L,/path/to/lib      # -L 选项,指定库搜索路径,等价与 gcc source.c -L/path/to/lib
gcc source.c -Wl,-l,m                 # -l 选项,等价与 gcc source.c -lm,建议直接使用 -lm,语法更简洁。
  • 选项类别 必须使用 -Wl, 的典型选项
    • 代码优化 --gc-sections, --as-needed
    • 内存布局 -T, -Ttext, -Tdata
    • 共享库 -soname, --version-script
    • 安全增强 -z noexecstack, -z relro, -z now
    • 调试 --verbose, --cref

1.5.3. -Wl,--strip-all,--gc-sections,--as-needed

gcc source.c -Wl,--strip-all,--gc-sections,--as-needed
gcc source.c -Wl,--wrap,malloc  # 使用 __wrap_malloc 替代 malloc
  • --gc-sections 移除未使用的代码和数据段(需配合 -ffunction-sections 和 -fdata-sections)。
    • 用于移除可执行文件中未使用的代码和数据段(sections),从而减小二进制文件体积。
    • 若某个节被标记为 USED(如通过 attribute((used))),则不会被回收。
    • 启用 GC 会增加链接时间(需分析所有符号),但通常对运行时性能无影响。
    • 若二进制体积不是关键因素,可关闭此选项以加快编译。
    • -O2 会自动启用一些内联优化,但无法替代 --gc-sections 的全局代码删除能力。
    • 验证:使用 size 命令对比文件大小
  • --strip-all 或 --strip-debug 移除符号表和调试信息。
  • --as-needed 仅链接真正使用的共享库(减少依赖)。
  • --wrap <symbol> 允许替换标准库函数(用于测试或钩子)。

1.5.4. -Wl,--verbose,-soname,<name>

gcc source.c -Wl,--verbose,-soname,libmylib.so.1

--verbose 输出链接过程的详细信息。
-soname <name> 设置共享库的运行时名称(用于版本控制)。

1.5.5. -Wl,-T,<script>,-Ttext,<address>,-Tdata,<address>

gcc source.c -Wl,-T,memory_layout.ld
gcc source.c -Wl,-Ttext,0x10000
gcc source.c -Wl,-Tdata,0x20000

-T <script> 使用自定义链接脚本(用于嵌入式系统或特殊内存布局)。
-Ttext <address> 指定代码段(.text)的加载地址。
-Tdata <address> 指定数据段(.data)的加载地址。

1.6. 高级选项

1.6.1. -pedantic

严格遵循语言标准,拒绝非标准特性。

1.6.2. -fsanitize=<type>

启用运行时检查(如内存泄漏、未定义行为)。

1.6.3. -rpath <path>

设置运行时库搜索路径(替代 LD_LIBRARY_PATH)。

gcc source.c -Wl,-rpath,/path/to/lib

相关文章:

  • JavaWeb期末速成 JSP
  • 网络编程之HTML语言基础
  • flatbuffer源码编译和使用方法
  • 短剧小程序开发:开启碎片化娱乐新视界
  • SpringCloud微服务:服务保护和分布式事务
  • 三次握手建立连接,四次挥手释放连接——TCP协议的核心机制
  • Linux 下的 PM2 完整指南
  • linux基于内存实现jar文件搜索
  • 如何有效监控JVM环境,保障应用性能
  • Elasticsearch:使用 ES|QL 进行地理空间距离搜索
  • 动态规划3——背包类动态规划详解
  • elasticSearch是什么,如何使用,有什么用
  • 考研系列—408真题操作系统篇(2015-2019)
  • Windows环境变量原理(用户变量与系统变量)(用户环境变量、系统环境变量)
  • centos6.5 老旧系统编译glib-2.58.3.tar.bz2
  • vue-property-decorator实践(一)
  • 如何通过插件系统打造个性化效率工作流
  • AUTOSAR图解==>AUTOSAR_TR_InteroperabilityOfAutosarTools
  • PEP 8: E302 expected 2 blank lines, found 0
  • [vela os_5] 中断系统 | 任务调度 | 日志系统
  • 淘宝关键词搜索工具/百度优化排名
  • 做网站必须需要服务器嘛/百度推广平台收费标准
  • 国内新闻最新消息今天疫情/搜索引擎优化实训
  • 景观设计公司排名前十强/昆明优化网站公司
  • 做网站应该画什么图/中国进入一级战备2023
  • 兼职网站哪个靠谱/网站加速