# 10.2. Installing modules

Morloc Manual > Modules and Libraries | https://morloc-project.github.io/docs/modules/installing-modules.html | prev: https://morloc-project.github.io/docs/modules/importing-modules.md | next: https://morloc-project.github.io/docs/modules/universal-library.md

The default Morloc modules are hosted on GitHub under the [morloclib](https://github.com/morloclib) organization. Modules can be installed with the `morloc install` command:

```console
$ morloc install internal
$ morloc install root
$ morloc install root-cpp
$ morloc install root-py
$ morloc install root-r
```

The positional arguments to `morloc install` are **install strings**. Each describes one module to install and optionally pins it to a specific commit, branch, or release tag. The same shape is used in the `morloc-deps` entries of a `package.yaml`. More than one install string may be passed in a single invocation, in which case each is installed in turn (any transitive dependencies are also installed automatically).

```text
INSTALL  := [REMOTE ":"] NAME [ "@" [FORM ":"] REF ]
REMOTE   := "github" | "gitlab" | "bitbucket" | "codeberg" | "azure"
NAME     := <repo>           # core module on the default org (morloclib)
          | <owner>/<repo>   # repository under the chosen remote
          | <local-path>     # must start with '.', '/', or '~'
FORM     := "hash" | "branch" | "version" | "tag"   # 'tag' is an alias of 'version'
REF      := <hexhash>        # seven or more hex digits
          | <semver>         # [v]M.m[.p][-prerelease][+build]
          | <branch>         # a valid git branch name
```

Without an explicit `FORM:` prefix the `REF` is auto-detected by trying hash first, then version, then branch. If no `@REF` is given the default branch is used. The default `REMOTE` is `github`, the default core organization is `morloclib`, and clones use HTTPS unless `--ssh` is passed.

A bare name like `root` resolves to `morloclib/root` on github.com. An `owner/repo` form resolves to `github.com/owner/repo`. Adding a remote prefix selects a different host: `gitlab:` is gitlab.com, `codeberg:` is codeberg.org, `bitbucket:` is bitbucket.org. Local paths must begin with `.`, `/`, or `~`; everything from the path start to the first `@` is the path, and any `@REF` that follows is honored only when the local directory is itself a git repository — otherwise the working tree is copied verbatim (filtering `.git` and gitignored files) and the ref is silently dropped.

If the optional `registry` field is set in `~/.morloc/config.yaml`, bare names and bare `owner/name` strings (containing none of `:`, `@`, `.`, `~`) are resolved against the registry before falling back to a git clone from GitHub. Refs are not supported in registry mode — the registry’s latest version is always installed.

**Table 11. Install string examples**

| Install string | Effect |
| --- | --- |
| `root` | stdlib `root` from `morloclib/root` on GitHub (default branch) |
| `root root-py math` | install three modules in one invocation |
| `weena/calendar` | `weena/calendar` on GitHub (default branch) |
| `github:weena/calendar` | same as above, with the remote stated explicitly |
| `gitlab:weena/calendar` | `weena/calendar` on gitlab.com |
| `codeberg:weena/foo` | `weena/foo` on codeberg.org |
| `weena/calendar@1.0` | release tag `1.0` (semver auto-detected) |
| `weena/calendar@v1.0.0` | release tag `v1.0.0` |
| `weena/calendar@version:1.0.0` | explicit release-tag form |
| `weena/calendar@tag:1.0.0` | same as `@version:1.0.0` (`tag` is an alias) |
| `weena/calendar@a1b2c3d` | commit `a1b2c3d` (hash auto-detected at >= 7 hex chars) |
| `weena/calendar@hash:abc1234` | explicit commit-hash form |
| `weena/calendar@dev` | branch `dev` (auto-detected after hash/version fail) |
| `weena/calendar@branch:feature/x` | explicit branch form (allows `/` in the branch name) |
| `gitlab:weena/foo@version:1.0` | remote prefix combined with an explicit release tag |
| `.` | install from the current working directory |
| `./mymod` | install from a relative path |
| `~/code/mymod` | install from a tilde-expanded path |
| `/abs/path/to/mod` | install from an absolute path |
| `./mymod@branch:dev` | install branch `dev` of a local git repo |
| `./mymod@v0.2.0` | install tag `v0.2.0` of a local git repo |

The `morloc install -h` help screen carries a shorter example block for quick reference.

Installed modules are stored in `~/.local/share/morloc/lib/` and can be imported in any Morloc script.

To view the modules that are currently installed, you can run `morloc list`. This will list all installed modules, their version, and their short descriptions. Adding the `-v` option additionally prints the types of all exported terms.

To view just the exports of one desired module, you can include pattern that matches the module of interest:

```bash
$ morloc list -v il
Modules:
  internal
    pack :: a -> b
    unpack :: b -> a
    (.) :: (b -> c) -> (a -> b) -> a -> c
    ($) :: (a -> b) -> a -> b
```

Here `il` matches any module with a name including the ordered characters `i` and `l` — only `internal` in this case.

## 10.2.1. Configuring the C++ build

When a Morloc program contains C sources, the compiler invokes \`g\` (or whatever `$CXX` resolves to) to build the C++ side of the program. Three optional `package.yaml` fields tune that build: two structured fields (`cpp-version` and `dependencies`) that translate into specific flag patterns, and one verbatim field (`cxx-flags`) that passes arbitrary flags through unchanged. For build steps that go beyond flag-tweaking, a fourth field — `setup` — runs a shell script at install time.

**`cpp-version: 20`**

Selects the C standard. Translates directly into a \`-std=cNN\` flag (default `20`).

```yaml
cpp-version: 20
```

**`dependencies: [foo, bar]`**

Names shared libraries the C code links against. For each entry \`name\`, Morloc looks for \`lib<name>.so\` under \`~/.local/share/morloc/lib\` and a \`<name>.h\` / \`.hpp\` / \`.hxx\` under \`~/.local/share/morloc/include\`, then emits the matching \`-l\`, \`-I\`, \`-L\`, and \`-Wl,-rpath\` flags. Use this when your C code does `#include <foo.hpp>` and links against a `libfoo.so` that another Morloc package installed.

```yaml
dependencies:
  - eigen-cppmorloc
  - jsoncpp
```

**`cxx-flags: [-O3, -DENABLE_FAST_PATH]`**

A free-form list of flags appended verbatim to the compile command. Use this for anything the structured fields above don’t cover — optimization levels, architecture targeting, preprocessor defines, warning controls, and so on. Each list element is one shell argument, so no quoting or word-splitting is needed.

```yaml
cxx-flags:
  - -O3
  - -march=native
  - -DENABLE_FAST_PATH
```

The three fields combine in the obvious way:

```yaml
name: vector-ops
version: 0.1.0
cpp-version: 20
dependencies: [eigen-cppmorloc]
cxx-flags:
  - -O3
  - -march=native
  - -DEIGEN_NO_DEBUG
```

When one package depends on another, the downstream package inherits all three fields from its dependencies: a consumer of `vector-ops` above will automatically get `-leigen-cppmorloc` and the listed `cxx-flags` on its own C++ compile line.

For build steps that go beyond what these flags can express — running `cmake`, building a vendored library from source, fetching pre-built artifacts, or installing a Python or R package — use the more general `setup` field, which names a shell script that runs once at install time:

```yaml
name: my-package
setup: scripts/install.sh
```

The script runs after the module’s source has been laid down on disk and after morloc-level dependencies have been installed, with these environment variables set:

**`MORLOC_HOME`**

Morloc’s install root (default `~/.local/share/morloc`).

**`MORLOC_MODULE_NAME`, `MORLOC_MODULE_VERSION`**

name and version from this `package.yaml`.

**`MORLOC_MODULE_DIR`**

absolute path to the installed module’s directory; also the script’s working directory.

**`MORLOC_PLANE`, `MORLOC_PLANE_DIR`**

the active plane name and its directory.

A non-zero exit fails the install. The path must be relative to the module root and must not contain `..` segments. Prefer the three structured fields above when they suffice — a setup script is more powerful but also more code to maintain.
