构建gstreamer1.0-plugins-bad-qt遇__init_array_end未定义引用错误求助
__init_array_end/__init_array_start未定义的链接错误 问题背景
在Yocto环境构建gstreamer1.0-plugins-bad-qt包时,引入conf/distro/include/security_flags.inc后触发链接错误,提示__init_array_end和__init_array_start未定义,具体失败环节为链接libgstdecklink.so。已尝试以下方案但未解决:
- 在bb文件中添加额外LDFLAGS
- 移除security_flags.inc中的LDFLAGS
- 删除带与不带security_flags.inc时的差异LDFLAGS
原因分析
security_flags.inc中的安全编译/链接选项(如段优化、符号隐藏类参数)可能破坏了编译器生成初始化数组的默认逻辑,导致链接器无法找到__init_array_start/__init_array_end符号——这类符号通常由链接脚本自动生成,若被过度优化或链接脚本被修改,就会出现未定义错误。
可行修复方案
1. 针对性禁用冲突的链接选项
找出security_flags.inc中可能影响初始化数组的参数(比如-Wl,--gc-sections、-fdata-sections、-ffunction-sections、-Wl,--exclude-libs,ALL),在gstreamer1.0-plugins-bad-qt的bb/bbappend文件中移除这些选项:
# 移除可能导致段被丢弃的选项 LDFLAGS_remove = "-Wl,--gc-sections -fdata-sections -ffunction-sections"
如果只想针对decklink插件修复,可追加编译参数强制保留符号:
EXTRA_OEMAKE_append += " LDFLAGS='${LDFLAGS} -Wl,--undefined=__init_array_start -Wl,--undefined=__init_array_end'"
2. 检查并修复链接脚本
security_flags.inc可能替换了默认链接脚本,导致初始化数组的符号定义缺失。先查看当前链接器使用的脚本:
${CC} -Wl,--verbose | grep "using linker script"
若链接脚本被修改,需确保其中包含初始化数组的定义:
.init_array : ALIGN(8) { __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; }
如果缺失,要么修改链接脚本补充上述内容,要么在包的bb文件中指定使用默认链接脚本:
LDFLAGS_append = " -Wl,-T ${STAGING_DIR_TARGET}/usr/lib/ldscripts/${TARGET_ARCH}.ld"
3. 强制链接器保留目标符号
直接在bb文件中添加链接选项,告诉链接器必须保留__init_array_start和__init_array_end:
LDFLAGS_append += " -Wl,--undefined=__init_array_start -Wl,--undefined=__init_array_end"
该选项会阻止链接器将这些符号标记为“未引用”而丢弃相关段。
4. 升级编译器版本排查兼容性问题
部分旧版本GCC/LD在处理安全选项时存在bug,导致初始化数组符号丢失。可尝试升级Yocto中的编译器版本,比如在local.conf中指定:
PREFERRED_VERSION_gcc-cross-${TARGET_ARCH} = "12.%"
验证方法
修改完成后,清理并重新构建包:
bitbake gstreamer1.0-plugins-bad-qt -c cleanall && bitbake gstreamer1.0-plugins-bad-qt
查看链接阶段日志,确认错误是否消失。
内容的提问来源于stack exchange,提问作者Quinn

