Project structure

You may organize your Hare projects to whatever extent you find preferable or necessary to support your use-case. However, we do have conventions on how most Hare projects are structured which you may find useful as a consistent baseline.

Directory structure

Hare users are encouraged to place directories containing Hare modules directly at the root of their project, such that files comprising the “example” module would appear at example/*.ha. Additionally, a few other directories have a prescribed conventional usage:

  • cmd/*/: executable programs (e.g. cmd/example/*.ha)

  • doc/: manual pages or other documentation separate from haredocs

  • scripts/: shell scripts, if applicable

  • internal/: modules relevant to cmd/*/ but not installed [1]

The files COPYING, README.md or README, and Makefile often appear at the root of the project tree, corresponding to their broadly conventional usage. The Makefile is explained in the next section.

If you have no particular opinions or needs with respect to software licensing, Hare projects tend to prefer MPL 2.0 for libraries and GPLv3 for executables.

Footnotes

Makefiles

Hare projects usually include a Makefile to facilitate building and installing the project. These Makefiles should provide the following (.PHONY) targets as applicable:

  • all: build all executables. This should be the default (first) target.

  • check: run tests (hare test)

  • clean: remove build artifacts

  • docs: build documentation (e.g. man pages)

  • install-bin: install executables

  • install-docs: install documentation

  • install-lib: install Hare modules

  • install: install everything

  • uninstall-bin: uninstall executables

  • uninstall-docs: uninstall documentation

  • uninstall-lib: uninstall Hare modules

  • uninstall: uninstall everything

Hare projects should install to the /usr/local PREFIX by default, and respect the PREFIX and DESTDIR variables.

Two example Makefiles are provided here to get you started; feel free to merge or expand these to suit your project’s specific needs.

Example Makefile with executables

This is an example Makefile for a project which only installs executables:

.POSIX:
.SUFFIXES:
HARE=hare
HAREFLAGS=

DESTDIR=
PREFIX=/usr/local
BINDIR=$(PREFIX)/bin

all: example-cmd

example-cmd:
	$(HARE) build $(HAREFLAGS) -o $@ cmd/$@/

check:
	$(HARE) test $(HAREFLAGS)

clean:
	rm -f example-cmd

install:
	install -Dm755 example-cmd $(DESTDIR)$(BINDIR)/example-cmd

uninstall:
	rm -f $(DESTDIR)$(BINDIR)/example-cmd

.PHONY: all check clean install uninstall

Example Makefile with modules

This is an example project which only installs Hare modules, “example1” and “example2”:

.POSIX:
.SUFFIXES:
HARE=hare
HAREFLAGS=

DESTDIR=
PREFIX=/usr/local
SRCDIR=$(PREFIX)/src
HARESRCDIR=$(SRCDIR)/hare
THIRDPARTYDIR=$(HARESRCDIR)/third-party

check:
	$(HARE) test $(HAREFLAGS)

install:
	install -Dm644 example1/* $(DESTDIR)$(THIRDPARTYDIR)/example1/
	install -Dm644 example2/* $(DESTDIR)$(THIRDPARTYDIR)/example2/

uninstall:
	rm -rf $(DESTDIR)$(THIRDPARTYDIR)/example1
	rm -rf $(DESTDIR)$(THIRDPARTYDIR)/example2

.PHONY: check install uninstall