hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

modules.md (7901B)


      1 # Hare Modules
      2 
      3 *This document is informative. It describes the behavior of the upstream Hare
      4 distribution's build driver, but other Hare implementations may differ, and we
      5 may revise this behavior in the future.*
      6 
      7 TODO:
      8 
      9 - Describe caching mechanism
     10 - hare.ini considerations and linking to static libraries
     11 
     12 The **host** is the machine which is running the build driver and Hare
     13 toolchain. The **target** is the machine which the completed program is expected
     14 to run on. This may not be the same as the host configuration, for example when
     15 **cross-compiling**. The **build driver**, located at `cmd/hare`, orchestrates
     16 this process by collecting the necessary source files to build a Hare program,
     17 resolving its dependencies, and executing the necessary parts of the toolchain
     18 in the appropriate order.
     19 
     20 ## The build driver and the Hare specification
     21 
     22 The Hare language specification is defined at a layer of abstraction that does
     23 not include filesystems, leaving it to the implementation to define how Hare
     24 sources are organized. The upstream Hare distribution maps the concept of a
     25 "module" onto what the spec defines as a *unit*, and each Hare source file in
     26 the filesystem provides what the specification refers to as a *subunit*.
     27 
     28 The upstream Hare distribution provides the "hosted" translation environment.
     29 Hare programs prepared for the "freestanding" environment may also be compiled
     30 with the upstream distribution, but the standard library is not used in this
     31 situation.
     32 
     33 ## Build tags
     34 
     35 The upstream distribution defines the concept of a **build tag**, or "tag",
     36 which is an alphanumeric string and an "inclusive" or "exclusive" bit, which is
     37 used to control the list of source files considered for inclusion in a Hare
     38 module.
     39 
     40 The environment defines a number of default build tags depending on the target
     41 system it was configured for. For example, a Linux system running on an x86\_64
     42 processor defines +linux and +x86\_64 by default, which causes files tagged
     43 +linux or +x86\_64 to be included, and files tagged -linux or -x86\_64 to be
     44 excluded.
     45 
     46 The host configuration defines a set of default build tags, which may be
     47 overridden by specifying an alternate target. The `hare version -v` command
     48 prints out the defaults.
     49 
     50 It is important to note that Hare namespaces and build tags are mutually
     51 exclusive grammars, thanks to the fact that the + and - symbols may not appear
     52 in a Hare identifier.
     53 
     54 ## Locating modules on the filesystem
     55 
     56 Each module, identified by its namespace, is organized into a "**module root**"
     57 directory, where all of its source files may be found, either as members or
     58 descendants. This directory corresponds to a file path which is formed by
     59 replacing the namespace delimiters (`::`) with the path separator for the target
     60 host system (e.g. `/`). This forms a relative path, which is then applied to
     61 each of several possible **source roots**.
     62 
     63 A source root is a directory which forms the top of a hierarchy of Hare modules
     64 and their sources. This directory may also itself be a module, namely the **root
     65 module**: it provides the unit for the empty namespace, where, for example, the
     66 "main" function can be found. Generally speaking, there will be at least two
     67 source roots to choose from: the user's program, and the standard library.
     68 
     69 The current working directory (`.`) is always assigned the highest priority. If
     70 the `HAREPATH` environment variable is set, it specifies a colon-delimited (`:`)
     71 list of additional candidates in descending order of preference. If unset, a
     72 default value is used, which depends on the host configuration, generally
     73 providing at least the path to the standard library's installation location, as
     74 well the installation location of third-party Hare modules. The `hare version
     75 -v` command prints out the defaults configured for this host.
     76 
     77 Each of these source roots is considered in order of precedence by concatenating
     78 the source root path and the relative path of the desired module, and checking
     79 if a **valid** Hare module is present. A module is considered valid if it
     80 contains any regular files, or symlinks to regular files, whose names end in
     81 `.ha` or `.s`; or if it contains any directories, or symlinks to directories;
     82 whose names begin with `+` or `-` and which would also be considered valid under
     83 these criteria, applied recursively.
     84 
     85 The user's program, or any dependency, may *shadow* a module from the standard
     86 library (or another dependency) by providing a suitably named directory in a
     87 source root with a higher level of precedence.
     88 
     89 ## Assembling the list of source files
     90 
     91 A source file is named with the following convention:
     92 
     93 `<name>[<tags...>].<ext>`
     94 
     95 The \< and \> symbols denote a required parameter, and \[ and \] denote optional
     96 parameters. Some example names which follow this convention are:
     97 
     98 - `main.ha`
     99 - `pipe+linux.ha`
    100 - `example-freebsd.ha`
    101 - `longjmp.s`
    102 - `foo+linux-x86_64.ha`
    103 
    104 The build driver examines the list of files in a given module's root directory,
    105 eliminating those with incompatible build tags, and produces a list of
    106 applicable files. Once files with incompatible build tag have been eliminated,
    107 only one file for a given "name" may be provided, such that a module with the
    108 files `hello.ha` and `hello.s` is invalid. Only the "ha" and "s" extensions are
    109 used, respectively denoting Hare sources and assembly sources.
    110 
    111 If any sub-directories of the module's root directory begin with `-` or `+`,
    112 they are treated as a set of build tags and considered for their compatibility
    113 with the build driver's active set of build tags. If compatible, the process is
    114 repeated within that directory, treating its contents as members of the desired
    115 module.
    116 
    117 ## Semantics of specific tools
    118 
    119 A summary of how the mechanisms documented above are applied by each tool is
    120 provided.
    121 
    122 ### hare build, hare run
    123 
    124 The input to this command is the location of the root module for the Hare
    125 program to be built or run. If the path provided identifies a file, that file is
    126 used as the sole input file for the root module. If the path identifies a
    127 directory, the directory is used as the root directory for the root module,
    128 whose source files are assembled according to the algorithm described above.
    129 
    130 ### hare test
    131 
    132 `hare test` walks the current source root (i.e. the current working directory)
    133 by recursively checking if that directory, and every directory which is a
    134 descendant of it, is a valid Hare module. Each of these modules is compiled with
    135 the special +test build tag defined. Dependencies of these modules are also
    136 built, but with the +test tag unspecified, with the exception of the rt module,
    137 which provides a special test runner in this mode. The resulting executable is
    138 executed, which causes all of the `@test` functions in the current source root
    139 to be executed.
    140 
    141 The command line arguments for hare test, if given at all, are interpreted by
    142 rt+test as a list of namespace wildcards (see [fnmatch]) defining which subsets
    143 of the test suite to run.
    144 
    145 [fnmatch]: https://docs.harelang.org/fnmatch
    146 
    147 ### haredoc
    148 
    149 The `haredoc` command accepts a list of identifiers to fetch documentation for,
    150 using the same identifiers which the user might use in a Hare source file to
    151 utilize the corresponding module or declaration.
    152 
    153 The desired identifier is converted to a path. If this path refers to a
    154 directory which is a valid Hare module, documentation for that module is shown.
    155 If that path refers to a directory which is not a valid Hare module, it is
    156 walked to determine if any of its sub-directories are valid Hare modules; if so,
    157 a list of those sub-directories is shown. If the path does not exist, the most
    158 specific component of the identifier is removed, and looked up as a module,
    159 within which the least-significant component is looked up as a declaration
    160 exported from that module. If the module or this declaration still is not found,
    161 the identifier is deemed unresolvable and an error is shown.