记第一次修包mariadb
记第一次修包mariadb
报错的具体信息如下所示
[ 4526s] In file included from /home/abuild/rpmbuild/BUILD/mariadb-11.8.1/mysys/lf_hash.cc:30:
[ 4526s] /home/abuild/rpmbuild/BUILD/mariadb-11.8.1/include/my_cpu.h: In function 'void MY_RELAX_CPU()':
[ 4526s] /home/abuild/rpmbuild/BUILD/mariadb-11.8.1/include/my_cpu.h:100:3: error: '__builtin_riscv_pause' was not declared in this scope; did you mean '__builtin_riscv_fsflags'?
[ 4526s] 100 | __builtin_riscv_pause();
[ 4526s] | ^~~~~~~~~~~~~~~~~~~~~
[ 4526s] | __builtin_riscv_fsflags
在拿到错误之后,经过网络检索与询问AI可以得知__builtin_riscv_pause
是一个编译器内置函数,如果这个函数找不到有可能是该版本的gcc编译器不支持这个内置函数,因此第一想法是将这个内置函数通过内联汇编的形式嵌入代码,通过查阅gcc13编译器的手册可以看到如下信息:
而gcc12编译器的使用手册则空空如也
这进一步确定了OE使用的gcc12编译器中没有该内置函数,因此使用内联汇编替代(第一个坑开始了) 该函数,代码如下
__asm__ __volatile__ ("pause":::"memory");
开始编译,报了Error: unrecognized opcode `pause', extension `zihintpause' required
,针对该函数单独进行测试发现,必须显式的指定扩展才可以通过编译,因此在spec文件中添加了对应了指令集支持(第二个坑,在spec文件里添加对特定架构的编译指令是错误示范,愿诸位引以为戒),添加代码如下:
%define CMAKE_RISCV64_FLAGS -DCMAKE_C_FLAGS="-march=rv64g_zihintpause" -DCMAKE_CXX_FLAGS="-march=rv64g_zihintpause"
CMAKE_RISCV64_FLAGS
是我的自定义变量,检测当前架构是否是RV64,并将后面的指令集优化添加进编译命令,经过测试,x86_64,aarch64,RISCV64架构下均可以编译通过,在我通过编译后,王老师针对我的PR提出了疑问,为什么要指定指令集优化,并且因为我添加的代码与后面一个条件分支的内联汇编(__asm__ __volatile__ ("":::"memory");
)非常相似,是否有合并的可能性
#elif defined __GNUC__ && defined __riscv
__asm__ __volatile__ ("pause":::"memory");
#elif defined __GNUC__
__asm__ __volatile__ ("":::"memory");
并且在得知我第一次修包之后,王老师给我提供了修包的基本模板与规范(非常感谢王老师):
- 尽可能少的修改源码,如果存在特定版本的编译问题,使用if进行分支
- 编译指令要修改在CMakeLists,不要对spec文件有大的改动
针对提出的疑问,我做出说明:即只有添加了zihintpause
扩展编译器才可以识别pause指令,并在考虑到跨平台时ARM架构不支持pause,因此不适合将pause指令放在#elif defined __GNUC__
条件分支下。在王老师的模板基础上我修改了自己的PR,并最终合并。
在本次修包中,我学到了在cmake文件中如何识别不同的架构与添加不同的编译指令,并了解了在处理跨平台问题的时候不能针对某一个平台进行修改,还要考虑到对所有可能设计的平台有没有影响。放在本次修包中,体现在不能影响到gcc13及以上的编译器的处理,又不能影响到ARM等其他平台的编译。
挖个坑:除了我这种修改源码包的修包方式之外,还有一位老师指出了可以将gcc13的对 __builtin_riscv_pause
的支持引入到gcc12中,本次修包大抵已经结束,但我想实现一个这个思路,使用了这么多次gcc,还从没注意到gcc源码里长什么样呢,希望我这次修包可以顺利。
第一次写播客来分享自己的所得,如果有所疏忽,希望可以不吝赐教,感谢