rules_tcl

Bazel rules for building, testing, and managing Tcl applications and libraries.

Overview

rules_tcl provides a comprehensive set of Bazel rules for working with the Tcl scripting language. It supports:

  • Building executables with tcl_binary
  • Creating reusable libraries with tcl_library
  • Writing and running tests with tcl_test
  • Code quality checks with linting and formatting aspects
  • Dependency management through Tcl's package system

The rules handle Tcl's package system, runfiles, and provide seamless integration with Bazel's build system.

Quick Start

Setup

Add the following to your MODULE.bazel file:

bazel_dep(name = "rules_tcl", version = "{version}")

register_toolchains(
    "@rules_tcl//tcl/toolchain",
)

Basic Example

Create a simple Tcl executable:

load("@rules_tcl//tcl:tcl_binary.bzl", "tcl_binary")

tcl_binary(
    name = "hello",
    srcs = ["hello.tcl"],
)

Library Example

Create a reusable Tcl library:

load("@rules_tcl//tcl:tcl_library.bzl", "tcl_library")

tcl_library(
    name = "greetings",
    srcs = [
        "greet.tcl",
        "pkgIndex.tcl",  # Required for libraries
    ],
)

Tcl Bazel rules

Rules

tcl_binary

load("@rules_tcl//tcl:defs.bzl", "tcl_binary")

tcl_binary(name, deps, srcs, data, env, main)

A tcl_binary is an executable Tcl program consisting of a collection of .tcl source files (possibly belonging to other tcl_library rules), a *.runfiles directory tree containing all the code and data needed by the program at run-time, and a stub script that starts up the program with the correct initial environment and data.

load("@rules_tcl//tcl:defs.bzl", "tcl_binary")

tcl_binary(
    name = "foo",
    srcs = ["foo.tcl"],
    deps = [
        ":bar",  # a tcl_library
    ],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther Tcl packages to link to the current target.List of labelsoptional[]
srcsThe list of source (.tcl) files that are processed to create the target.List of labelsrequired
dataFiles needed by this rule at runtime. May list file or rule targets. Generally allows any target.List of labelsoptional[]
envDictionary of strings; values are subject to $(location) and "Make variable" substitution.Dictionary: String -> Stringoptional{}
mainThe name of the source file that is the main entry point of the application. This file must also be listed in srcs. If left unspecified, name is used instead. If name does not match any filename in srcs, main must be specified.LabeloptionalNone

tcl_library

load("@rules_tcl//tcl:defs.bzl", "tcl_library")

tcl_library(name, deps, srcs, data)

A Tcl library that can be depended upon by other Tcl targets.

A tcl_library represents a Tcl package that can be imported using Tcl's package require command. The library must include a pkgIndex.tcl file in its srcs attribute, which defines the package metadata and how to load the package.

Important: The pkgIndex.tcl file must be included in the srcs attribute. This file is used by Tcl's package system to locate and load the package.

Example:

load("@rules_tcl//tcl:defs.bzl", "tcl_library")

tcl_library(
    name = "mylib",
    srcs = [
        "mylib.tcl",
        "pkgIndex.tcl",
    ],
    deps = [
        ":otherlib",  # Another tcl_library
    ],
    visibility = ["//visibility:public"],
)

The library can then be used as a dependency in other targets:

tcl_binary(
    name = "app",
    srcs = ["app.tcl"],
    deps = [":mylib"],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther Tcl packages to link to the current target.List of labelsoptional[]
srcsThe list of source (.tcl) files that are processed to create the target.List of labelsrequired
dataFiles needed by this rule at runtime. May list file or rule targets. Generally allows any target.List of labelsoptional[]

tcl_toolchain

load("@rules_tcl//tcl:defs.bzl", "tcl_toolchain")

tcl_toolchain(name, tclcore, tcllib, tclsh)

A toolchain rule that defines the Tcl interpreter and libraries for building Tcl targets.

The tcl_toolchain rule configures the Tcl environment used by all tcl_binary, tcl_library, and tcl_test targets. It specifies:

  • The Tcl interpreter (tclsh) to use for execution
  • The Tcl core library files (tclcore)
  • The Tcl standard library (tcllib)

Typically, you don't need to create a tcl_toolchain directly. The rules provide a default toolchain that you register in your MODULE.bazel:

register_toolchains("@rules_tcl//tcl/toolchain")

If you need a custom toolchain (e.g., a different Tcl version), you can define your own:

load("@rules_tcl//tcl:tcl_toolchain.bzl", "tcl_toolchain")

tcl_toolchain(
    name = "my_tcl_toolchain",
    tclsh = "@tcl_8_6//:tclsh",
    tclcore = "@tcl_8_6//:tclcore",
    tcllib = "@tcllib//:tcllib",
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
tclcoreA label to the tclcore files.Labelrequired
tcllibA label to the tcllib files.Labelrequired
tclshThe path to a tclsh binary.Labelrequired

Nagelfar Bazel rules

Rules

Aspects

nagelfar_toolchain

load("@rules_tcl//tcl/nagelfar:defs.bzl", "nagelfar_toolchain")

nagelfar_toolchain(name, nagelfar, syntaxdb)

A toolchain rule for configuring the Nagelfar Tcl syntax checker.

The nagelfar_toolchain rule specifies the Nagelfar script and syntax database files used by tcl_nagelfar_aspect and tcl_nagelfar_test for static analysis of Tcl code.

Typically, you don't need to define this directly. Instead, use the bzlmod extension:

nagelfar = use_extension("@rules_tcl//tcl/nagelfar:extensions.bzl", "nagelfar")
nagelfar.toolchain()
use_repo(nagelfar, "nagelfar_toolchains")
register_toolchains("@nagelfar_toolchains//:all")

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
nagelfarThe nagelfar.tcl script.Labelrequired
syntaxdbNagelfar syntax database files.LabeloptionalNone

tcl_nagelfar_test

load("@rules_tcl//tcl/nagelfar:defs.bzl", "tcl_nagelfar_test")

tcl_nagelfar_test(name, target)

A test rule for performing Nagelfar static analysis on a Tcl target.

Usage:

load("@rules_tcl//tcl/nagelfar:tcl_nagelfar_test.bzl", "tcl_nagelfar_test")

tcl_nagelfar_test(
    name = "mylib_nagelfar",
    target = ":mylib",
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
targetThe Tcl target to perform Nagelfar analysis on.Labelrequired

tcl_nagelfar_aspect

load("@rules_tcl//tcl/nagelfar:defs.bzl", "tcl_nagelfar_aspect")

tcl_nagelfar_aspect()

An aspect for performing Nagelfar static analysis on Tcl targets.

The tcl_nagelfar_aspect applies Nagelfar checks to all Tcl targets in the dependency graph.

Usage:

bazel build //my:target \
    --aspects=@rules_tcl//tcl/nagelfar:tcl_nagelfar_aspect.bzl%tcl_nagelfar_aspect \
    --output_groups=+tcl_nagelfar_checks

Or configure it in your .bazelrc:

build:nagelfar --aspects=@rules_tcl//tcl/nagelfar:tcl_nagelfar_aspect.bzl%tcl_nagelfar_aspect
build:nagelfar --output_groups=+tcl_nagelfar_checks

Ignoring targets:

To skip Nagelfar for specific targets, add one of these tags:

  • no_tcl_nagelfar
  • no_nagelfar
  • no_lint
  • nolint

ASPECT ATTRIBUTES

ATTRIBUTES

Tclint Bazel rules

Rules

Aspects

tcl_tclint_fmt_test

load("@rules_tcl//tcl/tclint:defs.bzl", "tcl_tclint_fmt_test")

tcl_tclint_fmt_test(name, target)

A test rule for performing formatting checks on a Tcl target.

Usage:

load("@rules_tcl//tcl/tclint:tcl_tclint_fmt_test.bzl", "tcl_tclint_fmt_test")

tcl_tclint_fmt_test(
    name = "mylib_format",
    target = ":mylib",
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
targetThe Tcl target to perform formatting checks on.Labelrequired

tcl_tclint_test

load("@rules_tcl//tcl/tclint:defs.bzl", "tcl_tclint_test")

tcl_tclint_test(name, target)

A test rule for performing tclint linting checks on a Tcl target.

Usage:

load("@rules_tcl//tcl/tclint:tcl_tclint_test.bzl", "tcl_tclint_test")

tcl_tclint_test(
    name = "mylib_tclint",
    target = ":mylib",
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
targetThe Tcl target to perform linting on.Labelrequired

tclint_toolchain

load("@rules_tcl//tcl/tclint:defs.bzl", "tclint_toolchain")

tclint_toolchain(name, tclint)

A toolchain rule for configuring tclint.

The tclint_toolchain rule specifies the tclint Python library used by tcl_tclint_aspect, tcl_format_aspect, and related test rules.

Typically, you don't need to define this directly. Instead, use the bzlmod extension:

tclint = use_extension("@rules_tcl//tcl/tclint:extensions.bzl", "tclint")
tclint.toolchain()
use_repo(tclint, "tclint_toolchains")
register_toolchains("@tclint_toolchains//:all")

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
tclintThe tclint python library.Labelrequired

tcl_tclint_aspect

load("@rules_tcl//tcl/tclint:defs.bzl", "tcl_tclint_aspect")

tcl_tclint_aspect()

An aspect for performing tclint linting checks on Tcl targets.

Uses tclint to check for code quality issues.

Usage:

bazel build //my:target \
    --aspects=@rules_tcl//tcl/tclint:tcl_tclint_aspect.bzl%tcl_tclint_aspect \
    --output_groups=+tcl_tclint_checks

Ignoring targets:

To skip tclint for specific targets, add one of these tags:

  • no_tcl_lint
  • no_tclint
  • no_lint
  • nolint

ASPECT ATTRIBUTES

ATTRIBUTES

tcl_tclint_fmt_aspect

load("@rules_tcl//tcl/tclint:defs.bzl", "tcl_tclint_fmt_aspect")

tcl_tclint_fmt_aspect()

An aspect for performing formatting checks on Tcl targets.

Uses tclint to verify formatting.

Usage:

bazel build //my:target \
    --aspects=@rules_tcl//tcl/tclint:tcl_tclint_fmt_aspect.bzl%tcl_tclint_fmt_aspect \
    --output_groups=+tcl_tclint_fmt_checks

Ignoring targets:

To skip format checking for specific targets, add one of these tags:

  • no_tcl_format
  • no_tclformat
  • no_tclfmt
  • noformat
  • nofmt

ASPECT ATTRIBUTES

ATTRIBUTES