使用Bazel构建ncurses代码时出错:'unctrl'类型冲突
问题描述
基于Bazel构建的ncurses项目,迁移至Bazel 8.0.0 LTS的bzlmod后,使用Bazel中央仓库的ncurses模块构建时出现编译错误,提示conflicting types for 'unctrl'。具体错误如下:
$ bazel build //foo:color --verbose_failures INFO: Analyzed target //foo:color (0 packages loaded, 0 targets configured). ERROR: /Users/dzc/Projects/davidzchen/bazel-ncurses-example/foo/BUILD:3:11: Compiling foo/color.cc failed: (Exit 1): cc_wrapper.sh failed: error executing CppCompile command (from target //foo:color) (cd /private/var/tmp/_bazel_dzc/87450ce08cbc0c792b19d6253d30d152/sandbox/darwin-sandbox/143/execroot/_main && \ exec env - \ PATH='/Users/dzc/Library/Caches/bazelisk/downloads/sha256/ea529c3c03d6981e13e25af126b63b41435c9a42bf28435bbabbe3b11542ddcf/bin:/opt/homebrew/opt/ruby/bin:/opt/homebrew/opt/llvm/bin:/opt/local/bin:/opt/local/sbin:/Users/dzc/.bin:/Users/dzc/.local/bin:/usr/local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Applications/VMware Fusion.app/Contents/Public:~/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/opt/homebrew/opt/ruby/bin:/opt/homebrew/opt/llvm/bin:/Applications/iTerm.app/Contents/Resources/utilities:/Users/dzc/go/bin:/opt/homebrew/opt/go/libexec/bin:/Library/Frameworks/Mono.framework/Commands:/Users/dzc/.antigen/bundles/robbyrussell/oh-my-zsh/lib:/Users/dzc/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/history-substring-search:/Users/dzc/.antigen/bundles/zsh-users/zsh-syntax-highlighting:/Users/dzc/.antigen/bundles/zsh-users/zsh-completions:/Users/dzc/.antigen/bundles/zsh-users/zsh-autosuggestions' \ PWD=/proc/self/cwd \ external/rules_cc++cc_configure_extension+local_config_cc/cc_wrapper.sh -U_FORTIFY_SOURCE -fstack-protector -Wall -Wthread-safety -Wself-assign -Wunused-but-set-parameter -Wno-free-nonheap-object -fcolor-diagnostics -fno-omit-frame-pointer '-std=c++17' '-frandom-seed=bazel-out/darwin_arm64-fastbuild/bin/foo/_objs/color/color.o' -iquote . -iquote bazel-out/darwin_arm64-fastbuild/bin -iquote external/ncurses+ -iquote bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+ -isystem external/ncurses+/include -isystem bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+/include -isystem external/ncurses+/ncurses -isystem bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+/ncurses '-mmacosx-version-min=15.2' -MD -MF bazel-out/darwin_arm64-fastbuild/bin/foo/_objs/color/color.d '-std=c++20' -c foo/color.cc -o bazel-out/darwin_arm64-fastbuild/bin/foo/_objs/color/color.o -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -Xclang '-fmodule-name=//foo:color' -Xclang '-fmodule-map-file=bazel-out/darwin_arm64-fastbuild/bin/foo/color.cppmap' -Xclang -fno-cxx-modules -fmodules-strict-decluse -Wprivate-header -Xclang '-fmodule-map-file=external/rules_cc++cc_configure_extension+local_config_cc/module.modulemap' -Xclang '-fmodule-map-file=bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+/ncurses.cppmap') # Configuration: 9b382b18c38178c86436d40b630070f6a7b54b2d54b8541e3a8dda9e825538d4 # Execution platform: @@platforms//host:host Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging In file included from foo/color.cc:3: In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ncurses.h:2918: bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+/include/unctrl.h:61:54: error: conflicting types for 'unctrl' 61 | NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype); | ^ bazel-out/darwin_arm64-fastbuild/bin/external/ncurses+/include/unctrl.h:58:38: note: previous declaration is here 58 | NCURSES_EXPORT(NCURSES_CONST char *) unctrl (chtype); | ^ 1 error generated. Target //foo:color failed to build INFO: Elapsed time: 2.201s, Critical Path: 0.91s INFO: 97 processes: 11 internal, 86 darwin-sandbox. ERROR: Build did NOT complete successfully
已知bazel build @ncurses可成功执行,但构建项目目标时Bazel加载系统ncurses.h而非远程归档文件,添加common --incompatible_strict_action_env至.bazelrc后问题未解决。环境为Bazel 8.0.0、macOS Sequoia 15.2。
原因分析
- 头文件冲突:macOS SDK自带的ncurses.h会包含系统版本的
unctrl.h,而Bazel中央仓库的ncurses模块也提供了自己的unctrl.h,两者对unctrl函数的声明不一致(系统版本无SCREEN*参数,远程版本有该参数),导致类型冲突。 - include路径优先级:Bazel默认编译配置中,系统SDK的头文件路径优先级高于远程ncurses模块的include路径,使得编译器优先找到系统的ncurses.h,进而引入冲突的头文件。
解决方法
方法1:调整头文件包含顺序,优先使用远程ncurses头文件
修改项目中目标的BUILD配置,强制编译器先查找远程ncurses的include目录,覆盖系统头文件:
cc_binary( name = "color", srcs = ["color.cc"], deps = ["@ncurses//:ncurses"], # 确保远程ncurses的头文件路径优先级最高 copts = ["-isystem $(execpath @ncurses//:include)"], includes = ["external/ncurses/include"], )
方法2:通过bzlmod配置增强依赖隔离
在MODULE.bazel中确保ncurses模块正确引入,并添加额外配置强化隔离:
bazel_dep(name = "ncurses", version = "6.4.20240210") # 禁用系统ncurses的自动检测 build_setting( name = "ncurses_disable_system", build_setting_default = "true", visibility = ["//visibility:public"], )
方法3:定义宏避免头文件重复包含
在编译选项中添加宏定义,阻止系统ncurses头文件的部分内容加载:
cc_binary( name = "color", srcs = ["color.cc"], deps = ["@ncurses//:ncurses"], copts = [ "-D NCURSES_NOMACROS", "-D NCURSES_INCLUDED", ], )
验证
修改配置后重新执行构建命令:
bazel build //foo:color --verbose_failures
内容的提问来源于stack exchange,提问作者archetypezero
相关产品推荐
相关产品推荐

