load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain") def _generate_fruit_config_impl(ctx): cc_toolchain = find_cpp_toolchain(ctx) feature_configuration = cc_common.configure_features( ctx = ctx, cc_toolchain = cc_toolchain, requested_features = ctx.features, unsupported_features = ctx.disabled_features, ) c_compiler_path = cc_common.get_tool_for_action( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, ) check_output_files = [] for check_source in ctx.files.check_sources: check_name = check_source.path[:-len(".cpp")].split('/')[-1].split('\\')[-1] output_file = ctx.actions.declare_file(check_name + ".o") c_compile_variables = cc_common.create_compile_variables( feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts, source_file = check_source.path, output_file = output_file.path, ) command_line = cc_common.get_memory_inefficient_command_line( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, variables = c_compile_variables, ) env = cc_common.get_environment_variables( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, variables = c_compile_variables, ) check_define = 'FRUIT_HAS_%s' % check_name.upper() check_output_file = ctx.actions.declare_file(check_name + ".h") ctx.actions.run_shell( command = '"$@" &>/dev/null && echo "#define %s 1" >"%s" || echo "#define %s 0" >"%s"; touch "%s"' % ( check_define, check_output_file.path, check_define, check_output_file.path, output_file.path ), arguments = [c_compiler_path] + command_line, env = env, inputs = depset( [check_source], transitive = [cc_toolchain.all_files], ), outputs = [output_file, check_output_file], ) check_output_files.append(check_output_file) merged_output_file = ctx.actions.declare_file("fruit/impl/fruit-config-base.h") ctx.actions.run_shell( command = '\n'.join([ '(', 'echo "#ifndef FRUIT_CONFIG_BASE_H"', 'echo "#define FRUIT_CONFIG_BASE_H"', 'echo "#define FRUIT_USES_BOOST 1"', 'cat %s' % ' '.join([check_output_file.path for check_output_file in check_output_files]), 'echo "#endif"', ')>%s' % merged_output_file.path ]), inputs = check_output_files, outputs = [merged_output_file], ) compilation_context, compilation_outputs = cc_common.compile( actions = ctx.actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, public_hdrs = [merged_output_file], name = "%s_link" % ctx.label.name, ) linking_context, linking_outputs = cc_common.create_linking_context_from_compilation_outputs( actions = ctx.actions, feature_configuration = feature_configuration, compilation_outputs = compilation_outputs, cc_toolchain = cc_toolchain, name = "%s_link" % ctx.label.name, ) return [ DefaultInfo(files = depset([merged_output_file]), runfiles = ctx.runfiles(files = [merged_output_file])), CcInfo(compilation_context=compilation_context, linking_context=linking_context), ] generate_fruit_config = rule( implementation = _generate_fruit_config_impl, attrs = { "check_sources": attr.label_list(allow_files = True), "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), }, toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], fragments = ["cpp"], )