1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-01 04:19:55 +00:00

Add jpm tool, based on cook.

Modify cook as well.
This commit is contained in:
Calvin Rose 2019-05-27 16:50:57 -04:00
parent ce9cd4fcef
commit 1696de233c
6 changed files with 204 additions and 49 deletions

View File

@ -300,6 +300,8 @@ install: $(JANET_TARGET) $(PKG_CONFIG_PATH)/janet.pc
ln -sf $(SONAME) $(LIBDIR)/libjanet.so ln -sf $(SONAME) $(LIBDIR)/libjanet.so
ln -sf libjanet.so.$(shell $(JANET_TARGET) -e '(print janet/version)') $(LIBDIR)/$(SONAME) ln -sf libjanet.so.$(shell $(JANET_TARGET) -e '(print janet/version)') $(LIBDIR)/$(SONAME)
cp tools/cook.janet $(JANET_PATH) cp tools/cook.janet $(JANET_PATH)
cp tools/jpm $(BINDIR)/jpm
chmod +x $(BINDIR)/jpm
cp tools/highlight.janet $(JANET_PATH) cp tools/highlight.janet $(JANET_PATH)
cp tools/bars.janet $(JANET_PATH) cp tools/bars.janet $(JANET_PATH)
mkdir -p $(MANPATH) mkdir -p $(MANPATH)

View File

@ -131,6 +131,7 @@ copy src\include\janet.h dist\janet.h
copy src\include\janetconf.h dist\janetconf.h copy src\include\janetconf.h dist\janetconf.h
copy tools\cook.janet dist\cook.janet copy tools\cook.janet dist\cook.janet
copy tools\highlight.janet dist\highlight.janet copy tools\highlight.janet dist\highlight.janet
copy tools\jpm dist\jpm
exit /b 0 exit /b 0
:TESTFAIL :TESTFAIL

View File

@ -130,6 +130,7 @@ janet_mainclient = executable('janet', core_src, core_image, init_gen, mainclien
include_directories : incdir, include_directories : incdir,
dependencies : [m_dep, dl_dep], dependencies : [m_dep, dl_dep],
install : true) install : true)
janet_jpm = install_data('tools/jpm', install_dir : 'bin')
# Documentation # Documentation
docs = custom_target('docs', docs = custom_target('docs',

View File

@ -1686,15 +1686,16 @@
@{}) @{})
(defn dofile (defn dofile
"Evaluate a file in a new environment and return the new environment." "Evaluate a file and return the resulting environment."
[path & args] [path & args]
(def {:exit exit-on-error (def {:exit exit-on-error
:source source :source source
:env env
:compile-only compile-only} (table ;args)) :compile-only compile-only} (table ;args))
(def f (if (= (type path) :core/file) (def f (if (= (type path) :core/file)
path path
(file/open path))) (file/open path)))
(def newenv (make-env)) (default env (make-env))
(defn chunks [buf _] (file/read f 2048 buf)) (defn chunks [buf _] (file/read f 2048 buf))
(defn bp [&opt x y] (defn bp [&opt x y]
(def ret (bad-parse x y)) (def ret (bad-parse x y))
@ -1704,7 +1705,7 @@
(def ret (bad-compile x y z)) (def ret (bad-compile x y z))
(if exit-on-error (os/exit 1)) (if exit-on-error (os/exit 1))
ret) ret)
(run-context {:env newenv (run-context {:env env
:chunks chunks :chunks chunks
:on-parse-error bp :on-parse-error bp
:on-compile-error bc :on-compile-error bc
@ -1715,7 +1716,7 @@
:compile-only compile-only :compile-only compile-only
:source (or source (if (= f path) "<anonymous>" path))}) :source (or source (if (= f path) "<anonymous>" path))})
(when (not= f path) (file/close f)) (when (not= f path) (file/close f))
(table/setproto newenv nil)) env)
(def module/loaders (def module/loaders
"A table of loading method names to loading functions. "A table of loading method names to loading functions.

View File

@ -1,5 +1,6 @@
# Library to help build janet natives and other # Library to help build janet natives and other
# build artifacts. # build artifacts.
# Copyright 2019 © Calvin Rose
# Windows is the OS outlier # Windows is the OS outlier
(def- is-win (= (os/which) :windows)) (def- is-win (= (os/which) :windows))
@ -8,26 +9,44 @@
(def- objext (if is-win ".obj" ".o")) (def- objext (if is-win ".obj" ".o"))
(def- modext (if is-win ".dll" ".so")) (def- modext (if is-win ".dll" ".so"))
(def prefix (or (os/getenv "PREFIX") "/usr/local")) # Get default paths and options from environment
(def prefix (or (os/getenv "PREFIX")
(if is-win "C:\\Janet" "/usr/local")))
(def bindir (or (os/getenv "BINDIR")
(string prefix sep "bin")))
(def libdir (or (os/getenv "LIBDIR")
(string prefix sep (if is-win "Library" "lib/janet"))))
(def includedir (or (os/getenv "INCLUDEDIR") module/*headerpath*))
(def optimize (or (os/getenv "OPTIMIZE") 2))
(def CC (or (os/getenv "CC") (if is-win "cl" "cc")))
(defn artifact
"Add an artifact. An artifact is an item that can be installed
or otherwise depended upon after being built."
[x]
(let [as (dyn :artifacts)]
(array/push (or as (setdyn :artifacts @[])) x)))
(defn- add-command
"Add a build command."
[cmd]
(let [cmds (dyn :commands)]
(array/push (or cmds (setdyn :commands @[])) cmd)))
(defn shell (defn shell
"Do a shell command" "Do a shell command"
[& args] [& args]
(def cmd (string ;args)) (add-command (string ;args)))
(print cmd)
(def res (os/shell cmd))
(unless (zero? res)
(error (string "command exited with status " res))))
(defn- rm (defmacro delay-build
"Remove a directory and all sub directories." "Delay an express to build time."
[path] [& expr]
(if (= (os/stat path :mode) :directory) ~(,add-command (fn [] ,;expr)))
(do
(each subpath (os/dir path) (defn- copy
(rm (string path sep subpath))) "Copy a file from one location to another."
(os/rmdir path)) [src dest]
(os/rm path))) (shell (if is-win "robocopy " "cp -rf ") src " " dest (if is-win " /s /e" "")))
(defn- needs-build (defn- needs-build
[dest src] [dest src]
@ -94,8 +113,6 @@
(seq [[d v] :pairs defines] (make-define d (if (not= v true) v)))) (seq [[d v] :pairs defines] (make-define d (if (not= v true) v))))
# Defaults # Defaults
(def OPTIMIZE 2)
(def CC (if is-win "cl" "cc"))
(def LD (if is-win (def LD (if is-win
"link" "link"
(string CC (string CC
@ -103,12 +120,12 @@
(if is-mac " -undefined dynamic_lookup" "")))) (if is-mac " -undefined dynamic_lookup" ""))))
(def CFLAGS (string (def CFLAGS (string
(if is-win "/I" "-I") (if is-win "/I" "-I")
module/*headerpath* includedir
(if is-win " /O" " -std=c99 -Wall -Wextra -fpic -O") (if is-win " /O" " -std=c99 -Wall -Wextra -fpic -O")
OPTIMIZE)) optimize))
(defn- compile-c (defn- compile-c
"Compile a C file into an object file." "Compile a C file into an object file. Delayed."
[opts src dest] [opts src dest]
(def cc (or (opts :compiler) CC)) (def cc (or (opts :compiler) CC))
(def cflags (or (opts :cflags) CFLAGS)) (def cflags (or (opts :cflags) CFLAGS))
@ -119,7 +136,7 @@
(shell cc " -c " src " " ;defines " " cflags " -o " dest)))) (shell cc " -c " src " " ;defines " " cflags " -o " dest))))
(defn- link-c (defn- link-c
"Link a number of object files together." "Link a number of object files together. Delayed."
[opts target & objects] [opts target & objects]
(def ld (or (opts :linker) LD)) (def ld (or (opts :linker) LD))
(def cflags (or (opts :cflags) CFLAGS)) (def cflags (or (opts :cflags) CFLAGS))
@ -131,7 +148,7 @@
(shell ld " " cflags " -o " target " " olist " " lflags)))) (shell ld " " cflags " -o " target " " olist " " lflags))))
(defn- create-buffer-c (defn- create-buffer-c
"Inline raw byte file as a c file." "Inline raw byte file as a c file. Immediate."
[source dest name] [source dest name]
(when (needs-build dest source) (when (needs-build dest source)
(def f (file/open source :r)) (def f (file/open source :r))
@ -148,16 +165,41 @@
(file/close out) (file/close out)
(file/close f))) (file/close f)))
# Public # Installation Helpers
(defn make-native (defn- prep-install
[dir]
(try (os/mkdir dir) ([err] nil)))
(defn- install-janet-module
"Install a janet source module."
[name]
(prep-install libdir)
(copy name libdir))
(defn- install-native-module
"Install a native module."
[name]
(prep-install libdir)
(copy name libdir))
(defn- install-binscript
"Install a binscript."
[name]
(prep-install bindir)
(copy name bindir))
# Declaring Artifacts - used in project.janet
(defn declare-native
"Build a native binary. This is a shared library that can be loaded "Build a native binary. This is a shared library that can be loaded
dynamically by a janet runtime." dynamically by a janet runtime."
[& opts] [& opts]
(def opt-table (table ;opts)) (def opt-table (table ;opts))
(os/mkdir "build")
(def sources (opt-table :source)) (def sources (opt-table :source))
(def name (opt-table :name)) (def name (opt-table :name))
(def lname (lib-name name))
(artifact [lname :native opt-table])
(loop [src :in sources] (loop [src :in sources]
(compile-c opt-table src (object-name src))) (compile-c opt-table src (object-name src)))
(def objects (map object-name sources)) (def objects (map object-name sources))
@ -166,29 +208,108 @@
(def c-src (embed-c-name src)) (def c-src (embed-c-name src))
(def o-src (embed-o-name src)) (def o-src (embed-o-name src))
(array/push objects o-src) (array/push objects o-src)
(create-buffer-c src c-src (embed-name src)) (delay-build (create-buffer-c src c-src (embed-name src)))
(compile-c opt-table c-src o-src))) (compile-c opt-table c-src o-src)))
(link-c opt-table (lib-name name) ;objects)) (link-c opt-table lname ;objects))
(defn clean (defn declare-source
"Remove all built artifacts." "Create a Janet modules. This does not actually build the module(s),
[] but registers it for packaging and installation."
(rm "build")) [& opts]
(def opt-table (table ;opts))
(def sources (opt-table :source))
(each s sources
(artifact [s :janet opt-table])))
(defn make-archive (defn declare-binscript
"Declare a janet file to be installed as an executable script."
[& opts]
(def opt-table (table ;opts))
(def main (opt-table :main))
(artifact [main :binscript opt-table]))
(defn declare-archive
"Build a janet archive. This is a file that bundles together many janet "Build a janet archive. This is a file that bundles together many janet
scripts into a janet image. This file can the be moved to any machine with scripts into a janet image. This file can the be moved to any machine with
a janet vm and the required dependencies and run there." a janet vm and the required dependencies and run there."
[& opts] [& opts]
(def opt-table (table ;opts)) (def opt-table (table ;opts))
(os/mkdir "build")
(def entry (opt-table :entry)) (def entry (opt-table :entry))
(def name (opt-table :name)) (def name (opt-table :name))
(spit (string name ".jimage") (make-image (require entry)))) (def iname (string "build" sep name ".jimage"))
(artifact [iname :image opt-table])
(delay-build (spit iname (make-image (require entry)))))
(defn make-binary (defn declare-project
"Make a binary executable that can be run on the current platform. This function "Define your project metadata."
generates a self contained binary that can be run of the same architecture as the [&keys meta]
build machine, as the current janet vm will be packaged with the output binary." (setdyn :project meta))
[& opts]
(error "Not Yet Implemented.")) # Tool usage - called from tool
(defn- rm
"Remove a directory and all sub directories."
[path]
(if (= (os/stat path :mode) :directory)
(do
(each subpath (os/dir path)
(rm (string path sep subpath)))
(os/rmdir path))
(os/rm path)))
(defn- flush-commands
"Run all pending commands."
[]
(os/mkdir "build")
(when-let [cmds (dyn :commands)]
(each cmd cmds
(if (bytes? cmd)
(do
(print cmd)
(def res (os/shell cmd))
(unless (zero? res)
(error (string "command exited with status " res))))
(cmd)))
(setdyn :commands @[])))
(defn clean
"Remove all built artifacts."
[]
(print "cleaning...")
(rm "build"))
(defn build
"Build all artifacts."
[]
(print "building...")
(flush-commands))
(defn install
"Install all artifacts."
[]
(flush-commands)
(print "installing...")
(each [name kind opts] (dyn :artifacts ())
(case kind
:janet (install-janet-module name)
:image (install-janet-module name)
:native (install-native-module name)
:binscript (install-binscript name)))
(flush-commands))
(defn test
"Run all tests. This means executing janet files in the test directory."
[]
(flush-commands)
(print "testing...")
(defn dodir
[dir]
(each sub (os/dir dir)
(def ndir (string dir sep sub))
(case (os/stat ndir :mode)
:file (when (string/has-suffix? ".janet" ndir)
(print "running " ndir " ...")
(dofile ndir :exit true))
:directory (dodir ndir))))
(dodir "test")
(print "All tests passed."))

29
tools/jpm Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env janet
# Cook CLI tool for building janet projects.
(import cook :prefix "")
(defn- load
[]
(dofile "./project.janet" :env (fiber/getenv (fiber/current))))
# Flag handlers
(case (process/args 2)
"install" (do (load) (install))
"build" (do (load) (build))
"clean" (clean)
"test" (do (load) (test))
(do
(def x (process/args 2))
(if (not= x "help") (print "unknown command: " x))
(print "usage: jpm [command]")
(print
`
Commands are:
help : Show this help
install : Install all artifacts
test : Run all tests
build : Build all artifacts
clean : Remove all artifacts
`)))