GCC 使用指南(gcc 9.4 compiling、warning 解决办法)

本文介绍了在Ubuntu20.04环境下,从GCC4.8.5升级到GCC9.4.0后遇到的编译问题。作者详细展示了如何通过官方文档解决编译警告和错误,特别是关于-Werror=unused-function的处理。文章强调了理解编译选项和查阅GCC文档的重要性,并提供了GCC9.4编译选项的查询方法。同时,还分享了在系统库libstdc++中查找问题源的尝试过程。最后,给出了修改编译选项以忽略特定警告的解决方案。

背景

最近项目需要使用 Ubuntu 20.04.4,查看编译器版本居然是 9.4.0,自然项目迁移过程中会有很多编译问题需要解决,毕竟之前的 gcc 版本都是 4.8.5 的,版本差异很大。

使用 gcc(g++) 遇到编译问题,首选当然是浏览器直接搜索问题关键字即可,一般都是有解决办法的,但是碰到和高版本如:gcc 8.4、gcc 9.4版本的问题,很多时候就不太好找的。因此就需要自己去 GCC官网 针对具体问题具体查看了。

附 GCC 编译问题速查链接:3 GCC Command Options

编译环境

lm@lm:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"

lm@lm:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)

GCC 官网

GCC 官网地址为:GCC, the GNU Compiler Collection
在这里插入图片描述

官网列出一般是每个大版本的最终版(如:GCC 9.4),但是如果想查看中间的某个版本可以点开上图中的两处,打开相应的链接(如:GCC 9 Release Series),截图如下:

在这里插入图片描述

点击其中的 documentation 就可以看到手册中更多相关的内容,当前支持Online、PDF、PostScript 、HTML等多种格式。
在这里插入图片描述

GCC 使用

对于我们大部分人来说,更多的还是比较关注如何使用GCC。
使用 GCC 9.4 编译代码经常碰到的问题一般是 warning (毕竟一些项目要求是 all warnings being treated as errors,那么warning咱就必须消除 )或者 error,特别是平台移植的时候。
具体而言 GCC 的使用方式如下:

编译遇到问题

在下面的代码中,编译遇到一个错误,尽管从直面来看是个 Error,但是自己查看,应该是告警(warning),但是因为项目需求,在编译选项添加了 -Wall ,因此才会有最后的 cc1plus: all warnings being treated as errors
最重要的是,针对该问题,我们看到了解决编译问题的线索,就是标记那一行的错误提示码:[-Werror=unused-function]
在这里插入图片描述

查编译选项

打开GCC版本对应的 3.1 Option Summary,(这里以9.4举例,毕竟每个GCC版本的 Option Summary 内容是不同的)
搜索该编译选项 unused-function ,截图如下:
在这里插入图片描述
找到之后,往上看属于是:Warning Options大类
在这里插入图片描述
点击上面的 Options to Request or Suppress Warnings
继续在该页面搜索该编译选项:unused-function
在这里插入图片描述
继续向下搜索,可以看到关于该编译选项更加详细信息:
在这里插入图片描述
即,之所有会有告警是因为:

Warn whenever a static function is declared but not defined or a non-inline static function is unused. This warning is enabled by -Wall.
每当声明了静态函数但未定义或未使用非内联静态函数时发出警告。 此警告由 -Wall 启用。

回看代码

知道了引起此告警的原因,而且有告警存在,那么就要回看下代码是哪里的问题。
查阅代码错误的地方位于:/usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:237:10
![在这里插入图片描述](https://img-blog.csdnimg.cn/54c7d10f54d84c5f9c5ed5ddeadc0488.png
但是很明显,这里是系统库 libstdc++ 中的代码,而我们一般只引用其 *.h 头文件和 lib 库。

补充一点小知识:

libstdc++ 是 GNU 标准 C++ 库 ,用于实施 ISO 14882 C++ 标准库。
该库称为 libstdc++ 而不是 stdlibc++。

最初的 ISO C++ 标准化工作的完成为 C++ 社区提供了一套强大的可重用工具,最终以 C++ 标准库的形式。然而,C++ 实现(正如标准草案过去所说的那样)“不完整和不正确”,并且许多都受到使用它们的编译器的限制。
GNU 编译器集合(gcc、g++ 等)被广泛认为是世界领先的编译器之一。它的开发由 GCC 团队监督。作为开源项目标志的所有快速开发和可移植性都适用于 libstdc++。
所有来自 C++98/C++03、C++11 和 C++14 的标准类和函数(例如字符串、向量<>、iostreams、算法等)都是免费提供的,并试图完全合规。正在进行工作以完成对 ISO C++ 标准当前版本的支持。

即使如此,但是我仍旧没死心,继续查找该文件对应的库文件:

lm@lm:/usr/lib/x86_64-linux-gnu$ ls -al libgthread*
-rw-r--r-- 1 root root  2870 Jul 12  2021 libgthread-2.0.a
lrwxrwxrwx 1 root root    19 Jul 12  2021 libgthread-2.0.so -> libgthread-2.0.so.0
lrwxrwxrwx 1 root root    26 Jul 12  2021 libgthread-2.0.so.0 -> libgthread-2.0.so.0.6400.6
-rw-r--r-- 1 root root 14488 Jul 12  2021 libgthread-2.0.so.0.6400.6

lm@lm:/usr/lib/x86_64-linux-gnu$ nm libgthread-2.0.so.0.6400.6
nm: libgthread-2.0.so.0.6400.6: no symbols

lm@lm:/usr/lib/x86_64-linux-gnu$ file libgthread-2.0.so.0.6400.6
libgthread-2.0.so.0.6400.6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=bd39b0be15c80cc559d7e9b4edec3d1938e9f1c5, stripped
lm@lm:/usr/lib/x86_64-linux-gnu$

发现库中没找到 symbols,而且库文件都被 stripped
到此只能选择放弃了,因为毕竟再查下去,唯有源码才可解惑了。

解决方案

基于此,针对此编译告警,当前做的就只有保留此告警。这就需要修改编译选项,将涉及到的 C++ 产品文件暂时忽略该告警。
具体修改方式为:

  1. 找到引起告警的产品代码源文件所在的makefile文件(或者cmake);
  2. 查看编译选项(一般是makefile文件)xx_xx_CPPFLAGS(x_xx是最终会生成的 lib 库)
  3. 添加或者追加编译选项 xx_xx_CPPFLAGS := -Wno-unused-function
  4. 重新编译产品代码

其他案例

针对 GCC 9.4 编译过程中遇到的其他问题,如果感兴趣也可以出门左转,参看其他两个实例:
GCC 9.4 编译error: catching polymorphic type ‘class std::bad_alloc’ by value [-Werror=catch-value=]
GCC 9.4 编译 specified bound 255 equals destination size [-Werror=stringop-truncation]

Reference

GCC, the GNU Compiler Collection
Welcome to GCC Wiki
Using the GNU Compiler Collection (GCC)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值