使用高版本GCC进行项目编译

举报
enali 发表于 2020/08/28 20:43:34 2020/08/28
【摘要】 文章主要介绍在使用高版本GCC进行项目编译时遇到的问题和解决方案。假设系统已经编译安装了高版本的GCC,并且没有覆盖系统自带的GCC(即并存)。

问题背景

CentOS7的GCC版本为4.8.5,这个版本对C++11的支持不完整,比如,对于正则表达式库,编译器本身支持,但标准库不支持。

之前的c++项目在Ubuntu18.04上编译,在迁移到CentOS7后,使用系统自带的GCC编译项目一直出错,经过排查定位到正则库的支持问题。

这种情况有两种解决方案:1,替换使用`Boost`库的`regex`库,工作量非常小;2,编译安装更高版本的GCC来编译项目。

第一种方案在第三方库也用到了regex时没办法处理。作为库开发者,如果要兼容低版本GCC时,通常在CMake脚本中会判断,如果是低版本GCC则依赖安装Boost库作为方案。但一般三方库如果声明是针对c++11开发,则不会做这种兼容性考虑。

第二种方案的问题是,高版本GCC编译出的项目会依赖高版本的标准库,在相同架构的相同系统之间,做不到可移植性。

项目编译

使用高版本GCC进行项目编译时,主要关注两点:1,项目是否确认是使用高版本GCC进行的编译;2,项目使用高版本GCC编译时是否链接的是高版本的标准库。

具体的编译过程和指导跟项目的编译方式相关,下面分别针对不同的编译方式进行说明。当前主要包含:`boost`, `cmake`, `make`

b2编译

b2目前只知道Boost库在使用,它有自己的一套编译和配置逻辑。因此,这里相当于是在说明,如何在编译boost库时指定高版本GCC。

编译boost时,会自动搜索当前系统已安装的编译器,然后在编译时指定。但这有时并不生效,需要主动在user-config.jam文件中进行配置。此文件或者位于用户主目录($HOME)下,或者位于$BOOST_BUILD_PATH目录下。后者在源码编译时,指tools/build/src目录。

文件内容形式为using <toolset-name> : <version> : <cmd-path> : <options>;,例如,如果使用clang编译器时,using clang : 10.0 : /usr/bin/clang++ : -std=c++14。编译选项除了在此处指定外,也可在命令行参数中指定:cxxflags="-std=c++14"指定编译的c++标准。

在配置后,使用b2命令时,指定参数:toolset=<toolset-name>-<version>。

cmake编译

使用cmake进行项目编译,通常会使用3条指令:

mkdir build && cd build  # 创建构建目录(1)
cmake .. # 创建构建缓存(2)
make # 编译(3)

cmake会默认使用系统自带的GCC,并非当前PATH中的GCC。通常,在编译安装高版本GCC后,会将相应的bin目录添加到系统GCC的路径之前,这样在执行gcc --version时会验证是否安装成功。但cmake对GCC的选择,感觉跟默认路径/usr/bin/gcc相关。

在使用(2)命令时,查看输出的日志信息,可以确认当前cmake使用gcc版本。在(3)命令时,开启冗余日志模式,使用VERBOSE=1 make来查看链接时是否使用高版本GCC标准库。

修改cmake的默认GCC有两种方式:1,设置环境变量CC/CXX,与make相同;2,指定CMAKE_C_COMPILER和CMAKE_CXX_COMPILER两个变量,通过-Dkey=value的形式。

make编译

使用make进行项目编译,通常采用设置环境变量CC/CXX的方式来指定编译用的GCC版本。

项目运行

高版本GCC编译安装后的执行文件或动态库依赖高版本的GCC标准库。如果将编译结果移植到另一个同架构同系统的机子,则会运行失败。C++标准库一直存在的ABI不兼容问题,就是对同一个API,不同版本的标准库实现不同,导致在链接时失败。

通常有两种方式来解决:1,静态链接标准库;2,复制高版本的标准库到指定位置(覆盖或链接)。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。