hare(1)

NAME

hare - compiles, runs, and tests Hare programs

SYNOPSIS

hare build [-cv]
    [-D ident[:type]=value]
    [-j jobs]
    [-L libdir]
    [-l name]
    [-o path]
    [-t arch]
    [-T tags] [-X tags]
    [path]

hare deps [-Mm] [-T tags] [-X tags] path

hare run [-v]
    [-D ident[:type]=value]
    [-l name]
    [-L libdir]
    [-j jobs]
    [-T tags] [-X tags]
    [path] [args...]

hare test [-v]
    [-D ident[:type]=value]
    [-l name]
    [-L libdir]
    [-j jobs]
    [-T tags] [-X tags]
    tests

hare version [-v]

DESCRIPTION

hare build compiles a Hare program into an executable. The path argument is a path to a Hare source file or a directory which contains a Hare module (see MODULES below). If no path is given, the Hare module contained in the current working directory is built.

hare deps queries the dependencies graph of a Hare program. The path argument is equivalent in usage to hare build.

hare run compiles and runs a Hare program. The path argument is equivalent in usage to hare build. If provided, any additional args are passed to the Hare program which is run. os::args[0] is set to the path argument.

hare test compiles and runs tests for Hare code. All Hare modules in the current working directory are recursively discovered, built, and their tests made eligible for the test run. If the test argument is omitted, all tests are run. Otherwise, the list of named tests are run. hare test adds the +test and +debug tags to the default build tags.

hare version prints version information for the hare program. If -v is supplied, it also prints information about the build parameters. The output format is consistent for machine reading: the first line is always "Hare version $version". Subsequent lines give configuration values in the form of a name, value, and optional context, separated by tabs.

OPTIONS

  hare build

-c
    Compile only, do not link. The output is an object file (for Hare-only modules) or archive (for mixed source modules).

-v
    Enable verbose logging. Prints every command to stderr before executing it.

-D ident[:type]=value
    Passed to harec(1) to define a constant in the type system. ident is parsed as a Hare identifier (e.g. "foo::bar::baz"), type as a Hare type (e.g. "str" or "struct { x: int, y: int }"), and value as a Hare expression (e.g. "42"). Take care to address any necessary escaping to avoid conflicts between your shell syntax and Hare syntax.

-j jobs
    Defines the maximum number of jobs which hare will execute in parallel. The default is the number of processors available on the host.

-l name
    Link with the named system library. The name is passed to pkg-config --libs (see pkg-config(1)) to obtain the appropriate linker flags.

-L libdir
    Add directory to the linker library search path.

-o path
    Set the output file to the given path.

-t arch
    Set the desired architecture for cross-compiling. See ARCHITECTURES for supported architecture names.

-T tags
    Adds additional build tags. See CUSTOMIZING BUILD TAGS.

-X tags
    Unsets build tags. See CUSTOMIZING BUILD TAGS.

  hare deps

-d
    Print dependency graph as a dot file for use with graphviz(1).

-M
    Print rules compatible with POSIX make(1).

-T tags
    Adds additional build tags. See CUSTOMIZING BUILD TAGS.

-X tags
    Unsets build tags. See CUSTOMIZING BUILD TAGS.

  hare run

-v
    Enable verbose logging. Prints every command to stderr before executing it.

-D ident[:type]=value
    Passed to harec(1) to define a constant in the type system. ident is parsed as a Hare identifier (e.g. "foo::bar::baz"), type as a Hare type (e.g. "str" or "struct { x: int, y: int }"), and value as a Hare expression (e.g. "42"). Take care to address any necessary escaping to avoid conflicts between your shell syntax and Hare syntax.

-j jobs
    Defines the maximum number of jobs which hare will execute in parallel. The default is the number of processors available on the host.

-l name
    Link with the named system library. The name is passed to pkg-config --libs (see pkg-config(1)) to obtain the appropriate linker flags.

-L libdir
    Add directory to the linker library search path.

-T tags
    Adds additional build tags. See CUSTOMIZING BUILD TAGS.

-X tags
    Unsets build tags. See CUSTOMIZING BUILD TAGS.

  hare test

-v
    Enable verbose logging. Prints every command to stderr before executing it.

-D ident[:type]=value
    Passed to harec(1) to define a constant in the type system. ident is parsed as a Hare identifier (e.g. "foo::bar::baz"), type as a Hare type (e.g. "str" or "struct { x: int, y: int }"), and value as a Hare expression (e.g. "42"). Take care to address any necessary escaping to avoid conflicts between your shell syntax and Hare syntax.

-j jobs
    Defines the maximum number of jobs which hare will execute in parallel. The default is the number of processors available on the host.

-l name
    Link with the named system library. The name is passed to pkg-config --libs (see pkg-config(1)) to obtain the appropriate linker flags.

-L libdir
    Add directory to the linker library search path.

-T tags
    Adds additional build tags. See CUSTOMIZING BUILD TAGS.

-X tags
    Unsets build tags. See CUSTOMIZING BUILD TAGS.

  hare version

-v
    Show build parameters.

MODULES

The path argument to hare build and hare run are used to identify the inputs for the build. If this path is a file, it is treated as a single Hare source file. If it is a directory, the directory is treated as a module, and is placed in the global namespace for the build.

All files which end in .ha and .s are treated as inputs to the module, and are respectively treated as Hare sources and assembly sources. A module with a mix of assembly and Hare sources are considered mixed modules, and have some special semantics.

The list of files considered eligible may be filtered by build tags. The format for the filename is name[+tags].ext, where the name is user-defined, the ext is either 'ha' or 's', and a list of tags are provided after the name. A plus symbol ('+') will cause a file to be included only if that tag is present, and a minus symbol ('-') will cause a file to be excluded if that tag is present. Only one file for a given name will be selected for the build, and among files with eligible tags, the one with the most tag specifiers is selected.

For example, if the following files are present in a directory:

    • foo.ha
    • bar.ha
    • bar+linux.ha
    • bar+plan9.ha
    • baz+x86_64.s
    • bat-x86_64.ha

If the build tags are +linux+x86_64, then the files which are included in the module are foo.ha, bar+linux.ha, and baz+x86_64.s.

Additionally, subdirectories in a module will be considered part of that module if their name consists only of a tag set, e.g. "+linux" or "-x86_64". A directory with a name and tag set is never considered as part of any module, such as "example+linux". A directory with only a name (e.g. "example") is considered a sub-module of its parent directory and must be imported separately, so "foo::bar" refers to foo/bar/.

DEPENDENCY RESOLUTION

The "use" statements in each source file which is used as an input to hare build or hare run are scanned and used to determine the dependencies for the program, and this process is repeated for each dependency to obtain a complete dependency graph.

Dependencies are searched for by examining first the current working directory, then each component of the HAREPATH environment variable in order, which is a list of paths separated by colons. The default value of the HAREPATH may be found with the hare version -v command. Typically, it is set to include the path to the standard library installed on the system, as well as a system-provided storage location for third-party modules installed via the system package manager.

ARCHITECTURES

The -t flag for hare build is used for cross-compilation, and selects a architecture different from the host to target. The list of supported architectures is:

    • aarch64
    • riscv64
    • x86_64

The system usually provides reasonable defaults for the AR, AS, and LD tools based on the desired target. However, you may wish to set these variables yourself to control the cross toolchain in use.

CUSTOMIZING BUILD TAGS

Build tags allow you to add constraints on what features or platforms are enabled for your build. A tag is a name, consisting of alphanumeric characters and underscores, and a + or - prefix to signal inclusivity or exclusivity. See MODULES for details on how build tags affect module input selection.

To add new tag constraints, inclusive or exclusive, use the -T flag. "-T +foo-bar" will include the 'foo' tag and exclude the 'bar' tag. To remove constraints, use the -X in a similar fashion; "-X +foo-bar" will reverse the previous -T example.

Some tags are enabled by default, enabling features for the host platform. You can view the default tagset by running hare version -v. To remove all default tags, use "-X^".

ENVIRONMENT

The following environment variables affect hare's execution:

HARECACHE | The path to the object cache. Defaults to $XDG_CACHE_HOME/hare, or ~/.cache/hare if that doesn't exist.
HAREPATH | See DEPENDENCY RESOLUTION.
HAREFLAGS | Applies additional flags to the command line arguments.
HAREC | Name of the harec(1) command to use.
AR | Name of the ar(1) command to use.
ARFLAGS | Additional flags to pass to ar(1).
AS | Name of the as(1) command to use.
ASFLAGS | Additional flags to pass to as(1).
LD | Name of the ld(1) command to use.
LDLINKFLAGS | Additional flags to pass to ld(1).

SEE ALSO

harec(1), haredoc(1), as(1), ld(1), ar(1), make(1)