aboutsummaryrefslogtreecommitdiff
path: root/configuration/bazel/build_defs.bzl
blob: 28c3b17c4d2112c65807a098d37e6d472e209426 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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"],
)