如何通过Bazel genrule正确获取ISPC生成的输出文件?
问题分析
Bazel的genrule运行在隔离沙盒中,所有输入输出的路径由Bazel统一管理。你当前的genrule命令直接使用相对文件名(如square.h、square.o)指定输出位置,导致ISPC生成的文件不在Bazel预期的输出路径下,因此Bazel无法检测到这些文件,触发"declared output was not created"错误。
另外代码中存在拼写错误:generted_header_filename应为generated_header_filename,虽不直接导致当前问题,但建议修正以避免后续混淆。
修复方案
核心修改:使用Bazel的位置变量指定输出路径
在genrule的cmd中,必须用$(location <文件名>)来获取Bazel为输出文件分配的沙盒内路径,而非直接写文件名。同时优化规则以支持多ISPC源文件:
修改ispc_cc_library的实现如下:
def ispc_cc_library(name, srcs, target_compatible_with = [], **kwargs): generated_objs = [] generated_hdrs = [] for ispc_source_file in srcs: # 为每个源文件生成唯一的输出文件名,避免冲突 base_name = ispc_source_file.split('.')[0] generated_header = f"{name}_{base_name}.h" generated_obj = f"{name}_{base_name}.o" generated_objs.append(generated_obj) generated_hdrs.append(generated_header) native.genrule( name = f"{name}_{base_name}_ispc_gen", srcs = [ispc_source_file], outs = [generated_obj, generated_header], cmd = select({ "@platforms//os:linux": f""" $(location @ispc_linux_x86_64//:ispc) \\ --target=avx2 --arch=x86-64 \\ $(location {ispc_source_file}) \\ --header-outfile=$(location {generated_header}) \\ -o $(location {generated_obj}) """, "@platforms//os:osx": f""" $(location @ispc_osx_x86_64//:ispc) \\ --target=avx2 --arch=x86-64 \\ $(location {ispc_source_file}) \\ --header-outfile=$(location {generated_header}) \\ -o $(location {generated_obj}) """, "@platforms//os:windows": f""" $(location @ispc_windows_x86_64//:ispc) \\ --target=avx2 --target-os=windows --arch=x86-64 \\ $(location {ispc_source_file}) \\ --header-outfile=$(location {generated_header}) \\ -o $(location {generated_obj}) """, }), tools = select({ "@platforms//os:linux": ["@ispc_linux_x86_64//:ispc"], "@platforms//os:osx": ["@ispc_osx_x86_64//:ispc"], "@platforms//os:windows": ["@ispc_windows_x86_64//:ispc"], }), target_compatible_with = target_compatible_with, ) native.cc_library( name = name, srcs = generated_objs, hdrs = generated_hdrs, target_compatible_with = target_compatible_with, **kwargs )
修改要点说明
- 路径引用修正:用
$(location)变量替代直接文件名,确保ISPC将文件生成到Bazel管控的正确路径,让Bazel能检测到输出文件。 - 多源文件支持:为每个ISPC源文件生成唯一的输出文件和genrule名称,避免多文件场景下的命名冲突。
- 拼写修正:修复了
generted_header_filename的拼写错误,提升代码可读性。 - 参数整理:将所有生成的目标文件和头文件统一传入
cc_library,确保规则能正确聚合输出。
验证修复
执行以下命令重新构建:
git clone https://github.com/Vertexwahn/rules_ispc.git cd rules_ispc cd tests bazel build //example:main
此时Bazel应能正确识别ISPC生成的.o和.h文件,构建流程正常完成。
内容的提问来源于stack exchange,提问作者Vertexwahn
相关产品推荐
相关产品推荐

