diff --git a/inline_src/BUILD.bazel b/inline_src/BUILD.bazel new file mode 100644 index 0000000..e69de29 diff --git a/inline_src/inline_src.bzl b/inline_src/inline_src.bzl new file mode 100644 index 0000000..5601411 --- /dev/null +++ b/inline_src/inline_src.bzl @@ -0,0 +1,100 @@ +"""Define the inline source object and its functions. +""" + +visibility("//lang/...") + +_INLINE_SRC_TYPE = "INLINE_SRC" + +def is_inline_src(obj): + """Test if an object is an inline source object or not. + + Args: + An object to test. + + Returns: + True it's an inline source object, false otherwise. + """ + return type(obj) == "struct" and getattr(obj, "type", None) == _INLINE_SRC_TYPE + +def inline_src_c(content): + """Construct an inline source object for C. + + Args: + content(str): Content of the source file. + + Returns: + An inline source object for C. + """ + + return struct( + type = _INLINE_SRC_TYPE, + content = content, + extension = "c", + ) + +def inline_src_cpp(content): + """Construct an inline source object for C++. + + Args: + content(str): Content of the source file. + + Returns: + An inline source object for C++. + """ + + return struct( + type = _INLINE_SRC_TYPE, + content = content, + extension = "cpp", + ) + +def _generate_inline_src_rule_impl(ctx): + """Implementation of `_generate_inline_src_rule`. + + Args: + ctx: Rule context. + + Returns: + Provider for the rule. + """ + output = ctx.actions.declare_file(ctx.label.name + "." + ctx.attr.extension) + ctx.actions.write( + output = output, + content = ctx.attr.content, + ) + return [DefaultInfo(files = depset([output]))] + +_generate_inline_src_rule = rule( + implementation = _generate_inline_src_rule_impl, + attrs = { + "content": attr.string( + doc = ( + "The content of the source file." + ), + mandatory = True, + ), + "extension": attr.string( + doc = ( + "The extension of the source file." + ), + mandatory = True, + ), + }, + provides = [DefaultInfo], +) + +def generate_inline_src(*, name, inline_src): + """Rule to generate inline source. + + Args: + name(str): The name of the target. + inline_src(inline source object): The inline source object to generate. + """ + if not is_inline_src(inline_src): + fail("`inline_src` must be an inline source object.") + + _generate_inline_src_rule( + name = name, + content = inline_src.content, + extension = inline_src.extension, + ) diff --git a/lang/cc/build_error.bzl b/lang/cc/build_error.bzl index abc151c..5f37dd4 100644 --- a/lang/cc/build_error.bzl +++ b/lang/cc/build_error.bzl @@ -9,6 +9,11 @@ load( "@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", ) +load( + "//inline_src:inline_src.bzl", + "generate_inline_src", + "is_inline_src", +) load( "//lang/private:general_build_actions.bzl", "DEFAULT_MATCHER", @@ -614,9 +619,19 @@ def cc_build_error( } kwargs.clear() + src = kwargs_try_build.pop("src") + if is_inline_src(src): + inline_src_target = name + "__i" + generate_inline_src( + name = inline_src_target, + inline_src = src, + ) + src = ":" + inline_src_target + try_build_target = name + "__0" _try_build( name = try_build_target, + src = src, tags = ["manual"] + tags, os = select({ Label("//platforms/os:linux"): "linux", diff --git a/lang/cc/defs.bzl b/lang/cc/defs.bzl index ab92f2a..722d555 100644 --- a/lang/cc/defs.bzl +++ b/lang/cc/defs.bzl @@ -7,9 +7,14 @@ load( _cc_build_error = "cc_build_error", _cc_build_error_test = "cc_build_error_test", ) +load( + ":inline_src.bzl", + _inline_src = "inline_src", +) visibility("public") cc_build_error = _cc_build_error cc_build_error_test = _cc_build_error_test CcBuildErrorInfo = _CcBuildErrorInfo +inline_src = _inline_src diff --git a/lang/cc/inline_src.bzl b/lang/cc/inline_src.bzl new file mode 100644 index 0000000..10c40af --- /dev/null +++ b/lang/cc/inline_src.bzl @@ -0,0 +1,15 @@ +"""Define `inline_src`. +""" + +load( + "//inline_src:inline_src.bzl", + "inline_src_c", + "inline_src_cpp", +) + +visibility("private") + +inline_src = struct( + c = inline_src_c, + cpp = inline_src_cpp, +)