移植FreeBSD devd到OpenBSD时链接器缺失预期符号求助
移植FreeBSD devd到OpenBSD的链接错误问题
正在将FreeBSD的devd移植到OpenBSD平台,已完成以下工作:补全缺失的系统调用、注释Makefile中FreeBSD专属配置、重构代码消除所有编译错误与警告,但链接阶段失败。
链接错误信息
foo$ make devd c++ -O2 -pipe -MD -MP -o devd devd.cc ld: error: undefined symbol: yyin >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(config::parse_one_file(char const*)) ld: error: undefined symbol: lineno >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(config::parse_one_file(char const*)) >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(new_match) ld: error: undefined symbol: yyparse >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(config::parse_one_file(char const*)) ld: error: undefined symbol: pidfile >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(config::open_pidfile()) >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(main) >>> referenced by devd.cc >>> /tmp/devd-e407ee.o:(main) c++: error: linker command failed with exit code 1 (use -v to see invocation)
当前使用的BSD风格Makefile
# $FreeBSD$ #.include <src.opts.mk> WARNS?= 3 PACKAGE=devd CONFGROUPS= CONFS DEVD CONFS= devd.conf DEVD= devmatch.conf DEVDDIR= /etc/devd #.if ${MK_ACPI} != "no" #DEVD+= asus.conf #.endif #.if ${MK_HYPERV} != "no" #CONFGROUPS+= HYPERV #HYPERVDIR=${DEVDDIR} #HYPERV+= hyperv.conf #HYPERVPACKAGE= hyperv-tools #.endif #.if ${MK_USB} != "no" #DEVD+= uath.conf ulpt.conf #.endif #.if ${MACHINE_ARCH} == "powerpc" #DEVD+= apple.conf #.endif #.if ${MK_ZFS} != "no" #DEVD+= zfs.conf #.endif PROG_CXX=devd SRCS= devd.cc token.l parse.y y.tab.h MAN= devd.8 devd.conf.5 LIBADD= util YFLAGS+=-v CFLAGS+=-I. -I${.CURDIR} CFLAGS.clang += -Wno-missing-variable-declarations CFLAGS.gcc = -Wno-redundant-decls CXXFLAGS.gcc = -Wno-redundant-decls CLEANFILES= y.output y.tab.i HAS_TESTS= SUBDIR.${MK_TESTS}+= tests .include <bsd.prog.mk>
解决方案建议
1. 解决flex/bison相关未定义符号(yyin、lineno、yyparse)
- 修正SRCS列表:移除
y.tab.h,头文件不需要加入源文件列表,OpenBSD的bsd.prog.mk会自动处理.l和.y文件的编译规则,生成对应的C文件并参与链接。 - 启用行号支持:如果
lineno是flex生成的行号变量,需要在token.l开头添加%option yylineno,确保flex生成的代码包含行号定义。 - C++兼容处理:由于项目使用C编译(
PROG_CXX=devd),flex默认生成C代码,需要在token.l中添加%option c++,确保生成的代码能被C编译器正确编译;同时给bison添加YFLAGS+=-Wno-deprecated等选项,适配C++编译环境。
2. 解决pidfile未定义符号
- 适配OpenBSD pidfile接口:FreeBSD的
pidfile()函数在OpenBSD中不存在,OpenBSD的libutil提供pidfile_open()、pidfile_write()、pidfile_close()等替代函数。需要修改代码中调用pidfile的逻辑:- 示例替换:将
pidfile("devd");替换为pidfile_open("devd", 0600, NULL);,写入PID时调用pidfile_write(),程序退出前调用pidfile_close()。
- 示例替换:将
- 确认头文件引用:确保代码中包含
<util.h>头文件,保证pidfile相关函数的声明被正确引入。
3. 其他Makefile调整建议
- 完善CLEANFILES:添加
lex.yy.c和y.tab.c到CLEANFILES列表,确保flex/bison生成的中间文件能被清理。 - 验证规则触发:OpenBSD的
bsd.prog.mk会自动识别.l和.y文件,无需手动添加生成规则,只要SRCS中包含这两个文件即可。
内容的提问来源于stack exchange,提问作者gjbauer
相关产品推荐
相关产品推荐

