diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-05-11 15:01:09 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-05-11 15:01:09 -0400 |
| commit | 761a483e28935f0bdee4658c37dfaa4606c2660a (patch) | |
| tree | 2e0b76801f2838d568ebd7b9c76884599ada0744 | |
| parent | 84c29ce5facc166515b80abf79f33b2ea21bf9fa (diff) | |
Add new system for tracking versions.
48 files changed, 314 insertions, 75 deletions
diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000..b89c0751 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,20 @@ +# Version History + +## v0.3 + +- Added a versioning system based on CHANGES.md files. + +## v0.2 + +- Improved compatibility on different platforms. +- Switched to use a per-file unique ID suffix instead of renaming symbols after + compilation with `objcopy`. +- Installation process now sets user permissions as needed, which fixes an + issue where a user not in the sudoers file couldn't install even to a local + directory. +- Fixed some bugs with Table and Text hashing. +- Various other bugfixes and internal optimizations. + +## v0.1 + +First version to get a version number. @@ -67,10 +67,11 @@ OSFLAGS != case $(OS) in *BSD|Darwin) echo '-D_BSD_SOURCE';; Linux) echo '-D_GNU EXTRA= G=-ggdb O=-O3 -GIT_VERSION=$(shell git log -1 --pretty=format:"$$(git describe --tags --abbrev=0)_%as_%h") +TOMO_VERSION=$(shell awk '/^## / {print $$2; exit}' CHANGES.md) +GIT_VERSION=$(shell git log -1 --pretty=format:"%as_%h") CFLAGS=$(CCONFIG) $(INCLUDE_DIRS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LTO) \ -DTOMO_PREFIX='"$(PREFIX)"' -DSUDO='"$(SUDO)"' -DDEFAULT_C_COMPILER='"$(DEFAULT_C_COMPILER)"' \ - -DTOMO_VERSION='"$(GIT_VERSION)"' + -DTOMO_VERSION='"$(TOMO_VERSION)"' -DGIT_VERSION='"$(GIT_VERSION)"' CFLAGS_PLACEHOLDER="$$(printf '\033[2m<flags...>\033[m\n')" LDLIBS=-lgc -lcord -lm -lunistring -lgmp -ldl LIBTOMO_FLAGS=-shared @@ -87,16 +88,17 @@ ifeq ($(OS),OpenBSD) LDLIBS += -lexecinfo endif -AR_FILE=libtomo.a +AR_FILE=libtomo_$(TOMO_VERSION).a ifeq ($(OS),Darwin) INCLUDE_DIRS += -I/opt/homebrew/include LDFLAGS += -L/opt/homebrew/lib - LIB_FILE=libtomo.dylib - LIBTOMO_FLAGS += -Wl,-install_name,@rpath/libtomo.dylib + LIB_FILE=libtomo_$(TOMO_VERSION).dylib + LIBTOMO_FLAGS += -Wl,-install_name,@rpath/libtomo_$(TOMO_VERSION).dylib else - LIB_FILE=libtomo.so - LIBTOMO_FLAGS += -Wl,-soname,libtomo.so + LIB_FILE=libtomo_$(TOMO_VERSION).so + LIBTOMO_FLAGS += -Wl,-soname,libtomo_$(TOMO_VERSION).so endif +EXE_FILE=tomo_$(TOMO_VERSION) COMPILER_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c)) STDLIB_OBJS=$(patsubst %.c,%.o,$(wildcard src/stdlib/*.c)) @@ -104,7 +106,7 @@ TESTS=$(patsubst test/%.tm,test/results/%.tm.testresult,$(wildcard test/*.tm)) API_YAML=$(wildcard api/*.yaml) API_MD=$(patsubst %.yaml,%.md,$(API_YAML)) -all: config.mk check-c-compiler check-libs build/lib/$(LIB_FILE) build/lib/$(AR_FILE) build/bin/tomo +all: config.mk check-c-compiler check-libs build/lib/$(LIB_FILE) build/lib/$(AR_FILE) build/bin/$(EXE_FILE) check-c-compiler: @$(DEFAULT_C_COMPILER) -v 2>/dev/null >/dev/null \ @@ -114,7 +116,7 @@ check-libs: check-c-compiler @echo 'int main() { return 0; }' | $(DEFAULT_C_COMPILER) $(LDFLAGS) $(LDLIBS) -x c - -o /dev/null 2>/dev/null >/dev/null \ || { printf '\033[31;1m%s\033[m\n' "I expected to find the following libraries on your system, but I can't find them: $(LDLIBS)"; exit 1; } -build/bin/tomo: $(STDLIB_OBJS) $(COMPILER_OBJS) +build/bin/$(EXE_FILE): $(STDLIB_OBJS) $(COMPILER_OBJS) @mkdir -p build/bin @echo $(CC) $(CFLAGS_PLACEHOLDER) $(LDFLAGS) $^ $(LDLIBS) -o $@ @$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ @@ -134,14 +136,14 @@ tags: config.mk: configure.sh bash ./configure.sh -%.o: %.c src/ast.h src/environment.h src/types.h config.mk +%.o: %.c src/ast.h src/environment.h src/types.h config.mk CHANGES.md @echo $(CC) $(CFLAGS_PLACEHOLDER) -c $< -o $@ @$(CC) $(CFLAGS) -c $< -o $@ %: %.tm ./local-tomo -e $< -test/results/%.tm.testresult: test/%.tm build/bin/tomo +test/results/%.tm.testresult: test/%.tm build/bin/$(EXE_FILE) @mkdir -p test/results @printf '\033[33;1;4m%s\033[m\n' $< @if ! COLOR=1 LC_ALL=C ./local-tomo -O 1 $< 2>&1 | tee $@; then \ @@ -176,10 +178,10 @@ man/man1/tomo.1: docs/tomo.1.md pandoc --lua-filter=docs/.pandoc/bold-code.lua -s $< -t man -o $@ examples: - ./build/bin/tomo -qIL examples/log examples/ini examples/vectors examples/http examples/wrap examples/colorful - ./build/bin/tomo -e examples/game/game.tm examples/http-server/http-server.tm \ + ./local-tomo -qIL examples/log examples/ini examples/vectors examples/http examples/wrap examples/colorful + ./local-tomo -e examples/game/game.tm examples/http-server/http-server.tm \ examples/tomodeps/tomodeps.tm examples/tomo-install/tomo-install.tm - ./build/bin/tomo examples/learnxiny.tm + ./local-tomo examples/learnxiny.tm deps: bash ./install_dependencies.sh @@ -188,7 +190,7 @@ check-utilities: check-c-compiler @which debugedit 2>/dev/null >/dev/null \ || printf '\033[33;1m%s\033[m\n' "I couldn't find 'debugedit' on your system! Try installing the package 'debugedit' with your package manager. (It's not required though)" -install-files: build/bin/tomo build/lib/$(LIB_FILE) build/lib/$(AR_FILE) check-utilities +install-files: build/bin/$(EXE_FILE) build/lib/$(LIB_FILE) build/lib/$(AR_FILE) check-utilities @if ! echo "$$PATH" | tr ':' '\n' | grep -qx "$(PREFIX)/bin"; then \ echo $$PATH; \ printf "\033[31;1mError: '$(PREFIX)/bin' is not in your \$$PATH variable!\033[m\n" >&2; \ @@ -198,15 +200,16 @@ install-files: build/bin/tomo build/lib/$(LIB_FILE) build/lib/$(AR_FILE) check-u exit 1; \ fi $(DEFINE_AS_OWNER); \ - as_owner mkdir -p -m 755 "$(PREFIX)/man/man1" "$(PREFIX)/man/man3" "$(PREFIX)/bin" "$(PREFIX)/include/tomo" "$(PREFIX)/lib"; \ - as_owner cp src/stdlib/*.h "$(PREFIX)/include/tomo/"; \ + as_owner mkdir -p -m 755 "$(PREFIX)/man/man1" "$(PREFIX)/man/man3" "$(PREFIX)/bin" "$(PREFIX)/include/tomo_$(TOMO_VERSION)" "$(PREFIX)/lib"; \ + as_owner cp src/stdlib/*.h "$(PREFIX)/include/tomo_$(TOMO_VERSION)/"; \ as_owner cp build/lib/$(LIB_FILE) build/lib/$(AR_FILE) "$(PREFIX)/lib/"; \ - as_owner rm -f "$(PREFIX)/bin/tomo"; \ - as_owner cp build/bin/tomo "$(PREFIX)/bin/"; \ + as_owner rm -f "$(PREFIX)/bin/$(EXE_FILE)"; \ + as_owner cp build/bin/$(EXE_FILE) "$(PREFIX)/bin/"; \ as_owner cp man/man1/* "$(PREFIX)/man/man1/"; \ - as_owner cp man/man3/* "$(PREFIX)/man/man3/"; + as_owner cp man/man3/* "$(PREFIX)/man/man3/"; \ + as_owner sh link_versions.sh -install-libs: build/bin/tomo check-utilities +install-libs: build/bin/$(EXE_FILE) check-utilities $(DEFINE_AS_OWNER); \ ./local-tomo -qIL lib/patterns lib/time lib/commands lib/shell lib/random lib/base64 lib/pthreads lib/uuid lib/core @@ -214,7 +217,8 @@ install: install-files install-libs uninstall: $(DEFINE_AS_OWNER); \ - as_owner rm -rvf "$(PREFIX)/bin/tomo" "$(PREFIX)/include/tomo" "$(PREFIX)/lib/$(LIB_FILE)" "$(PREFIX)/lib/$(AR_FILE)" "$(PREFIX)/share/tomo"; + as_owner rm -rvf "$(PREFIX)/bin/tomo" "$(PREFIX)/bin/tomo"[0-9]* "$(PREFIX)/bin/tomo_v"* "$(PREFIX)/include/tomo_v"* "$(PREFIX)/lib/libtomo_v*" "$(PREFIX)/share/tomo_$(TOMO_VERSION)"; \ + as_owner sh link_versions.sh endif diff --git a/docs/README.md b/docs/README.md index 017e344b..60aaf08f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,6 +14,7 @@ A few topics that are documented: - [Operator Overloading](operators.md) - [Special Methods](metamethods.md) - [C Interoperability](c-interoperability.md) +- [Versioning](versions.md) ## Types diff --git a/docs/libraries.md b/docs/libraries.md index 7febb2e1..8043bfaa 100644 --- a/docs/libraries.md +++ b/docs/libraries.md @@ -151,8 +151,8 @@ that can be used by other Tomo projects. You can build a library by running If you additionally add the `-I` flag, Tomo will copy the entire directory (excluding files and directories that begin with `.` such as `.git`) into -`~/.local/share/tomo/installed/` and create a symbolic link for the library's -`.so` file (or `.dylib` file on Mac) in `~/.local/share/tomo/lib/`. +`~/.local/share/tomo_vX.Y/installed/` (where `X` and `Y` are the major/minor +version of the compiler). ### Using Shared Libraries diff --git a/docs/tomo.1.md b/docs/tomo.1.md index c77e91cf..7ccf0397 100644 --- a/docs/tomo.1.md +++ b/docs/tomo.1.md @@ -63,4 +63,4 @@ C code, which is then compiled using a C compiler of your choice. : Print the compiler version and exit. `-r`, `--run` -: Run an installed tomo program from `~/.local/share/tomo/installed`. +: Run an installed tomo program from `~/.local/share/tomo_vX.Y/installed`. diff --git a/docs/versions.md b/docs/versions.md new file mode 100644 index 00000000..b44902b2 --- /dev/null +++ b/docs/versions.md @@ -0,0 +1,71 @@ +# Versioning + +The Tomo language and Tomo libraries both use a versioning system based on a a +changelog called `CHANGES.md` that includes a human-and-machine-readable +markdown list of versions. + +The version number is parsed from the first level 2 header (i.e. line beginning +with `## `). An example CHANGES.md file might look like this: + +``` +# Version History + +## v1.2 + +Version 1.2 adds some new features: + +- Autofrobnication +- Reverse froodling + +## v1.1 + +- Added a `--moop` compiler flag + +## v1.0 + +Major version change including: + +- Deprecated snobwozzling +- Added new syntax for sleazles + +## v0.3 + +Bugfixes and new features... +``` + +When you build the compiler or a library, if this file exists, it will be used +to determine the current version (the top-most level 2 header). + +## Tomo Language Versions + +The version for the Tomo language itself will come into play in a few ways: + +1. The compiler will be installed to `tomo_vX.Y` (where `X` is the major + version number and `Y` is the minor version number). +2. A symbolic link will be installed from `tomo` to the largest version of Tomo + that is installed on your machine (e.g. `~/.local/bin/tomo -> + ~/.local/bin/tomo_v2.12`). +3. Each version of Tomo will build and install its own shared library file + (e.g. `~/.local/lib/libtomo_v1.2.so`) and headers (e.g. + `~/.local/include/tomo_v1.2/tomo.h`). +4. Tomo libraries will be installed to a separate subdirectory for each version + of the compiler (e.g. `~/.local/share/tomo_v1.2/installed`). + + +# Rationale + +I have opted to use a CHANGES.md file instead of git tags or a project +configuration file for a few reasons. The first is that I think there is real +value provided by maintaining a human-readable changelog. This approach +encourages developers to maintain one. The second is to facilitate a development +cycle where developers iterate on new features under the umbrella of a new +version number, rather than the git tag-based approach where new features are +developed in the no man's land between version tags. I also opted to use a +human-readable markdown changelog rather than a build configuration file in +order to ensure that there is no mismatch between the documentation and the +configuration. My recommendation would be to develop code on a `main` or `dev` +branch, bumping the version number pre-emptively (with an empty changelist). As +new changes come in, add them to the changelog. Then, when it's appropriate, +create a git tag to mark the current commit as the canonical one for that +semantic version. Then, make a new commit after the tagged one bumping the +version number and signaling the beginning of a new cycle of development. diff --git a/examples/colorful/CHANGES.md b/examples/colorful/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/colorful/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/colorful/README.md b/examples/colorful/README.md index c03ace24..04a221e3 100644 --- a/examples/colorful/README.md +++ b/examples/colorful/README.md @@ -55,7 +55,7 @@ colorful [--help] [texts...] [--by-line] [--files ...] `colorful` can also be used as a Tomo library: ```tomo -use colorful +use colorful_v1.0 $Colorful" @(blue:Welcome to the @(bold:party)!) diff --git a/examples/colorful/colorful.tm b/examples/colorful/colorful.tm index 9a8bbbba..270efe8c 100644 --- a/examples/colorful/colorful.tm +++ b/examples/colorful/colorful.tm @@ -7,7 +7,7 @@ HELP := " CSI := "\033[" -use patterns +use patterns_v1.0 lang Colorful convert(text:Text -> Colorful) diff --git a/examples/coroutines/CHANGES.md b/examples/coroutines/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/coroutines/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/coroutines/README.md b/examples/coroutines/README.md index eef923e0..86b5dd00 100644 --- a/examples/coroutines/README.md +++ b/examples/coroutines/README.md @@ -6,7 +6,7 @@ This is a coroutine library built on top of a modified version of ## Example Usage ```tomo -use coroutines +use coroutines_v1.0 func main() co := Coroutine(func() diff --git a/examples/game/CHANGES.md b/examples/game/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/game/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/http-server/CHANGES.md b/examples/http-server/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/http-server/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/http-server/connection-queue.tm b/examples/http-server/connection-queue.tm index c56069e1..5cf8bb91 100644 --- a/examples/http-server/connection-queue.tm +++ b/examples/http-server/connection-queue.tm @@ -1,4 +1,4 @@ -use pthreads +use pthreads_v1.0 func _assert_success(name:Text, val:Int32; inline) fail("$name() failed!") if val < 0 diff --git a/examples/http-server/http-server.tm b/examples/http-server/http-server.tm index 80774bff..717aa733 100644 --- a/examples/http-server/http-server.tm +++ b/examples/http-server/http-server.tm @@ -9,9 +9,9 @@ use <unistd.h> use <arpa/inet.h> use <err.h> -use commands -use pthreads -use patterns +use commands_v1.0 +use pthreads_v1.0 +use patterns_v1.0 use ./connection-queue.tm diff --git a/examples/http-server/sample-site/random.tm b/examples/http-server/sample-site/random.tm index 153ac2af..75e185b3 100755 --- a/examples/http-server/sample-site/random.tm +++ b/examples/http-server/sample-site/random.tm @@ -1,5 +1,5 @@ #!/bin/env tomo -use random +use random_v1.0 func main() say(" diff --git a/examples/http/CHANGES.md b/examples/http/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/http/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/ini/CHANGES.md b/examples/ini/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/ini/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/ini/ini.tm b/examples/ini/ini.tm index 4dc27725..9bcfb3a4 100644 --- a/examples/ini/ini.tm +++ b/examples/ini/ini.tm @@ -1,5 +1,5 @@ -use patterns +use patterns_v1.0 _USAGE := " Usage: ini <filename> "[section[/key]]" diff --git a/examples/log/CHANGES.md b/examples/log/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/log/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/tomo-install/CHANGES.md b/examples/tomo-install/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/tomo-install/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/tomo-install/tomo-install.tm b/examples/tomo-install/tomo-install.tm index d915b993..e9838859 100644 --- a/examples/tomo-install/tomo-install.tm +++ b/examples/tomo-install/tomo-install.tm @@ -1,5 +1,5 @@ -use shell -use patterns +use shell_v1.0 +use patterns_v1.0 _USAGE := " tomo-install file.tm... diff --git a/examples/tomodeps/CHANGES.md b/examples/tomodeps/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/tomodeps/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm index 5513290c..af7f2573 100644 --- a/examples/tomodeps/tomodeps.tm +++ b/examples/tomodeps/tomodeps.tm @@ -1,6 +1,6 @@ # Show a Tomo dependency graph -use patterns +use patterns_v1.0 _USAGE := "Usage: tomodeps <files...>" diff --git a/examples/vectors/CHANGES.md b/examples/vectors/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/vectors/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/examples/wrap/CHANGES.md b/examples/wrap/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/examples/wrap/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/base64/CHANGES.md b/lib/base64/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/base64/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/commands/CHANGES.md b/lib/commands/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/commands/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/core/CHANGES.md b/lib/core/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/core/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/core/core.tm b/lib/core/core.tm index 6aa4c267..0b8aba53 100644 --- a/lib/core/core.tm +++ b/lib/core/core.tm @@ -1,9 +1,9 @@ # This file just uses all the most commonly used standard # library modules so you don't have to import them one-by-one -use patterns -use commands -use shell -use pthreads -use random -use time +use patterns_v1.0 +use commands_v1.0 +use shell_v1.0 +use pthreads_v1.0 +use random_v1.0 +use time_v1.0 diff --git a/lib/patterns/CHANGES.md b/lib/patterns/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/patterns/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/patterns/_test.tm b/lib/patterns/_test.tm index 1a06570f..26c23628 100644 --- a/lib/patterns/_test.tm +++ b/lib/patterns/_test.tm @@ -1,4 +1,4 @@ -use patterns +use patterns_v1.0 func main() amelie := "Am\{UE9}lie" diff --git a/lib/patterns/patterns.c b/lib/patterns/patterns.c index 04cc9c0e..74d542b8 100644 --- a/lib/patterns/patterns.c +++ b/lib/patterns/patterns.c @@ -4,7 +4,6 @@ #include <string.h> #include <strings.h> #include <sys/param.h> -#include <tomo/tomo.h> #include <unictype.h> #include <uniname.h> #include <unistring/version.h> diff --git a/lib/pthreads/CHANGES.md b/lib/pthreads/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/pthreads/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/random/CHANGES.md b/lib/random/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/random/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/shell/CHANGES.md b/lib/shell/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/shell/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/shell/README.md b/lib/shell/README.md index 4adb8cff..d4bcd42e 100644 --- a/lib/shell/README.md +++ b/lib/shell/README.md @@ -3,7 +3,7 @@ This module defines a `lang` for running shell scripts: ```tomo -use shell +use shell_v1.0 >> $Shell" seq 5 diff --git a/lib/shell/shell.tm b/lib/shell/shell.tm index da03f843..f9476161 100644 --- a/lib/shell/shell.tm +++ b/lib/shell/shell.tm @@ -1,4 +1,4 @@ -use commands +use commands_v1.0 lang Shell convert(text:Text -> Shell) diff --git a/lib/time/CHANGES.md b/lib/time/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/time/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/uuid/CHANGES.md b/lib/uuid/CHANGES.md new file mode 100644 index 00000000..42ae752c --- /dev/null +++ b/lib/uuid/CHANGES.md @@ -0,0 +1,5 @@ +# Version History + +## v1.0 + +Initial version diff --git a/lib/uuid/uuid.tm b/lib/uuid/uuid.tm index 06d48390..f2be618e 100644 --- a/lib/uuid/uuid.tm +++ b/lib/uuid/uuid.tm @@ -1,5 +1,5 @@ -use random -use time +use random_v1.0 +use time_v1.0 lang UUID func v4(-> UUID) # Random UUID diff --git a/link_versions.sh b/link_versions.sh new file mode 100644 index 00000000..3fadbe4f --- /dev/null +++ b/link_versions.sh @@ -0,0 +1,17 @@ +#!/bin/sh +TOMO_PREFIX="$(awk -F= '/PREFIX/{print $2}' config.mk)" +cd "$TOMO_PREFIX/bin" + +commands="$(ls | awk -F '[v.]' ' + /^tomo_v/{ + if ($2 >= max_major) max_major=$2; + if ($3 >= max_minor[$2]) max_minor[$2] = $3; + link_tomo=1 + } + END { + for (major in max_minor) { + if (max_major > 0) print "ln -fvs tomo_v"major"."max_minor[major]" tomo"major + } + if (link_tomo) print "ln -fvs tomo_v"max_major"."max_minor[max_major]" tomo" + }')" +eval "$commands" @@ -1,6 +1,7 @@ #!/bin/sh +version=$(awk '/^## / {print $2; exit}' CHANGES.md) here="$(realpath "$(dirname "$0")")" -if [ ! -e "$here/build/bin/tomo" ]; then +if [ ! -e "$here/build/bin/tomo_$version" ]; then echo "Tomo hasn't been compiled yet! Run \`make\` to compile it!" exit 1; fi @@ -10,4 +11,4 @@ LD_LIBRARY_PATH="$here/build/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \ LIBRARY_PATH="$here/build/lib${LIBRARY_PATH:+:$LIBRARY_PATH}" \ C_INCLUDE_PATH="$here/build/include${C_INCLUDE_PATH:+:$C_INCLUDE_PATH}" \ CPATH="$here/build/include${CPATH:+:$CPATH}" \ -tomo "$@" +tomo_"$version" "$@" diff --git a/src/compile.c b/src/compile.c index f3644488..98c0bdb0 100644 --- a/src/compile.c +++ b/src/compile.c @@ -1977,7 +1977,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return with_source_info(env, ast, CORD_all("$initialize", suffix, "();\n")); } else if (use->what == USE_MODULE) { glob_t tm_files; - if (glob(String(TOMO_PREFIX"/share/tomo/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) + if (glob(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) code_err(ast, "Could not find library"); CORD initialization = CORD_EMPTY; @@ -4457,7 +4457,7 @@ CORD compile_file(env_t *env, ast_t *ast) return CORD_all( env->do_source_mapping ? CORD_all("#line 1 ", CORD_quoted(ast->file->filename), "\n") : CORD_EMPTY, "#define __SOURCE_FILE__ ", CORD_quoted(ast->file->filename), "\n", - "#include <tomo/tomo.h>\n" + "#include <tomo_"TOMO_VERSION"/tomo.h>\n" "#include \"", name, ".tm.h\"\n\n", includes, env->code->local_typedefs, "\n", @@ -4484,7 +4484,7 @@ CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) switch (use->what) { case USE_MODULE: { glob_t tm_files; - if (glob(String(TOMO_PREFIX"/share/tomo/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) + if (glob(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) code_err(ast, "Could not find library"); CORD includes = CORD_EMPTY; @@ -4708,7 +4708,7 @@ CORD compile_file_header(env_t *env, Path_t header_path, ast_t *ast) CORD header = CORD_all( "#pragma once\n", env->do_source_mapping ? CORD_all("#line 1 ", CORD_quoted(ast->file->filename), "\n") : CORD_EMPTY, - "#include <tomo/tomo.h>\n"); + "#include <tomo_"TOMO_VERSION"/tomo.h>\n"); compile_typedef_info_t info = {.env=env, .header=&header, .header_path=header_path}; visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn=(void*)_make_typedefs, &info}); diff --git a/src/stdlib/print.h b/src/stdlib/print.h index 9bd89aea..5ef5b6ed 100644 --- a/src/stdlib/print.h +++ b/src/stdlib/print.h @@ -150,6 +150,6 @@ FILE *gc_memory_stream(char **buf, size_t *size); _fprint(_stream, __VA_ARGS__); \ fflush(_stream); \ _buf; }) -#define print_err(...) ({ fprint(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }) +#define print_err(...) ({ fprint(stderr, "\033[31;1m", __VA_ARGS__, "\033[m"); exit(EXIT_FAILURE); }) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index f4093849..3904ae70 100644 --- a/src/stdlib/stacktrace.c +++ b/src/stdlib/stacktrace.c @@ -102,7 +102,7 @@ public void print_stacktrace(FILE *out, int offset) cwd[cwd_len++] = '/'; cwd[cwd_len] = '\0'; - const char *install_dir = TOMO_PREFIX"/share/tomo/installed/"; + const char *install_dir = TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/"; static void *stack[1024]; int64_t size = (int64_t)backtrace(stack, sizeof(stack)/sizeof(stack[0])); @@ -82,8 +82,8 @@ static OptionalText_t " -D_BSD_SOURCE" #endif " -DGC_THREADS" - " -I'" TOMO_PREFIX "/include' -I'" TOMO_PREFIX "/share/tomo/installed' -I/usr/local/include"), - ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo"), + " -I'" TOMO_PREFIX "/include' -I'" TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed' -I/usr/local/include"), + ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo_"TOMO_VERSION), ldflags = Text("-Wl,-rpath,'"TOMO_PREFIX"/lib',-rpath,/usr/local/lib" " -L/usr/local/lib"), optimization = Text("2"), @@ -160,10 +160,10 @@ int main(int argc, char *argv[]) // Run a tool: if ((streq(argv[1], "-r") || streq(argv[1], "--run")) && argc >= 3) { if (strcspn(argv[2], "/;$") == strlen(argv[2])) { - const char *program = String("'"TOMO_PREFIX"'/share/tomo/installed/", argv[2], "/", argv[2]); + const char *program = String("'"TOMO_PREFIX"'/share/tomo_"TOMO_VERSION"/installed/", argv[2], "/", argv[2]); execv(program, &argv[2]); } - print_err("This is not an installed tomo program: \033[31;1m", argv[2], "\033[m"); + print_err("This is not an installed tomo program: ", argv[2]); } Text_t usage = Text("\x1b[33;4;1mUsage:\x1b[m\n" @@ -179,7 +179,7 @@ int main(int argc, char *argv[]) " --parse|-p: show parse tree\n" " --install|-I: install the executable or library\n" " --optimization|-O <level>: set optimization level\n" - " --run|-r: run a program from " TOMO_PREFIX "/share/tomo/installed\n" + " --run|-r: run a program from " TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed\n" ); Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args( @@ -216,7 +216,10 @@ int main(int argc, char *argv[]) ); if (show_version) { - print("Tomo version: ", TOMO_VERSION); + if (verbose) + print("Tomo version: ", TOMO_VERSION, " (", GIT_VERSION, ")"); + else + print("Tomo version: ", TOMO_VERSION); return 0; } @@ -249,7 +252,7 @@ int main(int argc, char *argv[]) for (int64_t i = 0; i < uninstall.length; i++) { Text_t *u = (Text_t*)(uninstall.data + i*uninstall.stride); - xsystem(as_owner, "rm -rvf '"TOMO_PREFIX"'/share/tomo/installed/", *u); + xsystem(as_owner, "rm -rvf '"TOMO_PREFIX"'/share/tomo_"TOMO_VERSION"/installed/", *u); print("Uninstalled ", *u); } @@ -368,6 +371,27 @@ Path_t build_file(Path_t path, const char *extension) return Path$with_component(build_dir, Texts(Path$base_name(path), Text$from_str(extension))); } +static Text_t get_version_suffix(Path_t lib_dir) +{ + Path_t changes_file = Path$with_component(lib_dir, Text("CHANGES.md")); + OptionalText_t changes = Path$read(changes_file); + if (changes.length <= 0) { + print_err("I couldn't find a valid CHANGES.md for the library in ", lib_dir, "\n" + "In order to install a library, it has to have a version defined in CHANGES.md\n" + "\n" + "Example CHANGES.md:\n" + "\n" + "# Version History\n" + "## v0.1\n" + "First version"); + } + const char *changes_str = Text$as_c_string(Texts(Text("\n"), changes)); + const char *version_line = strstr(changes_str, "\n## "); + if (version_line == NULL) + print_err("CHANGES.md in ", lib_dir, " does not have any valid versions starting with '## '"); + return Texts(Text("_"), Text$from_strn(version_line + 4, strcspn(version_line + 4, "\r\n"))); +} + void build_library(Path_t lib_dir) { lib_dir = Path$resolved(lib_dir, Path$current_dir()); @@ -382,7 +406,8 @@ void build_library(Path_t lib_dir) compile_files(env, tm_files, &object_files, &extra_ldlibs); - Path_t shared_lib = Path$with_component(lib_dir, Texts(Text("lib"), lib_dir_name, Text(SHARED_SUFFIX))); + Text_t version_suffix = get_version_suffix(lib_dir); + Path_t shared_lib = Path$with_component(lib_dir, Texts(Text("lib"), lib_dir_name, version_suffix, Text(SHARED_SUFFIX))); if (!is_stale_for_any(shared_lib, object_files)) { if (verbose) whisper("Unchanged: ", shared_lib); return; @@ -390,9 +415,9 @@ void build_library(Path_t lib_dir) FILE *prog = run_cmd(cc, " -O", optimization, " ", cflags, " ", ldflags, " ", ldlibs, " ", list_text(extra_ldlibs), #ifdef __APPLE__ - " -Wl,-install_name,@rpath/'lib", lib_dir_name, SHARED_SUFFIX, "'" + " -Wl,-install_name,@rpath/'lib", lib_dir_name, version_suffix, SHARED_SUFFIX, "'" #else - " -Wl,-soname,'lib", lib_dir_name, SHARED_SUFFIX, "'" + " -Wl,-soname,'lib", lib_dir_name, version_suffix, SHARED_SUFFIX, "'" #endif " -shared ", paths_str(object_files), " -o '", shared_lib, "'"); @@ -409,7 +434,8 @@ void build_library(Path_t lib_dir) void install_library(Path_t lib_dir) { Text_t lib_dir_name = Path$base_name(lib_dir); - Path_t dest = Path$with_component(Path$from_str(TOMO_PREFIX"/share/tomo/installed"), lib_dir_name); + Text_t version_suffix = get_version_suffix(lib_dir); + Path_t dest = Path$with_component(Path$from_str(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed"), Texts(lib_dir_name, version_suffix)); if (!Path$equal_values(lib_dir, dest)) { if (verbose) whisper("Clearing out any pre-existing version of ", lib_dir_name); xsystem(as_owner, "rm -rf '", dest, "'"); @@ -423,10 +449,10 @@ void install_library(Path_t lib_dir) if (verbose) whisper("Updating debug symbols for ", dest, "/lib", lib_dir_name, SHARED_SUFFIX); int result = system(String(as_owner, "debugedit -b ", lib_dir, " -d '", dest, "'" - " '", dest, "/lib", lib_dir_name, SHARED_SUFFIX, "'" - " 2>/dev/null >/dev/null")); + " '", dest, "/lib", lib_dir_name, version_suffix, SHARED_SUFFIX, "'" +)); (void)result; - print("Installed \033[1m", lib_dir_name, "\033[m to "TOMO_PREFIX"/share/tomo/installed"); + print("Installed \033[1m", lib_dir_name, "\033[m to "TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", lib_dir_name, version_suffix); } void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *extra_ldlibs) @@ -594,12 +620,12 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l } case USE_MODULE: { Text_t lib = Texts(Text("-Wl,-rpath,'"), - Text(TOMO_PREFIX "/share/tomo/installed/"), Text$from_str(use->path), - Text("' '" TOMO_PREFIX "/share/tomo/installed/"), + Text(TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed/"), Text$from_str(use->path), + Text("' '" TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed/"), Text$from_str(use->path), Text("/lib"), Text$from_str(use->path), Text(SHARED_SUFFIX "'")); Table$set(to_link, &lib, NULL, Table$info(&Text$info, &Void$info)); - List_t children = Path$glob(Path$from_str(String(TOMO_PREFIX"/share/tomo/installed/", use->path, "/*.tm"))); + List_t children = Path$glob(Path$from_str(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", use->path, "/*.tm"))); for (int64_t i = 0; i < children.length; i++) { Path_t *child = (Path_t*)(children.data + i*children.stride); Table_t discarded = {.fallback=to_compile}; diff --git a/src/typecheck.c b/src/typecheck.c index db3f392a..c80f6b2a 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -183,7 +183,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) } case USE_MODULE: { glob_t tm_files; - if (glob(String(TOMO_PREFIX"/share/tomo/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) + if (glob(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) code_err(module_ast, "Could not find library"); env_t *module_env = fresh_scope(env); |
