You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS Sequoia 15.5构建RpcExplorer遇ncurses版本化符号缺失问题

构建RpcExplorer在macOS Sequoia 15.5上的符号缺失问题

问题背景

在Apple Silicon的macOS Sequoia 15.5上构建RpcExplorer时遇到链接错误,该项目曾在macOS 14及以上版本正常构建,不确定从哪个版本开始失败。

构建完依赖库后,用nm命令检查发现,提示缺失的符号实际存在于lib/ncurses-6.3/dist/lib/libncursesw_g.a中,推测Apple工具链未能正确识别静态库中的符号。

需要明确此次系统更新的改动点,以及可修复该错误的编译标志。

构建命令与错误日志

git clone git@github.com:square/RpcExplorer.git
cd RpcExplorer

make
// 省略(成功的)库构建部分
// ...
// ...
g++ -std=c++17 -o RpcExplorer RpcExplorer.cc -Ilib/cdk-5.0-20230201/dist/include -Ilib/ncurses-6.3/dist/include -Ilib/protobuf-3.21.2/dist/include  lib/protobuf-3.21.2/dist/lib/libprotobuf.a lib/cdk-5.0-20230201/dist/lib/libcdkw.a lib/ncurses-6.3/dist/lib/libncursesw_g.a
Undefined symbols for architecture arm64:
  "_endwin$NCURSES60", referenced from:
      _endCDK in libcdkw.a[19](cdkscreen.o)
      _execCDKSwindow in libcdkw.a[42](swindow.o)
  "_init_pair$NCURSES60", referenced from:
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      _initCDKColor in libcdkw.a[22](draw.o)
      ...
  "_initscr$NCURSES60", referenced from:
      runCursesInterface(Options&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, google::protobuf::MethodDescriptor const*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, google::protobuf::MethodDescriptor const*>>>) in RpcExplorer-eac14a.o
      _initCDKScreen in libcdkw.a[19](cdkscreen.o)
  "_keypad$NCURSES60", referenced from:
      _newCDKButton in libcdkw.a[11](button.o)
      _newCDKDialog in libcdkw.a[21](dialog.o)
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKFselect in libcdkw.a[24](fselect.o)
      _newCDKLabel in libcdkw.a[30](label.o)
      _popupLabel in libcdkw.a[36](popup_label.o)
      ...
  "_newwin$NCURSES60", referenced from:
      _newCDKButton in libcdkw.a[11](button.o)
      _newCDKButton in libcdkw.a[11](button.o)
      _newCDKDialog in libcdkw.a[21](dialog.o)
      _newCDKDialog in libcdkw.a[21](dialog.o)
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKFselect in libcdkw.a[24](fselect.o)
      _newCDKFselect in libcdkw.a[24](fselect.o)
      ...
  "_start_color$NCURSES60", referenced from:
      _initCDKColor in libcdkw.a[22](draw.o)
  "_subwin$NCURSES60", referenced from:
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKEntry in libcdkw.a[23](entry.o)
      _newCDKScroll in libcdkw.a[39](scroll.o)
      _newCDKScroll in libcdkw.a[39](scroll.o)
      _newCDKSelection in libcdkw.a[41](selection.o)
      _newCDKSwindow in libcdkw.a[42](swindow.o)
  "_use_default_colors$NCURSES60", referenced from:
      runCursesInterface(Options&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, google::protobuf::MethodDescriptor const*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, google::protobuf::MethodDescriptor const*>>>) in RpcExplorer-eac14a.o
  "_waddch$NCURSES60", referenced from:
      __drawCDKButton in libcdkw.a[11](button.o)
      __focusCDKButton in libcdkw.a[11](button.o)
      __unfocusCDKButton in libcdkw.a[11](button.o)
      _drawCDKDialogButtons in libcdkw.a[21](dialog.o)
      _drawCDKDialogButtons in libcdkw.a[21](dialog.o)
      _drawCDKDialogButtons in libcdkw.a[21](dialog.o)
      _boxWindow in libcdkw.a[22](draw.o)
      _boxWindow in libcdkw.a[22](draw.o)
      _boxWindow in libcdkw.a[22](draw.o)
      _boxWindow in libcdkw.a[22](draw.o)
      ...
  "_wbkgd$NCURSES60", referenced from:
      __setBKattrButton in libcdkw.a[11](button.o)
      __setBKattrDialog in libcdkw.a[21](dialog.o)
      _setCDKEntryHighlight in libcdkw.a[23](entry.o)
      __setBKattrEntry in libcdkw.a[23](entry.o)
      __setBKattrEntry in libcdkw.a[23](entry.o)
      __setBKattrEntry in libcdkw.a[23](entry.o)
      _drawCDKEntryField in libcdkw.a[23](entry.o)
      ...
  "_wgetch$NCURSES60", referenced from:
      _getcCDKObject in libcdkw.a[10](binding.o)
  "_whline$NCURSES60", referenced from:
      _boxWindow in libcdkw.a[22](draw.o)
      _boxWindow in libcdkw.a[22](draw.o)
      _attrbox in libcdkw.a[22](draw.o)
      _attrbox in libcdkw.a[22](draw.o)
      _drawLine in libcdkw.a[22](draw.o)
      _drawShadow in libcdkw.a[22](draw.o)
      _cleanCDKEntry in libcdkw.a[23](entry.o)
      ...
  "_wrefresh$NCURSES60", referenced from:
      __drawCDKButton in libcdkw.a[11](button.o)
      __focusCDKButton in libcdkw.a[11](button.o)
      __unfocusCDKButton in libcdkw.a[11](button.o)
      _eraseCursesWindow in libcdkw.a[14](cdk.o)
      _deleteCursesWindow in libcdkw.a[14](cdk.o)
      _refreshCDKScreen in libcdkw.a[19](cdkscreen.o)
      _refreshCDKWindow in libcdkw.a[19](cdkscreen.o)
      ...
  "_wvline$NCURSES60", referenced from:
      _boxWindow in libcdkw.a[22](draw.o)
      _boxWindow in libcdkw.a[22](draw.o)
      _attrbox in libcdkw.a[22](draw.o)
      _attrbox in libcdkw.a[22](draw.o)
      _drawLine in libcdkw.a[22](draw.o)
      _drawShadow in libcdkw.a[22](draw.o)
      _drawCDKScrollList in libcdkw.a[39](scroll.o)
      _drawCDKScrollList in libcdkw.a[39](scroll.o)
      ...
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [RpcExplorer] Error 1

问题更新

  • 移除ncurses库后重新链接,缺失符号数量增加,说明部分未版本化的符号可被ncurses库解析。
  • 在所有源文件及Makefile、configure等辅助文件中,均未找到NCURSES60字符串。

核心问题可简化为:

  • macOS 15.5上的clang编译CDK时,为何要求部分curses符号带版本号,其他符号却不需要?如何禁用该行为,让cdk不依赖特定版本的curses符号?

解决方案

1. 重新构建ncurses并禁用符号版本化

ncurses默认会给符号添加版本后缀,重新构建时添加--disable-versioned-symbols选项:

cd lib/ncurses-6.3
./configure --disable-versioned-symbols --prefix=$(pwd)/dist
make clean && make && make install

2. 指定CDK使用本地ncurses库

CDK编译时可能被系统ncurses头文件影响,强制使用了版本化符号。在CDK的configure阶段指定本地ncurses路径:

cd lib/cdk-5.0-20230201
./configure --prefix=$(pwd)/dist --with-ncurses=$(pwd)/../ncurses-6.3/dist
make clean && make && make install

3. 调整链接顺序

将ncurses库放在CDK库之后,确保链接器优先从ncurses中查找符号:
修改Makefile中的链接命令,把lib/ncurses-6.3/dist/lib/libncursesw_g.a移到lib/cdk-5.0-20230201/dist/lib/libcdkw.a之后:

g++ -std=c++17 -o RpcExplorer RpcExplorer.cc -Ilib/cdk-5.0-20230201/dist/include -Ilib/ncurses-6.3/dist/include -Ilib/protobuf-3.21.2/dist/include  lib/protobuf-3.21.2/dist/lib/libprotobuf.a lib/ncurses-6.3/dist/lib/libncursesw_g.a lib/cdk-5.0-20230201/dist/lib/libcdkw.a

4. 禁用链接器的严格符号版本检查

在链接时添加-Wl,-no_deduplicate标志,缓解符号版本匹配问题:

g++ -std=c++17 -o RpcExplorer RpcExplorer.cc -Ilib/cdk-5.0-20230201/dist/include -Ilib/ncurses-6.3/dist/include -Ilib/protobuf-3.21.2/dist/include  lib/protobuf-3.21.2/dist/lib/libprotobuf.a lib/cdk-5.0-20230201/dist/lib/libcdkw.a lib/ncurses-6.3/dist/lib/libncursesw_g.a -Wl,-no_deduplicate

系统改动说明

macOS Sequoia 15.5中,Apple调整了clang链接器对符号版本的处理逻辑,默认更严格地检查符号版本匹配。旧版本可能自动兼容版本化与非版本化符号,但新版本强制要求符号完全匹配,导致原本兼容的链接逻辑失效。

内容的提问来源于stack exchange,提问作者merlin2011

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:15:53