GCC 使用指南(gcc 9.4 compiling、warning 解决办法)
背景最近项目需要使用 Ubuntu 20.04.4,查看下 编译器版本居然是 9.4.0,自然项目迁移过程中会有很多编译问题需要解决,毕竟之前的 gcc 版本都是 4.8.5的,差距很大。使用 gcc(g++) 遇到编译问题,首选当然是浏览器直接搜索问题关键字即可,一般都是有解决办法的,但是碰到和高版本如:gcc 8.4、gcc 9.4版本的问题,很多时候就不太好找的。因此就需要自己去 GCC官网
背景
最近项目需要使用 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
但是很明显,这里是系统库 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++ 产品文件暂时忽略该告警。
具体修改方式为:
- 找到引起告警的产品代码源文件所在的makefile文件(或者cmake);
- 查看编译选项(一般是makefile文件)
xx_xx_CPPFLAGS
(x_xx是最终会生成的 lib 库) - 添加或者追加编译选项
xx_xx_CPPFLAGS := -Wno-unused-function
- 重新编译产品代码
其他案例
针对 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)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)