smake

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2025 License: MIT Imports: 17 Imported by: 0

README

SMake: Make Powered by S-expressions

SMake is a build tool similar to make on UNIX systems, but it uses S-expressions for its Makefile syntax.

Why smake?

Makefiles written for GNU Make often depend heavily on /bin/sh or other Unix-specific shell features, making it difficult to write portable build scripts that run the same on both Windows and Linux.

smake is a minimal build tool that avoids this problem by embedding all behavior in a Lisp dialect (ISLisp-like). All build logic is expressed using built-in functions, avoiding external shell commands and Unix-specific syntax.

This approach enables truly cross-platform builds without writing platform-specific conditionals, and without assuming Unix-like tools on Windows.

Example Usage

Using smake (Installed)
> cd "./examples/cc"

> smake clean
rm "main.o"
rm "sub.o"
rm "cc.exe"

> smake
gcc -c main.c
gcc -c sub.c
gcc -o cc.exe main.o sub.o
Using smake (via go run)
$ go run github.com/hymkor/smake@latest
Found update files: ("orig_test.go" "orig.go" "match.go" "main_windows.go" "main_unix.go" "main.go" "io.go" "gnu_test.go" "gnu.go" "go.sum" "go.mod" "embed.lsp" "Makefile.lsp")
go fmt
go build -ldflags -s -w -X main.version=v0.4.2-6-g940b278

examples/cc/Makefile.lsp:

;; # Equivalent Makefile for GNU Make (for reference)
;; ifeq ($(OS),Windows_NT)
;;   EXE=.exe
;; else
;;   EXE=
;; endif
;; AOUT=$(notdir $(CURDIR))$(EXE)
;; OFILES=$(subst .c,.o,$(wildcard *.c))
;; $(AOUT): $(OFILES)
;;     gcc -o $@ $(OFILES)
;; .c.o:
;;     gcc -c $<

(defun c-to-o (c) (string-append (basename c) ".o"))

(defglobal c-files (wildcard "*.c"))
(defglobal o-files (mapcar #'c-to-o c-files))
(defglobal target  (string-append (notdir (getwd)) *exe-suffix*))

(case $1
  (("clean")
   (dolist (obj o-files)
     (if (probe-file obj)
       (rm obj)))
   (if (probe-file target)
     (rm target)))

  (t
    (dolist (c-src c-files)
      (if (updatep (c-to-o c-src) c-src)
        (spawn "gcc" "-c" c-src)))
    (apply #'spawn "gcc" "-o" target o-files))
  ) ; case

; vim:set lispwords+=apply,make:

Install

Download the zipfile for your environment from Releases and unzip.

Use Go-installer
go install github.com/hymkor/smake@latest
Use scoop-installer
scoop install https://raw.githubusercontent.com/hymkor/smake/master/smake.json

or

scoop bucket add hymkor https://github.com/hymkor/scoop-bucket
scoop install smake

How to build SMake

go build

Lisp References

Base interpreter
ISLisp Documents (English)
ISLisp Documents (Japanese)

The functions available in Makefile.lsp

(updatep TARGET SOURCES...)

It returns the list of newer files in SOURCES than TARGET

(spawn "COMMAND" "ARG-1" "ARG-2" ...)

Execute the external executable directly. If it fails, the process will stop with an error.

(q "COMMAND" "ARG-1" "ARG-2" ...)

Execute the external executable directly and return its standard-output as string.

(sh "SHELL-COMMAND")

Execute the shell command by CMD.exe or /bin/sh. If it fails, the build process stops with an error.

(sh-ignore-error "SHELL-COMMAND")

Same as (sh) but ignores errors.

(shell "SHELL-COMMAND")

Execute the shell command and return its standard-output as string. Same as $(shell "..") of GNU Make.

(echo STRING...)

Equivalent to the UNIX echo command.

(rm FILENAME...)

Equivalent to the UNIX rm command.

(touch FILENAME...)

Equivalent to the UNIX touch command.

(dolist (KEY '(VALUE...)) COMMANDS...)
(getenv "NAME")

Return the value of the environment variable NAME. If it does not exist, return nil.

(setenv "NAME" "VALUE")

Set the environment variable "NAME" to "VALUE".

(env (("NAME" "VALUE")...) COMMANDS...)

Set the environment variables and execute COMMANDS. Then, restores them to their original values.

(wildcard "PATTERN"...)

Expand PATTERNs as a wildcard and return them as a list.

(abspath "FILEPATH")

Same as $(abspath FILEPATH) of GNU Make

(dir "FILEPATH")

Same as $(dir FILEPATH) of GNU Make

(notdir "FILEPATH")

Same as $(notdir FILEPATH) of GNU Make

(basename "FILEPATH")

Same as $(basename FILEPATH) of GNU Make

(join-path "DIR" .. "FNAME")

Make path with "DIR"... "FNAME".

(probe-file FILENAME)

If FILENAME exists, it returns t. Otherwise nil. Same as -e of Perl.

(probe-directory DIRNAME)

If DIRNAME exists and it is a directory, it returns t. Otherwise nil. Same as -d of Perl.

(chdir "DIRNAME")

Change the current working directory to "DIRNAME"

(getwd)

Returns the current working directory.

(pushd "DIRNAME" COMMANDS)

Change the current directory to "DIRNAME" and execute COMMANDS like (progn). After COMMANDS, return to the original current directory.

(cp SRC... DST)

Copy file SRC... to DST (directory or new filename)

(mv SRC... DST)

Move file SRC... to DST (directory or new filename)

(string-split SEP SEQUENCE)

(string-split #\: "a:b:c") => ("a" "b" "c")

(shellexecute "ACTION" "PATH" ["PARAM"] ["DIRECTORY"])

Call Windows-API: shellexecute

(string-fields "STRING")

Split "STRING" with white-spaces. This function is similar with strings.Fields in golang

(let), (format) and so on

These are standard functions compatible with ISLisp. See also hymkor/gmnlisp

(match REGULAR-EXPRESSION STRING)

If REGULAR-EXPRESSION matches STRING, (match) returns a list containing the entire matched part followed by the captured groups (submatches). If there is no match, it returns nil.

The built-in variables

*windows*

Evaluates to t when the environment variable %OS% is "Windows_NT" (i.e., on Windows).

*dev-null*

Evaluates to "NUL" on Windows, and to "/dev/null" on other systems.

*exe-suffix*

The file extension used for executables on the current operating system (e.g., ".exe" on Windows; empty string on Unix).

*argv* (formerly *args*)

The command-line arguments passed to the program.

$0, $1, $2, .. $9

Equivalent to (and (<= N (length *args*)) (elt (cons "path-to-smake *args*) N)) where "path-to-smake" is the full path to the SMake executable.

*path-separator*

OS-specific path separator (Windows "\" , UNIX "/" )

*path-list-separator*

OS-specfic path list separator (Windows ";", UNIX ":")

License

MIT License

Author

HAYAMA_Kaoru (hymkor)


Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL