GCC 使用笔记

1. 前言 和其他现代语言不同,C/C++ 的编译系统是散装的,由众多工具组成。比如包管理器有 Conan,Vcpkg 等等,构建系统有 Cmake, Ninja, autotools, scons 以及原始的 Makefile. 也有想要一统天下的 Bazel 说句题外话,我深入用过 Conan + Cmake 和 Bazel 两种方案,并在公司负责这两种编译系统的开发和维护。相比来说,我认为前者方案适合纯 C/C++/cuda 项目,非常方便好用,官方提供的库菜单很多,对交叉编译支持完备。后者则更适合大型、复杂项目,以及多语言,多个模块项目,Bazel 目标依赖系统做的很好,上游目标改动后会触发下游目标编译,这点是 Conan 和 Cmake 系统无法做到的。 但是 Bazel 对 C/C++ 的交叉编译没有支持,Cuda 规则没有官方提供,编译器规则开发经过多次迭代,可能前几年使用的在新版中已经无法使用,相对维护成本高很多。 回到正题,无论采用那种构建系统,最后总都归到编译器,主流的有 GCC 和 Clang 两种,我只用过 GCC,因此本文主要记录一些使用中觉得比较重要的点,供自己记录参考 2. 依赖问题 依赖问题应该是编译中大家遇到最多的问题。 简单来说,编译过程分为 编译 和 链接 两步,如果你写的代码没问题,那我们在进行编译时主要会遇到以下三种错误 编译的时候报找不到头文件 编译的时候报找不到依赖库 编译过了运行时候报找不到对应符号 下面我们分别讨论如何解决上述问题 2.1 找不到头文件 这个问题最容易解决,编译器默认只会查询 /usr/include, /usr/local/include 等几个标准路径下的头文件,将这些路径和代码里引用的相对路径拼起来就是头文件位置。 而对于放在非标准路径下的头文件,我们可以通过 -I 参数告诉编译器,如下 gcc -I{include_dir} -o my_program my_program.c 还有一种方法是使用 isystem gcc -isystem {include_dir} -o my_program my_program.c 这两种方式都可以引入头文件搜索路径,两者区别如下 ...

May 17, 2024 · 1 min · 192 words · Croak