1# Forked from header_template_rule. header_template_rule is not 2# compatible with our usage of select because its substitutions 3# attribute is a dict, and dicts may not be appended with select. We 4# get around this limitation by using a list as our substitutions. 5def _cmake_configure_file_impl(ctx): 6 command = ["cat $1"] 7 for definition in ctx.attr.definitions: 8 command.append( 9 "| sed 's@#cmakedefine {}@#define {}@'".format( 10 definition, 11 definition, 12 ), 13 ) 14 15 # Replace any that remain with /* #undef FOO */. 16 command.append("| sed -r 's@#cmakedefine ([A-Z0-9_]+)@/* #undef \\1 */@'") 17 command.append("> $2") 18 19 ctx.actions.run_shell( 20 inputs = [ctx.file.src], 21 outputs = [ctx.outputs.out], 22 command = " ".join(command), 23 arguments = [ 24 ctx.file.src.path, 25 ctx.outputs.out.path, 26 ], 27 ) 28 return [ 29 # create a provider which says that this 30 # out file should be made available as a header 31 CcInfo(compilation_context = cc_common.create_compilation_context( 32 33 # pass out the include path for finding this header 34 includes = depset([ctx.outputs.out.dirname, ctx.bin_dir.path]), 35 36 # and the actual header here. 37 headers = depset([ctx.outputs.out]), 38 )), 39 ] 40 41cmake_configure_file = rule( 42 implementation = _cmake_configure_file_impl, 43 doc = """ 44Mimics CMake's configure_file in Bazel. 45 46Args: 47 name: A unique name for this rule. 48 src: The input file template. 49 out: The generated output. 50 definitions: A mapping of identifier in template to its value. 51""", 52 attrs = { 53 # We use attr.string_list for compatibility with select and 54 # config_setting. See the comment above _cmake_configure_file_impl 55 # for more information. 56 "definitions": attr.string_list(mandatory = True), 57 "out": attr.output(mandatory = True), 58 "src": attr.label( 59 mandatory = True, 60 allow_single_file = True, 61 ), 62 }, 63 # output_to_genfiles is required for header files. 64 output_to_genfiles = True, 65) 66