Skip to content

Commit

Permalink
🎉 Release rules_carbon
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronmondal committed Jul 27, 2022
0 parents commit 29bfd1d
Show file tree
Hide file tree
Showing 19 changed files with 364 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Upstream LLVM/Clang requires C++17. This will only configure rules_cc.
build --repo_env=BAZEL_CXXOPTS='-std=c++17'
run --repo_env=BAZEL_CXXOPTS='-std=c++17'

# Separate the toolchain from regular code. This will put execution artifacts
# into bazel-out/ll_linux_exec_platform-opt-exec-<hash>.
build --experimental_platform_in_output_dir
run --experimental_platform_in_output_dir

# We require bzlmod.
build --experimental_enable_bzlmod
run --experimental_enable_bzlmod

# We use a custom registry.
build --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/
run --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/

# Hash diff (baseline config, transition config) in bazel-out directory names.
build --experimental_output_directory_naming_scheme=diff_against_baseline
run --experimental_output_directory_naming_scheme=diff_against_baseline

# Exec configuration handled by experimental_output_directory_layout.
build --experimental_exec_configuration_distinguisher=off
run --experimental_exec_configuration_distinguisher=off
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cbb4eb1973a7fb49d15ced3fea6498f714f3ab0c
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore Bazel build directories.
bazel-*
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:
- id: trailing-whitespace
exclude: ^patches/
- id: end-of-file-fixer
exclude: ^patches/
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: check-yaml
- id: check-case-conflict
- id: detect-private-key

- repo: https://github.com/PyCQA/doc8
rev: 0.10.1
hooks:
- id: doc8
name: doc8
description: This hook runs doc8 for linting docs
entry: python -m doc8
language: python
files: \.rst$

- repo: https://github.com/jlebar/pre-commit-hooks.git
rev: fb5e481f35f5a9b32a06ccfc28b8d6dda4525f75
hooks:
- id: bazel-buildifier
10 changes: 10 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module(
name = "rules_carbon",
version = "20220727.0",
compatibility_level = 0,
toolchains_to_register = [
"@rules_carbon//carbon:carbon_toolchain",
]
)

bazel_dep(name = "carbon", version = "0.0.0-2430c31")
106 changes: 106 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
Experimental rules for the experimental Carbon language
-------------------------------------------------------

This repository exposes ``carbon_binary`` to run Carbon files.

Since Carbon does not have a compiler yet, the ``carbon_binary`` target is a
shell wrapper around the proof-of-concept Carbon explorer. It is also only able
to take in a single source file as input.

- Examples: `rules_carbon/examples <https://github.com/eomii/rules_carbon/tree/main/examples>`_.

**Planned features**

- A full Carbon toolchain, as soon as a lowering to some form of processable IR
(probably LLVM IR) exists.
- ``carbon_library``, as soon as ``import`` is usable.
- Carbon-C++ interop with the toolchains in
`rules_ll <https://github.com/eomii/rules_ll>`_, as soon as this is feature is
implemented.

Quickstart
----------

Install `bazelisk <https://bazel.build/install/bazelisk>`_.

Execute the following commands in an empty directory to set up a Bazel module
capable of using ``carbon_binary``:

.. code:: bash
touch WORKSPACE.bazel .bazelrc
echo cbb4eb1973a7fb49d15ced3fea6498f714f3ab0c > .bazelversion
echo 'bazel_dep(name="rules_carbon", version="20220727.0")' > MODULE.bazel
Note that we use CI images of Bazel here because the prereleases do not include
the bugfixes we need.

Copy the following lines into the just created ``.bazelrc`` file:

.. code:: bash
# Upstream LLVM/Clang requires C++17. This will only configure rules_cc.
build --repo_env=BAZEL_CXXOPTS='-std=c++17'
run --repo_env=BAZEL_CXXOPTS='-std=c++17'
# Separate the toolchain from regular code. This will put execution artifacts
# into bazel-out/ll_linux_exec_platform-opt-exec-<hash>.
build --experimental_platform_in_output_dir
run --experimental_platform_in_output_dir
# We require bzlmod.
build --experimental_enable_bzlmod
run --experimental_enable_bzlmod
# We use a custom registry.
build --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/
run --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/
# Hash diff (baseline config, transition config) in bazel-out directory names.
build --experimental_output_directory_naming_scheme=diff_against_baseline
run --experimental_output_directory_naming_scheme=diff_against_baseline
# Exec configuration handled by experimental_output_directory_layout.
build --experimental_exec_configuration_distinguisher=off
run --experimental_exec_configuration_distinguisher=off
You can now load the ``carbon_executable`` rule definition in your
``BUILD.bazel`` files. For instance:

.. code:: python
load("@rules_carbon//carbon:defs.bzl", "carbon_binary")
carbon_binary(
name = "hello_world",
srcs = ["hello_world.carbon"],
# Uncomment the setting below to see fancy parser output.
# This setting is also enabled by running with --compilation_mode=dbg.
# interpreter_flags = [
# "--parser_debug",
# ]
)
See `rules_carbon/examples <https://github.com/eomii/rules_carbon/tree/main/examples>`_
for full examples.

Contributing
------------

Before you send a PR, install the ``pre-commit`` hooks::

pip install pre-commit
pre-commit install

and verify that all tools pass without failure on the entire repository::

pre-commit run --all-files

License
-------

Copyright 2022 `eomii <https://eomii.org>`_, distributed under the Apache 2.0
License.

The maintainers of ``rules_carbon`` absolutely love the Carbon project, but are
not affiliated with it in any way.
1 change: 1 addition & 0 deletions WORKSPACE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# We do not support classic WORKSPACE-based builds.
11 changes: 11 additions & 0 deletions carbon/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
load("//carbon:toolchain.bzl", "carbon_toolchain")

toolchain_type(name = "toolchain_type")

carbon_toolchain(name = "poc_toolchain")

toolchain(
name = "carbon_toolchain",
toolchain = ":poc_toolchain",
toolchain_type = ":toolchain_type",
)
85 changes: 85 additions & 0 deletions carbon/carbon.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#TODO: We can only create carbon_library when we have a proper toolchain :D

CARBON_RUNFILE = """#/bin/sh
{interpreter} {input_file}
"""

def _carbon_binary_impl(ctx):
"""Implementation function for carbon_binary.
Args:
ctx: The build context.
"""
inputs = ctx.files.srcs
if len(inputs) > 1:
fail("""The srcs attribute currently only supports a single source file.
This limitation will be lifted as soon as Carbon supports the imports.
""")

output = ctx.actions.declare_file(
"carbon_explorer_run_{}.sh".format(ctx.label.name),
)

args = ctx.attr.interpreter_flags
if ctx.var["COMPILATION_MODE"] == "dbg":
args = args + ["--parser_debug"]

output_content = """#!/bin/sh
{interpreter} --prelude={prelude} {args} {input}
""".format(
interpreter = ctx.toolchains["//carbon:toolchain_type"].interpreter.short_path,
prelude = ctx.toolchains["//carbon:toolchain_type"].prelude.path,
args = " ".join(args),
input = inputs[0].short_path,
)

ctx.actions.write(
output = output,
content = output_content,
is_executable = True,
)

runfiles = ctx.runfiles(
files = ctx.files.srcs + [
ctx.toolchains["//carbon:toolchain_type"].interpreter,
ctx.toolchains["//carbon:toolchain_type"].prelude,
],
)

return [
DefaultInfo(
executable = output,
runfiles = runfiles,
),
]

carbon_binary = rule(
implementation = _carbon_binary_impl,
executable = True,
attrs = {
"srcs": attr.label_list(
doc = """Compilable source files for this target.
The only file extension currently allowed is `".carbon"`.
""",
allow_files = [".carbon"],
),
"interpreter_flags": attr.string_list(
doc = "Additional arguments for the interpreter.",
),
},
toolchains = [
"//carbon:toolchain_type",
],
doc = """
Creates a carbon executable.
This is currently just a shell script that invokes the POC carbon explorer.
As soon as an actual toolchain exists this will be changed to produce a binary
executable.
Carbon does not yet have an implementation for C++ interop. As soon as
an implementation exists the attribute section for this target will be expanded
accordingly.
""",
)
3 changes: 3 additions & 0 deletions carbon/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load("//carbon:carbon.bzl", _carbon_binary = "carbon_binary")

carbon_binary = _carbon_binary
41 changes: 41 additions & 0 deletions carbon/toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
def _carbon_toolchain_impl(ctx):
prelude = ctx.actions.declare_file("prelude.carbon")
ctx.actions.symlink(
output = prelude,
target_file = ctx.file.prelude,
)

return [
platform_common.ToolchainInfo(
interpreter = ctx.executable.interpreter,
driver = ctx.executable.driver,
prelude = prelude,
),
]

carbon_toolchain = rule(
implementation = _carbon_toolchain_impl,
executable = False,
attrs = {
"interpreter": attr.label(
doc = """An interpreter. This is currently the carbon explorer.
As soon as we have a compiler we can remove this.""",
default = "@carbon//explorer:explorer",
executable = True,
cfg = "exec",
),
"driver": attr.label(
doc = """The carbon driver. Currently stops at the semantic AST,
since we do not have AST->LLVMIR yet.
""",
default = "@carbon//toolchain/driver:carbon",
executable = True,
cfg = "exec",
),
"prelude": attr.label(
doc = """The prelude.carbon file required by the interpreter.""",
default = "@carbon//explorer:standard_libraries",
allow_single_file = True,
),
},
)
24 changes: 24 additions & 0 deletions examples/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Upstream LLVM/Clang requires C++17. This will only configure rules_cc.
build --repo_env=BAZEL_CXXOPTS='-std=c++17'
run --repo_env=BAZEL_CXXOPTS='-std=c++17'

# Separate the toolchain from regular code. This will put execution artifacts
# into bazel-out/ll_linux_exec_platform-opt-exec-<hash>.
build --experimental_platform_in_output_dir
run --experimental_platform_in_output_dir

# We require bzlmod.
build --experimental_enable_bzlmod
run --experimental_enable_bzlmod

# We use a custom registry.
build --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/
run --registry=https://raw.githubusercontent.com/eomii/bazel-eomii-registry/main/

# Hash diff (baseline config, transition config) in bazel-out directory names.
build --experimental_output_directory_naming_scheme=diff_against_baseline
run --experimental_output_directory_naming_scheme=diff_against_baseline

# Exec configuration handled by experimental_output_directory_layout.
build --experimental_exec_configuration_distinguisher=off
run --experimental_exec_configuration_distinguisher=off
1 change: 1 addition & 0 deletions examples/.bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cbb4eb1973a7fb49d15ced3fea6498f714f3ab0c
2 changes: 2 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore Bazel build directories.
bazel-*
Empty file added examples/BUILD.bazel
Empty file.
4 changes: 4 additions & 0 deletions examples/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bazel_dep(name = "rules_carbon", version = "20220727.0")

# Uncomment this if runnning this example from a cloned rules_carbon repo.
# local_path_override(module_name = "rules_carbon", path = "..")
1 change: 1 addition & 0 deletions examples/WORKSPACE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# We do not support classic WORKSPACE-based builds.
13 changes: 13 additions & 0 deletions examples/hello_world/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@rules_carbon//carbon:defs.bzl", "carbon_binary")

carbon_binary(
name = "hello_world",
srcs = [
"hello_world.carbon",
],
# Uncomment the setting below to see fancy parser output.
# This setting is also enabled by running with --compilation_mode=dbg.
# interpreter_flags = [
# "--parser_debug",
# ]
)
7 changes: 7 additions & 0 deletions examples/hello_world/hello_world.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package HelloWorld api;

fn Main() -> i32 {
var s: auto = "Hello, World!";
Print(s);
return 0;
}

0 comments on commit 29bfd1d

Please sign in to comment.