Bazel中无法基于平台选择依赖问题求助
问题描述
我正在学习Bazel,尝试构建第三方库。有时使用Mac电脑,有时使用Linux电脑,因此构建opencv时希望根据平台使用不同的linkopts。查阅资料得知应该使用select和@platforms,但按配置在Linux机器上构建时出现如下错误:
ERROR: Target //thirdparty/opencv:opencv is incompatible and cannot be built, but was explicitly requested.
Dependency chain:
//thirdparty/opencv:opencv (442d8d)
//thirdparty/opencv:opencv_deps (442d8d) <-- target platform (@local_config_platform//:host) didn't satisfy constraint @platforms//os:osx
INFO: Elapsed time: 0.284s
看起来配置的选择逻辑没有生效,我的配置代码如下:
load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") cc_library( name = "opencv_deps", linkopts = select({ "@platforms//os:macos": [ "-ldl", "-lz", "-lpthread", "-lavutil", "-lavformat", "-lavcodec", "-lswscale", "-L/opt/homebrew/opt/ffmpeg/lib", "-L/opt/homebrew/Cellar/libx11/1.8.6/lib", "-framework Cocoa", "-framework Accelerate", ], "@platforms//os:linux": [ "-ldl", "-lz", "-lpthread" ], }), target_compatible_with = [ "@platforms//os:macos", "@platforms//os:linux" ], ) cmake( name = "opencv", build_args = [ "-j3", ], cache_entries = { "OPENCV_FORCE_3RDPARTY_BUILD": "ON", "BUILD_SHARED_LIBS": "OFF", "BUILD_TESTS": "OFF", "BUILD_PERF_TESTS": "OFF", "BUILD_opencv_apps": "OFF", "BUILD_opencv_calib3d": "OFF", "BUILD_opencv_core": "ON", "BUILD_opencv_dnn": "OFF", "BUILD_opencv_features2d": "OFF", "BUILD_opencv_flann": "OFF", "BUILD_opencv_gapi": "OFF", "BUILD_opencv_highgui": "ON", "BUILD_opencv_imgcodecs": "ON", "BUILD_opencv_imgproc": "ON", "BUILD_opencv_java_bindings_generator": "OFF", "BUILD_opencv_js": "OFF", "BUILD_opencv_ml": "OFF", "BUILD_opencv_objdetect": "OFF", "BUILD_opencv_photo": "OFF", "BUILD_opencv_python_bindings_generator": "OFF", "BUILD_opencv_stitching": "OFF", "BUILD_opencv_ts": "OFF", "BUILD_opencv_video": "OFF", "BUILD_opencv_videoio": "ON", "BUILD_opencv_world": "ON", "BUILD_IPP_IW": "ON", "WITH_ADE": "OFF", "WITH_CAROTENE": "OFF", "WITH_IPP": "OFF", "WITH_ITT": "ON", "WITH_OPENEXR": "OFF", "WITH_JASPER": "OFF", "WITH_JPEG": "OFF", "WITH_OPENJPEG": "ON", "WITH_TIFF": "OFF", "WITH_WEBP": "ON", "WITH_QUIRC": "ON", "WITH_GTK": "OFF", "WITH_OPENBLAS": "ON", "WITH_OPENCL": "OFF", }, env = { "CMAKE_BUILD_TYPE": "RelWithDebInfo", "CMAKE_BUILD_PARALLEL_LEVEL": "16", }, lib_source = "@opencv//:opencv_all", out_include_dir = "include/opencv4", out_static_libs = [ "libopencv_world.a", "opencv4/3rdparty/libittnotify.a", "opencv4/3rdparty/liblibopenjp2.a", "opencv4/3rdparty/liblibwebp.a", "opencv4/3rdparty/liblibpng.a", ], targets = [ "install", ], visibility = ["//visibility:public"], deps = [":opencv_deps"] )
问题原因及解决方法
报错的核心是target_compatible_with配置错误。Bazel中该字段的列表是逻辑与关系,要求目标平台同时满足所有约束。当前配置同时指定了@platforms//os:macos和@platforms//os:linux,这两个约束不可能同时成立,导致Linux平台判定opencv_deps不兼容。
解决方法有两种:
- 用
select为不同平台设置对应兼容性约束,确保每个平台只匹配自身的OS约束:
cc_library( name = "opencv_deps", linkopts = select({ "@platforms//os:macos": [ "-ldl", "-lz", "-lpthread", "-lavutil", "-lavformat", "-lavcodec", "-lswscale", "-L/opt/homebrew/opt/ffmpeg/lib", "-L/opt/homebrew/Cellar/libx11/1.8.6/lib", "-framework Cocoa", "-framework Accelerate", ], "@platforms//os:linux": [ "-ldl", "-lz", "-lpthread" ], }), target_compatible_with = select({ "@platforms//os:macos": ["@platforms//os:macos"], "@platforms//os:linux": ["@platforms//os:linux"], }), )
- 直接删除
target_compatible_with字段。因为linkopts中的select已经明确该库仅适用于macOS和Linux,Bazel会自动根据select条件推断兼容性,无需额外声明。
修改后重新构建,Linux平台就能正常匹配对应的linkopts,兼容性错误即可消除。
内容的提问来源于stack exchange,提问作者El_Loco

