1load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") 2load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain") 3 4def _generate_fruit_config_impl(ctx): 5 cc_toolchain = find_cpp_toolchain(ctx) 6 7 feature_configuration = cc_common.configure_features( 8 ctx = ctx, 9 cc_toolchain = cc_toolchain, 10 requested_features = ctx.features, 11 unsupported_features = ctx.disabled_features, 12 ) 13 c_compiler_path = cc_common.get_tool_for_action( 14 feature_configuration = feature_configuration, 15 action_name = C_COMPILE_ACTION_NAME, 16 ) 17 18 check_output_files = [] 19 for check_source in ctx.files.check_sources: 20 check_name = check_source.path[:-len(".cpp")].split('/')[-1].split('\\')[-1] 21 22 output_file = ctx.actions.declare_file(check_name + ".o") 23 24 c_compile_variables = cc_common.create_compile_variables( 25 feature_configuration = feature_configuration, 26 cc_toolchain = cc_toolchain, 27 user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts, 28 source_file = check_source.path, 29 output_file = output_file.path, 30 ) 31 command_line = cc_common.get_memory_inefficient_command_line( 32 feature_configuration = feature_configuration, 33 action_name = C_COMPILE_ACTION_NAME, 34 variables = c_compile_variables, 35 ) 36 env = cc_common.get_environment_variables( 37 feature_configuration = feature_configuration, 38 action_name = C_COMPILE_ACTION_NAME, 39 variables = c_compile_variables, 40 ) 41 42 check_define = 'FRUIT_HAS_%s' % check_name.upper() 43 check_output_file = ctx.actions.declare_file(check_name + ".h") 44 45 ctx.actions.run_shell( 46 command = '"$@" &>/dev/null && echo "#define %s 1" >"%s" || echo "#define %s 0" >"%s"; touch "%s"' % ( 47 check_define, check_output_file.path, check_define, check_output_file.path, output_file.path 48 ), 49 arguments = [c_compiler_path] + command_line, 50 env = env, 51 inputs = depset( 52 [check_source], 53 transitive = [cc_toolchain.all_files], 54 ), 55 outputs = [output_file, check_output_file], 56 ) 57 check_output_files.append(check_output_file) 58 59 merged_output_file = ctx.actions.declare_file("fruit/impl/fruit-config-base.h") 60 ctx.actions.run_shell( 61 command = '\n'.join([ 62 '(', 63 'echo "#ifndef FRUIT_CONFIG_BASE_H"', 64 'echo "#define FRUIT_CONFIG_BASE_H"', 65 'echo "#define FRUIT_USES_BOOST 1"', 66 'cat %s' % ' '.join([check_output_file.path for check_output_file in check_output_files]), 67 'echo "#endif"', 68 ')>%s' % merged_output_file.path 69 ]), 70 inputs = check_output_files, 71 outputs = [merged_output_file], 72 ) 73 74 compilation_context, compilation_outputs = cc_common.compile( 75 actions = ctx.actions, 76 feature_configuration = feature_configuration, 77 cc_toolchain = cc_toolchain, 78 public_hdrs = [merged_output_file], 79 name = "%s_link" % ctx.label.name, 80 ) 81 82 linking_context, linking_outputs = cc_common.create_linking_context_from_compilation_outputs( 83 actions = ctx.actions, 84 feature_configuration = feature_configuration, 85 compilation_outputs = compilation_outputs, 86 cc_toolchain = cc_toolchain, 87 name = "%s_link" % ctx.label.name, 88 ) 89 90 return [ 91 DefaultInfo(files = depset([merged_output_file]), runfiles = ctx.runfiles(files = [merged_output_file])), 92 CcInfo(compilation_context=compilation_context, linking_context=linking_context), 93 ] 94 95generate_fruit_config = rule( 96 implementation = _generate_fruit_config_impl, 97 attrs = { 98 "check_sources": attr.label_list(allow_files = True), 99 "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), 100 }, 101 toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 102 fragments = ["cpp"], 103)