ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

GCC 参数记不住?这份语法速查 + 多参数组合示例,收藏就够

GCC 参数记不住?这份语法速查 + 多参数组合示例,收藏就够 代码写得没问题一编译却蹦出一堆undefined reference to xxx。改了半天最后发现是命令里库的顺序写反了。今天把 GCC 语法、核心参数、多参数组合以及最容易踩的链接顺序坑一篇讲清。一、gcc 基本语法一条 gcc 命令长这样$ gcc[options][source files][object files][-o output file]四部分选项options、源文件、目标文件、输出文件。不写-o时默认生成a.out。提醒GCC 是GNU Compiler Collection的缩写不止能编 CC / Fortran 等都行。我们常说的gcc默认走 C 编译。二、核心参数速查分类参数作用编译控制-c只编译不链接生成 .o 目标文件预处理-Dname[value]定义宏等价于源码#define-Uname取消宏定义路径-I dir头文件header搜索目录-L dir库文件library搜索目录链接-l lib链接指定库如-lm链 libm输出-o file指定输出文件名优化-O level优化代码O0/O1/O2/O3/Os调试-g level生成 GDB 调试信息g1/g/g3共享库-fPIC生成位置无关代码Position Independent Code-shared生成共享库 .so警告-w关闭所有警告-Wall开启全部常用警告-Wextra在 -Wall 基础上再加额外警告分级速记优化-O-O0不优化默认-O2常用-O3激进-Os省体积调试-g-g1最少-g常规-g3最全含宏警告-w压制→ 默认 →-Wall→-Wextra三、多参数命令多数参数与顺序无关空格分隔即可# 优化 全警告 自定义名gcc-O2-Wall-oapp main.c utils.c# 可调试 暴露隐患开发期标配gcc-g-Wall-oapp main.c# 做共享库位置无关 共享固定搭配gcc-fPIC-shared-olibfoo.so foo.c# 引入第三方库头文件目录 库目录 链接库gcc-O2-Wall-I/opt/include -L/opt/lib-lmylib-oapp main.c# 定义宏 优化gcc-DDEBUG-O2-oapp main.c实战组合开发期用-g -Wall发布期用-O2 -Wall做 SDK / 插件用-fPIC -shared。四、注意-l 链接顺序很多人栽在这。-l链接库有依赖顺序被依赖的库写在后面。链接器linker从左到右只扫一遍静态库.a只在「能补上当前未定义符号」时才被拉入不会回头补救左侧的依赖。由此两条铁律目标文件.o写在库之前gcc app.o -lfoo别写gcc -lfoo app.o若 A 依赖 BA 调用 B写-lA -lB——等 A 暴露出对 B 的需求时B 还在右侧可被拉入依赖链app → foo → barapp 调 foofoo 调 bar命令结果原因gcc app.o -lfoo -lbar成功app 暴露 foo 需求→拉 foo→foo 暴露 bar 需求→右侧 bar 补上gcc -lfoo -lbar app.o失败处理库时 app 还没出现两库被整体跳过报undefined referencegcc app.o -lbar -lfoo失败foo 排在 bar 之后需要的 bar 已错过报undefined reference to bar进阶循环依赖A↔B单遍无解用分组循环扫描-Wl,--start-group -lA -lB -Wl,--end-group共享库.so符号在运行时由动态链接器解析顺序相对宽松但发行版默认--as-needed链接期顺序仍影响DT_NEEDED记录好习惯照旧踩坑细节-l和库名之间不能有空格写-lm不写-l m。五、参数别乱加-O3不一定更快激进内联会撑大代码、拖慢指令缓存命中嵌入式 / 实时场景慎用-O2更稳。-static静态链接可执行文件体积暴涨、无法享受系统库更新除非要的是可移植单文件。-w关警告等于蒙眼开车开发期别用至少上-Wall。-g进发布版带调试信息体积大且暴露源码结构发布时去掉或单独分离。结尾GCC 高频参数就这些记住「分类 组合 链接顺序」三件事编译报错能少一大半。参考资料https://www.rapidtables.com/code/linux/gcc.html
返回列表