产品:openEuler
版本:openEuler所有版本
组件:基础设施
分类:安全/编译
来源:现网/总结
【背景及现象描述】
使用同一份binutils源码,本地构建和使用openEuler rpm得到的二进制不同。经过定位,发现是由于rpm构建过程中installing gcc_secure,导致客户本地构建的编译选项与openEuler构建系统中的编译选项不同。这时客户就开始质疑:“我使用的是spec文件中提供的构建选项和编译选项,为什么发布件的编译选项和spec中的不一致,rpm是做了什么特殊处理吗?”。
【原因分析】
现在大家目光集中在gcc_secure身上,这是一个啥呢?gcc_secure是一个gcc编译器的包装器(wrapper),它通过替换原/usr/bin/gcc为/usr/bin/gcc_old,然后再创建一个名字叫gcc的脚本拦截所有调用原gcc的组件,并给原选项增加一些安全编译选项,实现增加安全编译选项的功能,它似乎会自动添加到obs打包过程中。看到这里,浓眉大眼的gcc_secure似乎完全是个好人啊?但是gcc_secure的实现机制存在以下问题:
- gcc_secure以
%post
的方式修改系统。这就导致gcc_secure无法卸载,只能通过重新安装gcc的方式覆盖gcc_secure。 - gcc_secure没有显式的写在rpm中的BuildRequires中,这导致对openEuler不太熟悉的用户可能不知道软件包在打包时还会通过gcc_secure添加一些安全编译选项。
- 不使用gcc_secure编译的包定义在gcc_secure_exclude中,目前不清楚为何这些包不使用gcc_secure构建,以及不是所有包都用gcc_secure构建会不会有兼容性问题。
对于openEuler而言,gcc_secure不算一个新鲜事物,相关讨论(吐槽/issue)早已堆积成山,基本上所有被它坑过的人都想去吐槽。但是由于系统中存在手写Makefile的软件包(有个issue讨论过),导致其他方案均不能百分百保证覆盖所有场景,所以gcc_secure是一个不是很优雅但是简单且高效的解决方案。
【解决方法】
可以在obs中查询软件包的构建日志,安装缺少的软件包,保证本地环境与obs环境尽量相同。
【总结与建议】
- 如果遇到莫名编译失败的场景,而且报"cat /.build.command 没有那个文件或目录",那可能是不小心安装了gcc_secure,这时重新安装gcc即可。
- 不想在打包过程中使用gcc_secure时,可以提PR修改gcc_secure_exclude OBS_PRJ_meta/master/prjconf-openEuler:selfbuild:function · src-openEuler/obs_meta - Gitee.com