diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 3651e89..1b9a55d 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -57,20 +57,9 @@ jobs: hash -r csc -version - - name: Install eggs - run: | - set -eu - mkdir -p .eggs - repo="$(chicken-install -repository)" - echo "CHICKEN_INSTALL_REPOSITORY=${PWD}/.eggs" >> "$GITHUB_ENV" - echo "CHICKEN_REPOSITORY_PATH=${PWD}/.eggs:${repo}" >> "$GITHUB_ENV" - export CHICKEN_INSTALL_REPOSITORY="${PWD}/.eggs" - export CHICKEN_REPOSITORY_PATH="${PWD}/.eggs:${repo}" - # shellcheck disable=SC2046 - chicken-install $(cat dependencies.txt) - + # Eggs are pinned in eggs.lock and installed by the Makefile into .eggs/. - name: Build sexc - run: make sexc && ./sexc --help + run: make && ./sexc --help - name: Run tests - run: make run-tests + run: make check diff --git a/.gitignore b/.gitignore index e50abab..d588d9c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Project-local Chicken egg repository +/.eggs + +# Compilation artifacts *.o *.import.scm *.link diff --git a/Makefile b/Makefile index 76857fa..ebb1898 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -CHICKEN_C = csc +CHICKEN_C ?= csc +CHICKEN_INSTALL ?= chicken-install +CHICKEN_STATUS ?= chicken-status CSC_FLAGS += -K prefix -static # What and why: # -emit-all-import-libraries: Emit import-libraries for all defined modules. @@ -12,17 +14,44 @@ CSC_FLAGS += -K prefix -static # error. # -c: Stop after compilation to object files. This one is obvious. +# GNU directory variables. Command line overrides, e.g. +# make prefix=$(HOME)/.local install +# make DESTDIR=/tmp/stage prefix=/usr install +prefix = /usr/local +exec_prefix = $(prefix) +bindir = $(exec_prefix)/bin +INSTALL = install +INSTALL_PROGRAM = $(INSTALL) + MODULE_FLAGS = -emit-all-import-libraries -module-registration -c # Order matters, since module check correctness on compilation MODULES = utils types sex-macros reader sex-modules semen sex-fmt-c fmt-c-writer sexc OBJ = $(MODULES:%=%.o) -sexc: $(OBJ) main.scm +DEPSFILE = dependencies.txt +DEPSLOCK = eggs.lock +EGGS_DIR := $(abspath .eggs) + +# Compiler's own repository (types.db, chicken.*), ignoring ambient venv vars. +SYSTEM_CHICKEN_REPO := $(shell env -u CHICKEN_INSTALL_REPOSITORY -u CHICKEN_REPOSITORY_PATH -u CHICKEN_EGG_CACHE -u CHICKEN_INSTALL_PREFIX $(CHICKEN_INSTALL) -repository 2>/dev/null) +CHICKEN_ABI := $(notdir $(SYSTEM_CHICKEN_REPO)) +EGGS_STAMP := $(EGGS_DIR)/.installed-$(CHICKEN_ABI) + +export CHICKEN_EGG_CACHE := $(EGGS_DIR)/cache +export CHICKEN_INSTALL_REPOSITORY := $(EGGS_DIR) +export CHICKEN_INSTALL_PREFIX := $(EGGS_DIR) +export CHICKEN_REPOSITORY_PATH := $(EGGS_DIR):$(SYSTEM_CHICKEN_REPO) + +all: sexc + +sexc: $(EGGS_STAMP) $(OBJ) main.scm $(CHICKEN_C) $(CSC_FLAGS) main.scm -o sexc-tmp -link sexc # otherwise csc hangs, probably because it tries to compile to sexc.o first mv sexc-tmp sexc +$(OBJ): $(EGGS_STAMP) + #------------------------------------------------------------------ utils.o: utils.module.scm utils.scm @@ -53,11 +82,11 @@ sexc.o: sexc.module.scm types.o sexc.scm fmt-c-writer.o sex-macros.o sex-modules $(CHICKEN_C) $(CSC_FLAGS) $(MODULE_FLAGS) sexc.module.scm -o sexc.o -unit sexc -link fmt-c-writer,sex-macros,sex-modules,reader,semen,types,utils # Unit testing -sex-tests: +sex-tests: $(EGGS_STAMP) $(MAKE) -C ./tests sex-tests cp ./tests/sex-tests ./ -sextest: +sextest: $(EGGS_STAMP) $(MAKE) -C ./tools/sextest sextest cp ./tools/sextest/sextest . @@ -71,14 +100,51 @@ check-modules: sexc check-exit-code: sexc @$(MAKE) --no-print-directory -C ./tests/exit-code check SEXC=../../sexc -run-tests: sexc sex-tests sextest +check run-tests: sexc sex-tests sextest ./sex-tests && ./sextest --sexc=./sexc $(SEX_TEST_PROGRAMS:%=./tests/sex-programs/%.sex) && $(MAKE) check-modules && $(MAKE) check-exit-code +install: all installdirs + $(INSTALL_PROGRAM) sexc $(DESTDIR)$(bindir)/sexc + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install + +installdirs: + $(INSTALL) -d $(DESTDIR)$(bindir) + +uninstall: + rm -f $(DESTDIR)$(bindir)/sexc + +# eggs.lock is the pin file (chicken-status -list). Install from it; +# do not float versions on a normal build. Regenerating the lock: +# make deps-update +$(EGGS_STAMP): $(DEPSLOCK) + mkdir -p $(CHICKEN_EGG_CACHE) + $(CHICKEN_INSTALL) -force -from-list $(DEPSLOCK) + touch $@ + +deps: $(EGGS_STAMP) + +deps-update: $(DEPSFILE) + rm -rf $(EGGS_DIR) + mkdir -p $(CHICKEN_EGG_CACHE) + $(CHICKEN_INSTALL) -force $$(cat $(DEPSFILE)) + CHICKEN_REPOSITORY_PATH=$(EGGS_DIR) $(CHICKEN_STATUS) -list | sort > $(DEPSLOCK).tmp + mv $(DEPSLOCK).tmp $(DEPSLOCK) + touch $(EGGS_STAMP) + clean: rm -f $(OBJ) main.o rm -f *.import.scm rm -f *.link rm -f sexc sex-tests sextest + $(MAKE) -C ./tests clean $(MAKE) -C ./tests/modules clean + $(MAKE) -C ./tools/sextest clean -.PHONY: clean run-tests sex-tests sextest check-modules check-exit-code +deps-clean: + rm -rf $(EGGS_DIR) + +.PHONY: all check run-tests check-modules check-exit-code \ + install install-strip installdirs uninstall \ + deps deps-update deps-clean clean sex-tests sextest diff --git a/Readme.org b/Readme.org index 9e0b73a..e335085 100644 --- a/Readme.org +++ b/Readme.org @@ -12,16 +12,46 @@ Sex is statically typed, compiled general purpose language. First, get yourself a Chicken, then, some Chicken deps. You also will need a C compiler. -** Install Chicken Eggs -Tip: there's a way to make Chicken install eggs non-globally. You need -to export ~CHICKEN_INSTALL_REPOSITORY~ and ~CHICKEN_REPOSITORY_PATH~ -environment variables. Refer to the documentation for more info: -https://wiki.call-cc.org/man/5/Extension%20tools#changing-the-repository-location - -~chicken-install `cat dependencies.txt`~ +Eggs are installed into a project-local ~.eggs/~ repository; they do not +touch the Chicken system repository. ** Compilation -~make~ +#+begin_src sh + make +#+end_src + +That installs pinned eggs from ~eggs.lock~ into ~.eggs/~ if needed, then +builds ~sexc~. ~dependencies.txt~ is the unpinned request list. To +refresh ~eggs.lock~ after changing it: + +#+begin_src sh + make deps-update +#+end_src + +** Static compilation +The default ~CSC_FLAGS~ include ~-static~, so ~sexc~ does not need +~.eggs~ at runtime and ~make install~ stays relocatable. Chicken must +provide ~libchicken.a~ (E.g. for gentoo: ~dev-scheme/chicken~ with +~static-libs~ use flag). + +To link dynamically instead (the binary will look for eggs under this +tree's ~.eggs~ path): + +#+begin_src sh + make CSC_FLAGS='-K prefix' +#+end_src + +** Installation +GNU directory variables: ~prefix~, ~exec_prefix~, ~bindir~, ~DESTDIR~. + +#+begin_src sh + # default installation (/usr/local/bin/) + make install + # customize the prefix (installs to ~/.local/bin) + make prefix=$(HOME)/.local install + # staged install for packaging + make DESTDIR=/tmp/stage prefix=/usr install +#+end_src * Usage ** Summary diff --git a/eggs.lock b/eggs.lock new file mode 100644 index 0000000..aeca254 --- /dev/null +++ b/eggs.lock @@ -0,0 +1,8 @@ +(brev-separate "1.100") +(fmt "0.8.14") +(getopt-long "4.0") +(matchable "1.2") +(srfi-1 "0.5.1") +(srfi-13 "0.3.8") +(srfi-69 "0.5.3") +(test "1.3") diff --git a/tests/Makefile b/tests/Makefile index b40a19e..7297715 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -46,3 +46,5 @@ clean: rm -f *.import.scm rm -f *.link rm -f sex-tests + +.PHONY: clean