Home

Awesome

Build status

D rules

Status

We make sure this repository works with the latest version of Bazel, but no other development is planned.

Volunteers are welcome. If you want to use the rules, consider contributing to this repository and becoming a maintainer.

Rules

<div class="toc"> <ul> <li><a href="#d_library">d_library</a></li> <li><a href="#d_source_library">d_source_library</a></li> <li><a href="#d_binary">d_binary</a></li> <li><a href="#d_test">d_test</a></li> <li><a href="#d_docs">d_docs</a></li> </ul> </div>

Setup

To use the D rules, add the following to your WORKSPACE file to add the external repositories for the D toolchain:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "io_bazel_rules_d",
    urls = ["https://github.com/bazelbuild/rules_d/archive/bcf137e3c9381545ce54715632bc1d31c51ee4da.tar.gz"],
    sha256 = "a32847bf2ae634563dece49c4dc8353956b64ba5c2d01ce811ea243e1a21b5b7",
    strip_prefix = "rules_d-bcf137e3c9381545ce54715632bc1d31c51ee4da",
)

load("@io_bazel_rules_d//d:d.bzl", "d_repositories")
d_repositories()

Roadmap

<a name="d_library"></a>

d_library

d_library(name, srcs, deps, includes, linkopts, versions)
<table class="table table-condensed table-bordered table-params"> <colgroup> <col class="col-param" /> <col class="param-description" /> </colgroup> <thead> <tr> <th colspan="2">Attributes</th> </tr> </thead> <tbody> <tr> <td><code>name</code></td> <td> <code>Name, required</code> <p>A unique name for this rule.</p> <p> This name will be used as the name of the library built by this rule. </p> </td> </tr> <tr> <td><code>srcs</code></td> <td> <code>List of labels, required</code> <p>List of D <code>.d</code> source files used to build the library.</p> </td> </tr> <tr> <td><code>deps</code></td> <td> <code>List of labels, optional</code> <p>List of libraries to be linked to this library target.</p> <p> These can either be other <code>d_library</code> targets, source-only <code>d_source_library</code> targets, or <code>cc_library</code> targets if linking a native library. </p> </td> </tr> <tr> <td><code>imports</code></td> <td> <code>List of strings, optional</code> <p>List of import dirs to add to the compile line.</p> <p> These will be passed to the D compiler via <code>-I</code> flags. </p> </td> </tr> <tr> <td><code>linkopts</code></td> <td> <code>List of strings, optional</code> <p>List of flags that are added to the D linker command.</p> <p> These will be passed to the D compiler via <code>-L</code> flags. </p> </td> </tr> <tr> <td><code>versions</code></td> <td> <code>List of strings, optional</code> <p>List of versions to be defined during compilation.</p> <p> Versions are used for conditional compilation and are enabled in the code using <code>version</code> condition blocks. These versions listed here will be passed to the D compiler using <code>-version</code> flags. </p> </td> </tr> </tbody> </table>

Example

Suppose you have the following directory structure for a D project:

[workspace]/
    WORKSPACE
    foo/
        BUILD
        foo.d
        bar.d
        baz.d

The library foo is built using a d_library target:

foo/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_library")

d_library(
    name = "foo",
    srcs = [
        "foo.d",
        "bar.d",
        "baz.d",
    ],
)

<a name="d_source_library"></a>

d_source_library

d_source_library(name, srcs, deps, includes, linkopts, versions)
<table class="table table-condensed table-bordered table-params"> <colgroup> <col class="col-param" /> <col class="param-description" /> </colgroup> <thead> <tr> <th colspan="2">Attributes</th> </tr> </thead> <tbody> <tr> <td><code>name</code></td> <td> <code>Name, required</code> <p>A unique name for this rule.</p> </td> </tr> <tr> <td><code>srcs</code></td> <td> <code>List of labels, required</code> <p> List of D <code>.d</code> source files that comprises this source library target. </p> </td> </tr> <tr> <td><code>deps</code></td> <td> <code>List of labels, optional</code> <p>List of library targets depended on by this target.</p> <p> These can either be other <code>d_source_library</code> targets or <code>cc_library</code> targets, such as when this source library target implements the D interface for a native library. Any native libraries will be linked by <code>d_library</code> targets that depend on this target. </p> </td> </tr> <tr> <td><code>imports</code></td> <td> <code>List of strings, optional</code> <p>List of import dirs to add to the compile line.</p> <p> These will be passed to the D compiler via <code>-I</code> flags for any <code>d_library</code> targets that depend on this target. </p> </td> </tr> <tr> <td><code>linkopts</code></td> <td> <code>List of strings, optional</code> <p>List of flags that are added to the D linker command.</p> <p> These will be passed to the D compiler via <code>-L</code> flags for any <code>d_library</code> targets that depend on this target. </p> </td> </tr> <tr> <td><code>versions</code></td> <td> <code>List of strings, optional</code> <p>List of version flags to be defined during compilation.</p> <p> Versions are used for conditional compilation and are enabled in the code using <code>version</code> condition blocks. These versions listed here will be passed to the D compiler using <code>-version</code> flags for any <code>d_library</code> targets that depend on this target. </p> </td> </tr> </tbody> </table>

Example

Suppose you have the following directory structure for a project building a C library and a D interface for the C library:

[workspace]/
    WORKSPACE
    greeter/
        BUILD
        native_greeter.c
        native_greeter.h
        native_greeter.d
    hello_world
        BUILD
        hello_world.d

Build the C library using the cc_library rule and then use the d_source_library to define the target for the D interface for the C native_greeter library:

greeter/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_source_library")

cc_library(
    name = "native_greeter_lib",
    srcs = ["native_greeter.c"],
    hdrs = ["native_greeter.h"],
)

d_source_library(
    name = "native_greeter",
    srcs = ["native_greeter.d"],
    deps = [":native_greeter_lib"],
)

Other targets can directly depend on the d_source_library target to link the C library:

hello_world/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_source_library")

d_binary(
    name = "hello_world",
    srcs = ["hello_world.d"],
    deps = ["//greeter:native_greeter"],
)

<a name="d_binary"></a>

d_binary

d_binary(name, srcs, deps, includes, linkopts, versions)
<table class="table table-condensed table-bordered table-params"> <colgroup> <col class="col-param" /> <col class="param-description" /> </colgroup> <thead> <tr> <th colspan="2">Attributes</th> </tr> </thead> <tbody> <tr> <td><code>name</code></td> <td> <code>Name, required</code> <p>A unique name for this rule.</p> <p> This name will be used as the name of the binary built by this rule. </p> </td> </tr> <tr> <td><code>srcs</code></td> <td> <code>List of labels, required</code> <p>List of D <code>.d</code> source files used to build the binary.</p> </td> </tr> <tr> <td><code>deps</code></td> <td> <code>List of labels, optional</code> <p>List of libraries to be linked to this binary target.</p> <p> These can either be other <code>d_library</code> targets, source-only <code>d_source_library</code> targets, or <code>cc_library</code> targets if linking a native library. </p> </td> </tr> <tr> <td><code>imports</code></td> <td> <code>List of strings, optional</code> <p>List of import dirs to add to the compile line.</p> <p> These will be passed to the D compiler via <code>-I</code> flags. </p> </td> </tr> <tr> <td><code>linkopts</code></td> <td> <code>List of strings, optional</code> <p>List of flags that are added to the D linker command.</p> <p> These will be passed to the D compiler via <code>-L</code> flags. </p> </td> </tr> <tr> <td><code>versions</code></td> <td> <code>List of strings, optional</code> <p>List of versions to be defined during compilation.</p> <p> Versions are used for conditional compilation and are enabled in the code using <code>version</code> condition blocks. These versions listed here will be passed to the D compiler using <code>-version</code> flags. </p> </td> </tr> </tbody> </table>

Suppose you have the following directory structure for a D project:

[workspace]/
    WORKSPACE
    hello_lib/
        BUILD
        greeter.d
    hello_world
        BUILD
        hello_world.d

The source file hello_lib/greeter.d defines a module greeter:

module greeter;
...

The hello_lib library is built using a d_library target:

hello_lib/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_library")

d_library(
    name = "hello_lib",
    srcs = ["greeter.d"],
)

By default, import paths are from the root of the workspace. Thus, the source for the hello_world binary, hello_world.d, would import the greeter module as follows:

import hello_lib.greeter;

However, this can be changed via the imports attribute on the d_library rule.

The hello_world binary is built using a d_binary target:

hello_world/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_library")

d_binary(
    name = "hello_world",
    srcs = ["hello_world.d"],
    deps = ["//hello_lib"],
)

<a name="d_test"></a>

d_test

d_test(name, srcs, deps, includes, linkopts, versions)
<table class="table table-condensed table-bordered table-params"> <colgroup> <col class="col-param" /> <col class="param-description" /> </colgroup> <thead> <tr> <th colspan="2">Attributes</th> </tr> </thead> <tbody> <tr> <td><code>name</code></td> <td> <code>Name, required</code> <p>A unique name for this rule.</p> <p> This name will be used as the name of the test built by this rule. </p> </td> </tr> <tr> <td><code>srcs</code></td> <td> <code>List of labels, required</code> <p>List of D <code>.d</code> source files used to build the test.</p> </td> </tr> <tr> <td><code>deps</code></td> <td> <code>List of labels, optional</code> <p>List of libraries to be linked to this test target.</p> <p> These can either be other <code>d_library</code> targets, source-only <code>d_source_library</code> targets, or <code>cc_library</code> targets if linking a native library. </p> </td> </tr> <tr> <td><code>imports</code></td> <td> <code>List of strings, optional</code> <p>List of import dirs to add to the compile line.</p> <p> These will be passed to the D compiler via <code>-I</code> flags. </p> </td> </tr> <tr> <td><code>linkopts</code></td> <td> <code>List of strings, optional</code> <p>List of flags that are added to the D linker command.</p> <p> These will be passed to the D compiler via <code>-L</code> flags. </p> </td> </tr> <tr> <td><code>versions</code></td> <td> <code>List of strings, optional</code> <p>List of versions to be defined during compilation.</p> <p> Versions are used for conditional compilation and are enabled in the code using <code>version</code> condition blocks. These versions listed here will be passed to the D compiler using <code>-version</code> flags. </p> </td> </tr> </tbody> </table>

Example

Suppose you have the following directory structure for a D project:

[workspace]/
    WORKSPACE
    hello_lib/
        BUILD
        greeter.d
        greeter_test.d

hello_lib/greeter.d:

module greeter;

import std.stdio;
import std.string;

class Greeter {
 private string greeting;

 public:
  this(in string greeting) {
    this.greeting = greeting.dup;
  }

  string makeGreeting(in immutable string thing) {
    return format("%s %s!", this.greeting, thing);
  }

  void greet(in immutable string thing) {
    writeln(makeGreeting(thing));
  }
}

hello_lib/greeter_test.d:

import hello_lib.greeter;

unittest {
  auto greeter = new Greeter("Hello");
  assert(greeter.makeGreeting("world") == "Hello world!");
}

void main() {}

To build the library and unit test:

hello_lib/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_library", "d_test")

d_library(
    name = "greeter",
    srcs = ["greeter.d"],
)

d_test(
    name = "greeter_test",
    srcs = ["greeter_test.d"],
    deps = [":greeter"],
)

The unit test can then be run using:

bazel test //hello_lib:greeter_test

<a name="d_docs"></a>

d_docs

d_docs(name, dep)
<table class="table table-condensed table-bordered table-params"> <colgroup> <col class="col-param" /> <col class="param-description" /> </colgroup> <thead> <tr> <th colspan="2">Attributes</th> </tr> </thead> <tbody> <tr> <td><code>name</code></td> <td> <code>Name, required</code> <p>A unique name for this rule.</p> </td> </tr> <tr> <td><code>dep</code></td> <td> <code>Label, required</code> <p>The label of the target to generate code documentation for.</p> <p> <code>d_docs</code> can generate HTML code documentation for the source files of <code>d_library</code>, <code>d_source_library</code>, <code>d_binary</code>, or <code>d_test</code> targets. </p> </td> </tr> </tbody> </table>

Example

Suppose you have the following directory structure for a D project:

[workspace]/
    WORKSPACE
    foo/
        BUILD
        foo.d
        bar.d
        baz.d

The foo/ directory contains the sources for the d_library foo. To generate HTML documentation for the foo library, define a d_docs target that takes the d_library foo as its dependency:

foo/BUILD:

load("@io_bazel_rules_d//d:d.bzl", "d_library", "d_docs")

d_library(
    name = "foo",
    srcs = [
        "foo.d",
        "bar.d",
        "baz.d",
    ],
)

d_docs(
    name = "foo_docs",
    dep = ":foo",
)

Running bazel build //foo:foo_docs will generate a zip file containing the HTML documentation generated from the source files. See the official D language documentation on the Documentation Generator for more information on the conventions for source documentation.