{"id":18053783,"url":"https://github.com/hymkor/smake","last_synced_at":"2025-04-10T22:53:07.756Z","repository":{"id":61918764,"uuid":"538518008","full_name":"hymkor/smake","owner":"hymkor","description":"SMake: Make Powered by S-expressions","archived":false,"fork":false,"pushed_at":"2025-01-16T11:39:45.000Z","size":138,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T22:53:00.523Z","etag":null,"topics":["islisp","lisp","make"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hymkor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-19T13:32:42.000Z","updated_at":"2025-01-16T11:39:47.000Z","dependencies_parsed_at":"2025-01-04T19:00:29.020Z","dependency_job_id":null,"html_url":"https://github.com/hymkor/smake","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fsmake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fsmake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fsmake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fsmake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hymkor","download_url":"https://codeload.github.com/hymkor/smake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312171,"owners_count":21082638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["islisp","lisp","make"],"created_at":"2024-10-31T00:08:01.864Z","updated_at":"2025-04-10T22:53:07.722Z","avatar_url":"https://github.com/hymkor.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"SMake: Make Powered by S-expressions\n====================================\n\nSMake is a build tool similar to `make` on UNIX systems, but it uses S-expressions for its Makefile syntax.\n\n### Example Usage\n\n```\n$ smake clean\nchdir \"examples/cc\"\nC:\\Users\\hymkor\\src\\smake\\smake.exe clean\nchdir \"C:\\Users\\hymkor\\src\\smake\"\nrm \".smake.exe~\"\nmv \"smake.exe\" \".smake.exe~\"\n\n$ go run github.com/hymkor/smake@latest\nFound 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\")\ngo fmt\ngo build -ldflags -s -w -X main.version=v0.4.2-6-g940b278\n```\n\n### Key Features\n\n- **Build Rules in Lisp:**  \n    The Makefile for smake is written entirely in an extended version of ISLisp, providing a powerful and flexible structure for defining build rules. \n- **Execution Behavior:**  \n    `smake` reads and executes Makefile.lsp in the current directory.\n- **No Installation Required:**  \n    If Go is available, you can use smake without installation via `go run github.com/hymkor/smake@latest`\n\n[Makefile.lsp](./Makefile.lsp):\n\n```Makefile.lsp\n(defglobal EXE     (shell \"go env GOEXE\"))\n(defglobal CURDIR  (getwd))\n(defglobal NAME    (notdir CURDIR))\n(defglobal TARGET  (string-append NAME EXE))\n(defglobal SOURCE  (wildcard \"*.go\"))\n(defglobal NUL     (if windows \"NUL\" \"/dev/null\"))\n(defglobal VERSION\n  (catch\n    'notag\n    (with-handler\n      (lambda (c) (throw 'notag \"v0.0.0\"))\n      (shell (string-append \"git describe --tags 2\u003e\" NUL)))))\n\n(case $1\n  ((\"get\")\n   (sh \"go get -u\"\n       \"go get -u github.com/hymkor/gmnlisp@master\"\n       \"go mod tidy\"))\n\n  ((\"touch\")\n   (dolist (fname SOURCE)\n     (touch fname)))\n\n  ((\"clean\")\n   (pushd \"examples/cc\"\n     (spawnlp $0 \"clean\"))\n   (dolist (fname (wildcard \"*~\"))\n     (rm fname))\n   (if (-e TARGET)\n     (mv TARGET (string-append \".\" TARGET \"~\"))))\n\n  ((\"upgrade\") ; upgrade the installed program with the newly built version\n   (if (probe-file TARGET)\n     (let ((delimiter (elt (if windows \";\" \":\") 0)))\n       (dolist (dir (string-split delimiter (getenv \"PATH\")))\n         (if (and (not (equalp CURDIR dir))\n                  (probe-file (joinpath dir TARGET)))\n           (progn\n             (format (standard-output) \"copy \\\"~A\\\" to \\\"~A\\\" ? [Y or N] \" TARGET dir)\n             (if (equalp (read-line (standard-input) nil nil) \"y\")\n               (cp TARGET dir))))))))\n\n  ((\"test\")\n   (assert-eq (match \"^a*$\" \"aaaa\") '(\"aaaa\"))\n   (assert-eq (match \"^v([0-9]+)\\.([0-9]+)\\.([0-9]+)$\" \"v10.20.30\")\n              '(\"v10.20.30\" \"10\" \"20\" \"30\"))\n   (assert-eq (match \"^a*$\" \"hogehoge\") nil)\n   (assert-eq (catch\n                'fail\n                (with-handler\n                  (lambda (c) (throw 'fail 'NG))\n                  (match \"(\" \"hogehoge\")))\n              'NG)\n   (sh \"go test\"))\n\n  ((\"dist\")\n   (dolist (goos '(\"linux\" \"windows\"))\n     (dolist (goarch '(\"386\" \"amd64\"))\n       (env ((\"GOOS\" goos) (\"GOARCH\" goarch))\n         (let* ((exe (shell \"go env GOEXE\"))\n                (target (string-append NAME exe)))\n           (rm target)\n           (sh \"go build\")\n           (spawnlp\n             \"zip\"\n             (string-append NAME \"-\" VERSION \"-\" goos \"-\" goarch \".zip\")\n             target))))))\n\n  ((\"release\")\n   (let ((b (create-string-output-stream)))\n     (format b \"gh release create -d --notes \\\"\\\" -t\")\n     (format b \" \\\"~A\\\"\" VERSION)\n     (format b \" \\\"~A\\\"\" VERSION)\n     (dolist (zip (wildcard (string-append NAME \"-\" VERSION \"-*.zip\")))\n       (format b \" \\\"~A\\\"\" zip))\n     (sh (get-output-stream-string b))))\n\n  ((\"clean-zip\")\n   (dolist (fname (wildcard \"*.zip\"))\n     (rm fname)))\n\n  ((\"manifest\")\n   (sh \"make-scoop-manifest *.zip \u003e smake.json\"))\n\n  ((\"readme\")\n   (sh \"example-into-readme\"))\n\n  (t\n    (let ((ufiles (updatep TARGET \"Makefile.lsp\" \"embed.lsp\" \"go.mod\" \"go.sum\" SOURCE)))\n      (if ufiles\n        (progn\n          (format (error-output) \"Found update files: ~S~%\" ufiles)\n          (sh \"go fmt\")\n          (spawnlp \"go\" \"build\" \"-ldflags\"\n                   (string-append \"-s -w -X main.version=\" VERSION)))\n        (progn\n          (format (error-output) \"No files updated~%\")\n          )\n        ); if\n      ); let\n    ); t\n  ); case\n\n; vim:set lispwords+=env,mapc,pushd,while,doenv:\n```\n\nOther examples:\n\n- [examples/cc/Makefile.lsp](./examples/cc/Makefile.lsp) for C Project\n\nInstall\n-------\n\nDownload the zipfile for your environment from [Releases](https://github.com/hymkor/smake/releases) and unzip.\n\n### Use Go-installer\n\n```\ngo install github.com/hymkor/smake@latest\n```\n\n### Use scoop-installer\n\n```\nscoop install https://raw.githubusercontent.com/hymkor/smake/master/smake.json\n```\n\nor\n\n```\nscoop bucket add hymkor https://github.com/hymkor/scoop-bucket\nscoop install smake\n```\n\n## How to build SMake\n\n```\ngo build\n```\n\n## Lisp References\n\n### Base interpreter\n\n+ [hymkor/gmnlisp](https://github.com/hymkor/gmnlisp)\n\n### ISLisp Documents (English)\n\n+ [ISLISP - Wikipedia](https://en.wikipedia.org/wiki/ISLISP)\n+ [ISLisp Home Page][ISLisp]\n\n[ISLisp]: http://islisp.org/\n\n### ISLisp Documents (Japanese)\n\n+ [JISX3012:1998 プログラム言語ＩＳＬＩＳＰ](https://kikakurui.com/x3/X3012-1998-01.html)\n+ [M.Hiroi's Home Page / お気楽 ISLisp プログラミング超入門](http://www.nct9.ne.jp/m_hiroi/clisp/islisp.html)\n\n## The functions available in Makefile.lsp\n\n### (updatep TARGET SOURCES...)\n\nIt returns the list of newer files in SOURCES than TARGET\n\n### (spawnlp \"COMMAND\" \"ARG-1\" \"ARG-2\" ...)\n### (spawnvp \"COMMAND\" '(\"ARG-1\" \"ARG-2\" ...))\n\nExecute the external executable directly. If it failes, top.\n\n### (q \"COMMAND\" \"ARG-1\" \"ARG-2\" ...)\n\nExecute the external executable directly and return its standard-output as string.\n\n### (sh \"SHELL-COMMAND\")\n\nExecute the shell command by CMD.exe or /bin/sh. If it fails, stop.\n\n### (sh- \"SHELL-COMMAND\")\n\nSame as (sh) but ignores errors.\n\n### (shell \"SHELL-COMMAND\")\n\nExecute the shell command and return its standard-output as string.\nSame as $(shell \"..\") of GNU Make.\n\n### (echo STRING...)\n\nSame as the UNIX command echo.\n\n### (rm FILENAME...)\n\nSame as the UNIX command rm.\n\n### (touch FILENAME...)\n\nSame as the UNIX command touch.\n\n### (dolist (KEY '(VALUE...)) COMMANDS...)\n\n### (getenv \"NAME\")\n\nReturn the value of the environment variable NAME. If it does not exist, return nil.\n\n### (setenv \"NAME\" \"VALUE\")\n\nSet the environment variable \"NAME\" to \"VALUE\".\n\n### (env ((\"NAME\" \"VALUE\")...) COMMANDS...)\n\nSet the environment variables and execute COMMANDS.\nThen, restores them to thier original values.\n\n### (wildcard \"PATTERN\"...)\n\nExpand PATTERNs as a wildcard and return them as a list.\n\n### (abspath \"FILEPATH\")\n\nSame as $(abspath FILEPATH) of GNU Make\n\n### (dir \"FILEPATH\")\n\nSame as $(dir FILEPATH) of GNU Make\n\n### (notdir \"FILEPATH\")\n\nSame as $(notdir FILEPATH) of GNU Make\n\n### (basename \"FILEPATH\")\n\nSame as $(basename FILEPATH) of GNU Make\n\n### (pathjoin \"DIR\" .. \"FNAME\") , (joinpath \"DIR\"... \"FNAME\")\n\nMake path with \"DIR\"... \"FNAME\".\n(joinpath) is an alias of (pathjoin).\nSame as filepath.Join of golang.\n\n### (-e FILENAME)\n\nIf FILENAME exists, it returns t. Otherwise nil.\nSame as -e of Perl.\n\n### (-d DIRNAME)\n\nIf DIRNAME exists and it is a directory, it returns t. Otherwise nil.\nSame as -d of Perl.\n\n### (chdir \"DIRNAME\")\n\nChange the current working directory to \"DIRNAME\"\n\n### (getwd)\n\nReturns the current working directory.\n\n### (pushd \"DIRNAME\" COMMANDS)\n\nChange the current directory to \"DIRNAME\" and execute COMMANDS like (progn).\nAfter COMMANDS, return to the original current directory.\n\n### (cp SRC... DST)\n\nCopy file SRC... to DST (directory or new filename)\n\n### (mv SRC... DST)\n\nMove file SRC... to DST (directory or new filename)\n\n### (string-split SEP SEQUENCE)\n\n`(string-split #\\: \"a:b:c\")` =\u0026gt; `(\"a\" \"b\" \"c\")`\n\n### (shellexecute \"ACTION\" \"PATH\" \\[\"PARAM\"\\] \\[\"DIRECTORY\"\\])\n\nCall Windows-API: shellexecute\n\n### (string-fields \"STRING\")\n\nSplit \"STRING\" with whilte-spaces. This function is similar with [strings.Fields](https://pkg.go.dev/strings@go1.20.1#Fields) in golang\n\n### (let), (format) and so on\n\nThey are compatible functions with ISLisp. See also [hymkor/gmnlisp](https://github.com/hymkor/gmnlisp)\n\n### windows\n\nIt is `t` (true) when %OS% is `Windows_NT`\n\n### (match REGULAR-EXPRESSION STRING)\n\nIf `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`.\n\n## The built-in variables\n\n- $/ - OS-specific path separator (Windows `\\` , UNIX `/` )\n- \\*args\\* - the command-line arguments\n- $1...$9 - the same as `(elt *args* N)`\n- $0 ... the current executing smake filename\n\nThese are available in `(make)` block\n\n- $@ - the target filename\n- $\u0026lt; - the first source filename\n- $? - the updated source filenames\n\n---\n\n- [Deprecated functions](./deprecated.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhymkor%2Fsmake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhymkor%2Fsmake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhymkor%2Fsmake/lists"}