Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ module(
)

bazel_dep(name = "rules_cc", version = "0.0.4")
bazel_dep(name = "bazel_skylib", version = "1.4.1")
bazel_dep(name = "stardoc", version = "0.5.3")
13 changes: 13 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("//third_party:test_repos.bzl", "test_repos")

http_archive(
name = "bazel_skylib",
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
],
)

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")

bazel_skylib_workspace()

http_archive(
name = "io_bazel_stardoc",
sha256 = "3fd8fec4ddec3c670bd810904e2e33170bedfe12f90adf943508184be458c8bb",
Expand Down
15 changes: 13 additions & 2 deletions cc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@modular_cc_toolchain//cc:features.bzl", "cc_feature", "action_mux")
load("//cc:action_names.bzl", "ACTION_NAME_GROUPS")
load("//cc:actions.bzl", "cc_action_config")
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
load("//cc:toolchain.bzl", "cc_toolchain_config")

cc_feature(
name = "garbage_collect_sections",
Expand All @@ -18,14 +19,24 @@ cc_feature(
cc_action_config(
name = "default_clang",
action_tools = {
ACTION_NAMES.c_compile: "@clang_llvm_x86_64_linux_gnu_ubuntu//:bin/clang",
ACTION_NAMES.c_compile: "@clang_llvm_x86_64_linux_gnu_ubuntu//:cc",
}
)

cc_toolchain_config(
name = "test_toolchain_config",
cc_features = [
":garbage_collect_sections",
],
action_configs = [
":default_clang",
]
)

filegroup(
name = "bzl_srcs",
srcs = glob(["*.bzl"]),
visibility = ["//visibility:public"],
)

exports_files(glob(["*.bzl"]))
exports_files(glob(["*.bzl"]))
36 changes: 36 additions & 0 deletions cc/common_features/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
load("@modular_cc_toolchain//cc:features.bzl", "cc_feature", "action_mux")
load("//cc:action_names.bzl", "ACTION_NAME_GROUPS")
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")

cc_feature(
name = "garbage_collect_sections",
action_flags = action_mux({
# Put each function and global var in their own linker section.
ACTION_NAME_GROUPS.all_cc_compile_actions: ["-ffunction-sections", "-fdata-sections"],
# Remove unused functions/symbols from linked binary.
ACTION_NAME_GROUPS.all_cc_link_actions: ["-Wl,--gc-sections"],
}),
doc = "Place each function in it's own section so that the linker can discard unused functions",
)

cc_feature(
name = "dependency_file",
enabled = True,
action_flags = action_mux({
(ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.objc_compile,
ACTION_NAMES.objcpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.clif_match): [
"-MD",
"-MF",
"%{dependency_file}",
]
})
)


135 changes: 125 additions & 10 deletions cc/features.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,79 @@

load(
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
"FeatureInfo",
"FeatureSetInfo",
"feature",
"feature_set",
"flag_group",
"flag_set",
)
load(
"@rules_cc//cc:action_names.bzl",
"ACTION_NAMES",
"ACTION_NAME_GROUPS",
)

ALL_COMPILE_ACTIONS = ACTION_NAME_GROUPS.all_cc_compile_actions + \
ACTION_NAME_GROUPS.all_cpp_compile_actions

ALL_SYSROOT_ACTIONS = ACTION_NAME_GROUPS.all_cc_compile_actions + \
ACTION_NAME_GROUPS.all_cc_link_actions + \
ACTION_NAME_GROUPS.all_cpp_compile_actions + \
ACTION_NAME_GROUPS.cc_link_executable_actions + \
ACTION_NAME_GROUPS.dynamic_library_link_actions + \
ACTION_NAME_GROUPS.nodeps_dynamic_library_link_actions + \
ACTION_NAME_GROUPS.transitive_link_actions

ALL_LINK_ACTIONS = ACTION_NAME_GROUPS.all_cc_link_actions + \
ACTION_NAME_GROUPS.cc_link_executable_actions + \
ACTION_NAME_GROUPS.dynamic_library_link_actions

# Extracted from: https://bazel.build/docs/cc-toolchain-config-reference#cctoolchainconfiginfo-build-variables
FLAG_VARS = {
"%{source_file}": ALL_COMPILE_ACTIONS,
"%{input_file}": ACTION_NAMES.strip,
"%{output_file}": ALL_COMPILE_ACTIONS,
"%{output_assembly_file}": ALL_COMPILE_ACTIONS,
"%{output_preprocess_file}": ALL_COMPILE_ACTIONS,
"%{dependency_file}": ALL_COMPILE_ACTIONS,
"%{pic}": ALL_COMPILE_ACTIONS,
"%{gcov_gcno_file}": ALL_COMPILE_ACTIONS,
"%{per_object_debug_info_file}": ALL_COMPILE_ACTIONS,
"%{sysroot}": ALL_SYSROOT_ACTIONS,
"%{def_file_path}": ALL_LINK_ACTIONS,
"%{linker_param_file}": ALL_LINK_ACTIONS,
"%{output_execpath}": ALL_LINK_ACTIONS,
"%{generate_interface_library}": ALL_LINK_ACTIONS,
"%{interface_library_builder_path}": ALL_LINK_ACTIONS,
"%{interface_library_input_path}": ALL_LINK_ACTIONS,
"%{interface_library_output_path}": ALL_LINK_ACTIONS,
"%{force_pic}": ALL_LINK_ACTIONS,
"%{strip_debug_symbols}": ALL_LINK_ACTIONS,
"%{is_cc_test}": ALL_LINK_ACTIONS,
"%{is_using_fission}": ALL_LINK_ACTIONS + ALL_LINK_ACTIONS,
"%{fdo_instrument_path}": ALL_COMPILE_ACTIONS + ALL_LINK_ACTIONS,
"%{fdo_prefetch_hints_path}": ALL_COMPILE_ACTIONS,
"%{csfdo_instrument_path}": ALL_COMPILE_ACTIONS + ALL_LINK_ACTIONS,
}

# Extracted from: https://bazel.build/docs/cc-toolchain-config-reference#cctoolchainconfiginfo-build-variables
FLAG_SEQUENCE_VARS = {
"%{includes}": ALL_COMPILE_ACTIONS,
"%{include_paths}": ALL_COMPILE_ACTIONS,
"%{quote_include_paths}": ALL_COMPILE_ACTIONS,
"%{system_include_paths}": ALL_COMPILE_ACTIONS,
"%{preprocessor_defines}": ALL_COMPILE_ACTIONS,
"%{striptopts}": ACTION_NAMES.strip,
"%{legacy_compile_flags}": ALL_COMPILE_ACTIONS,
"%{user_compile_flags}": ALL_COMPILE_ACTIONS,
"%{unfiltered_compile_flags}": ALL_COMPILE_ACTIONS,
"%{runtime_library_search_directories}": ALL_LINK_ACTIONS,
"%{library_search_directories}": ALL_LINK_ACTIONS,
"%{libraries_to_link}": ALL_LINK_ACTIONS,
"%{legacy_link_flags}": ALL_LINK_ACTIONS,
"%{user_link_flags}": ALL_LINK_ACTIONS,
"%{linkstamp_flags}": ALL_LINK_ACTIONS,
}

def action_mux(action_map):
""" Expands an iterable set of actions that map to a given flag.
Expand All @@ -19,6 +87,46 @@ def action_mux(action_map):
action_flags[action] = action_flags.get(action, []) + flags
return action_flags

BUILD_VARS_DOC_URL = "https://bazel.build/docs/cc-toolchain-config-reference"

def _extract_build_var_from_flag(flag):
var_start_index = flag.find("%{")
if var_start_index == -1:
return None
var_end_index = flag.find("}", start = var_start_index)
if var_end_index == -1:
fail(
"In flag '%s' opening variable '%{' was found but got to \
end of flag and no closing bracket found '}'" % (flag),
)
else:
allowed_in_variable = list("abcdefghijklmnopqrstuvwxyz_".elems())
flag_name = flag[var_start_index + 2:var_end_index]
for c in flag_name.elems():
if c not in allowed_in_variable:
fail(
"Found invalid character: ",
c,
" in variable.",
" The following characters are supported:\n",
allowed_in_variable,
"See the docs for more information: ",
BUILD_VARS_DOC_URL,
)

return flag[var_start_index:var_end_index + 1]

def _validate_build_var_with_action(build_var, action, is_iterated = False):
if is_iterated:
if build_var not in FLAG_SEQUENCE_VARS.keys():
fail("Build var '%s' is not found or is not a sequence" % build_var)
else:
valid_actions = FLAG_VARS.get(build_var)
if not valid_actions:
fail("Build var '%s' is not found or is a sequence, and requires iteration" % build_var)
if action not in valid_actions:
fail("Build var is used with unsupported action '%s', the following actions are supported for this build var:\n %s" % (action, valid_actions))

def _action_flags_as_flag_set(action, flags):
return flag_set(
actions = [action],
Expand All @@ -27,18 +135,22 @@ def _action_flags_as_flag_set(action, flags):

def _cc_feature_impl(ctx):
runfiles = ctx.runfiles(files = [])
feature_deps = []
for dep in ctx.attr.deps:
runfiles.merge(dep[DefaultInfo].default_runfiles)
if FeatureSetInfo in dep:
feature_deps.extend(dep[FeatureSetInfo].features)

this_feature = feature(
name = str(ctx.label),
enabled = ctx.attr.enabled,
flag_sets = [
_action_flags_as_flag_set(action, flags)
for action, flags in ctx.attr.action_flags.items()
],
)
return [
feature(
name = str(ctx.label),
enabled = ctx.attr.enabled,
flag_sets = [
_action_flags_as_flag_set(action, flags)
for action, flags in ctx.attr.action_flags.items()
],
),
feature_set(features = feature_deps + [this_feature]),
DefaultInfo(
files = depset(transitive = [
dep[DefaultInfo].files
Expand All @@ -64,8 +176,11 @@ cc_feature = rule(
"deps": attr.label_list(
doc = "The set of features that this feature implicitly enables/implies.",
),
"iterative_over_build_var": attr.string(
doc = "Iterate over a build variable"
)
},
provides = [FeatureInfo],
provides = [FeatureSetInfo],
doc = """
Configure a pipeline through each action in the C++ build.

Expand Down
77 changes: 77 additions & 0 deletions cc/toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
load("@rules_cc//cc:cc_toolchain_config_lib.bzl", "FeatureSetInfo", "tool_path")

# We are going to use action_confgs for everything as an alternative to
# using tool_paths which just add unneccesary confusion.
_NULL_TOOL_PATHS = [
tool_path(
name = "gcc",
path = "/usr/bin/clang",
),
tool_path(
name = "ld",
path = "/usr/bin/ld",
),
tool_path(
name = "ar",
path = "/bin/false",
),
tool_path(
name = "cpp",
path = "/bin/false",
),
tool_path(
name = "gcov",
path = "/bin/false",
),
tool_path(
name = "nm",
path = "/bin/false",
),
tool_path(
name = "objdump",
path = "/bin/false",
),
tool_path(
name = "strip",
path = "/bin/false",
),
]

def _toolchain_config_impl(ctx):
features = []
for feature in ctx.attr.features:
features.extend(feature[FeatureSetInfo].features)

return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
features = features, # NEW
# Unused let features handle this.
cxx_builtin_include_directories = [],
tool_paths = _NULL_TOOL_PATHS,

# TODO: Do we actually need any of these?
toolchain_identifier = "local",
host_system_name = "local",
target_system_name = "local",
target_cpu = "unknown",
target_libc = "unknown",
compiler = "unknown",
abi_version = "unknown",
abi_libc_version = "unknown",
)

cc_toolchain_config = rule(
_toolchain_config_impl,
attrs = {
"cc_features": attr.label_list(
doc = "The list of cc_features to include in this toolchain.",
mandatory = True,
providers = [FeatureSetInfo],
),
"action_configs": attr.label_list(
doc = "The list of cc_action_configs to include in this toolchain.",
mandatory = True,
),
},
provides = [CcToolchainConfigInfo],
)
40 changes: 40 additions & 0 deletions third_party/clang_llvm_x86_64_linux_gnu_ubuntu.BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
load("@bazel_skylib//rules:native_binary.bzl", "native_binary")
package(default_visibility = ["//visibility:public"])

exports_files(glob(["**/*"]))

filegroup(
name = "all_files",
srcs = glob(["**/*"]),
)

TOOLS = {
"cxx": {
"tool": "//:bin/clang++",
"data": ["//:cc"],
},
"cc": {
"tool": "//:bin/clang",
"data": ["//:ld"],
},
"ld": {
"tool": "//:bin/ld.lld",
"data": [],
},
"ar": {
"tool": "//:bin/llvm-ar",
"data": [],
},
"objdump": {
"tool": "//:bin/llvm-objdump",
"data": [],
},
"strip": {
"tool": "//:bin/llvm-strip",
"data": [],
},
}

[
native_binary(
name = name,
src = info["tool"],
data = info["data"],
out = name,
)
for name, info in TOOLS.items()
]