From c19b5948495be493b6341d3ff1b03da599a0cd0a Mon Sep 17 00:00:00 2001 From: Dave Cottlehuber Date: Wed, 29 Oct 2014 23:47:30 +0100 Subject: add escript plugin --- README.md | 27 +++++++++++++++++++++++ build.config | 1 + erlang.mk | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/escript.mk | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 plugins/escript.mk diff --git a/README.md b/README.md index c2d83a7..df87bf3 100644 --- a/README.md +++ b/README.md @@ -358,6 +358,33 @@ This plugin is available by default. It adds automatic compilation of ErlyDTL templates found in `templates/*.dtl` or any subdirectory. +Escript plugin +-------------- + +This plugin is available by default. It adds the following +target: + +`escript` which creates a shell-executable archive named +the same as your `$(PROJECT)`, containing the following files +from your application and its dependencies: + +* `*.beam` +* contents of `priv/` +* `sys.config` for your application + +There are a number of optional configuration parameters: + +* `ESCRIPT_NAME` if a different output file is required +* `ESCRIPT_COMMENT` to alter the comment line in the escript header +* `ESCRIPT_BEAMS` for the paths searched for `*.beam` files to include +* `ESCRIPT_SYS_CONFIG` defaults to `rel/sys.config` +* `ESCRIPT_EMU_ARGS` for the parameters used to start the VM +* `ESCRIPT_SHEBANG` for the line used by your shell to start `escript` +* `ESCRIPT_STATIC` for non-beam directories to be included as well + +Refer to http://www.erlang.org/doc/man/escript.html for +more information on `escript` functionality in general. + Relx plugin ----------- diff --git a/build.config b/build.config index 067a0ad..a166e01 100644 --- a/build.config +++ b/build.config @@ -16,5 +16,6 @@ plugins/dialyzer plugins/edoc plugins/elvis plugins/erlydtl +plugins/escript plugins/relx plugins/shell diff --git a/erlang.mk b/erlang.mk index 5b07ef8..8226e30 100644 --- a/erlang.mk +++ b/erlang.mk @@ -890,6 +890,69 @@ ebin/$(PROJECT).app:: $(shell find templates -type f -name \*.dtl 2>/dev/null) $(if $(strip $?),$(call compile_erlydtl,$?)) endif +# Copyright (c) 2014 Dave Cottlehuber +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-escript escript + +# Configuration. + +ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_COMMENT ?= This is an -*- erlang -*- file + +ESCRIPT_BEAMS ?= "ebin/*", "deps/*/ebin/*" +ESCRIPT_SYS_CONFIG ?= "rel/sys.config" +ESCRIPT_EMU_ARGS ?= -pa . \ + -noshell -noinput \ + -sasl errlog_type error \ + -escript main $(ESCRIPT_NAME) +ESCRIPT_SHEBANG ?= /usr/bin/env escript +ESCRIPT_STATIC ?= "deps/*/priv/**", "priv/**" + +# Core targets. + +distclean:: distclean-escript + +help:: + @printf "%s\n" "" \ + "Escript targets:" \ + " escript Build an executable escript archive" \ + +# Plugin-specific targets. + +# Based on https://github.com/synrc/mad/blob/master/src/mad_bundle.erl +# Copyright (c) 2013 Maxim Sokhatsky, Synrc Research Center +# Modified MIT License, https://github.com/synrc/mad/blob/master/LICENSE : +# Software may only be used for the great good and the true happiness of all +# sentient beings. +define ESCRIPT_RAW +'Read = fun(F) -> {ok, B} = file:read_file(filename:absname(F)), B end,'\ +'Files = fun(L) -> A = lists:concat([filelib:wildcard(X)||X<- L ]),'\ +' [F || F <- A, not filelib:is_dir(F) ] end,'\ +'Squash = fun(L) -> [{filename:basename(F), Read(F) } || F <- L ] end,'\ +'Zip = fun(A, L) -> {ok,{_,Z}} = zip:create(A, L, [{compress,all},memory]), Z end,'\ +'Ez = fun(Escript) ->'\ +' Static = Files([$(ESCRIPT_STATIC)]),'\ +' Beams = Squash(Files([$(ESCRIPT_BEAMS), $(ESCRIPT_SYS_CONFIG)])),'\ +' Archive = Beams ++ [{ "static.gz", Zip("static.gz", Static)}],'\ +' escript:create(Escript, [ $(ESCRIPT_OPTIONS)'\ +' {archive, Archive, [memory]},'\ +' {shebang, "$(ESCRIPT_SHEBANG)"},'\ +' {comment, "$(ESCRIPT_COMMENT)"},'\ +' {emu_args, " $(ESCRIPT_EMU_ARGS)"}'\ +' ]),'\ +' file:change_mode(Escript, 8#755)'\ +'end,'\ +'Ez("$(ESCRIPT_NAME)").' +endef +ESCRIPT_COMMAND = $(subst ' ',,$(ESCRIPT_RAW)) + +escript:: distclean-escript deps app + $(gen_verbose) erl -noshell -eval $(ESCRIPT_COMMAND) -s init stop + +distclean-escript: + $(gen_verbose) rm -f $(ESCRIPT_NAME) + # Copyright (c) 2013-2014, Loïc Hoguin # This file is part of erlang.mk and subject to the terms of the ISC License. diff --git a/plugins/escript.mk b/plugins/escript.mk new file mode 100644 index 0000000..5a6a0dd --- /dev/null +++ b/plugins/escript.mk @@ -0,0 +1,62 @@ +# Copyright (c) 2014 Dave Cottlehuber +# This file is part of erlang.mk and subject to the terms of the ISC License. + +.PHONY: distclean-escript escript + +# Configuration. + +ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_COMMENT ?= This is an -*- erlang -*- file + +ESCRIPT_BEAMS ?= "ebin/*", "deps/*/ebin/*" +ESCRIPT_SYS_CONFIG ?= "rel/sys.config" +ESCRIPT_EMU_ARGS ?= -pa . \ + -noshell -noinput \ + -sasl errlog_type error \ + -escript main $(ESCRIPT_NAME) +ESCRIPT_SHEBANG ?= /usr/bin/env escript +ESCRIPT_STATIC ?= "deps/*/priv/**", "priv/**" + +# Core targets. + +distclean:: distclean-escript + +help:: + @printf "%s\n" "" \ + "Escript targets:" \ + " escript Build an executable escript archive" \ + +# Plugin-specific targets. + +# Based on https://github.com/synrc/mad/blob/master/src/mad_bundle.erl +# Copyright (c) 2013 Maxim Sokhatsky, Synrc Research Center +# Modified MIT License, https://github.com/synrc/mad/blob/master/LICENSE : +# Software may only be used for the great good and the true happiness of all +# sentient beings. +define ESCRIPT_RAW +'Read = fun(F) -> {ok, B} = file:read_file(filename:absname(F)), B end,'\ +'Files = fun(L) -> A = lists:concat([filelib:wildcard(X)||X<- L ]),'\ +' [F || F <- A, not filelib:is_dir(F) ] end,'\ +'Squash = fun(L) -> [{filename:basename(F), Read(F) } || F <- L ] end,'\ +'Zip = fun(A, L) -> {ok,{_,Z}} = zip:create(A, L, [{compress,all},memory]), Z end,'\ +'Ez = fun(Escript) ->'\ +' Static = Files([$(ESCRIPT_STATIC)]),'\ +' Beams = Squash(Files([$(ESCRIPT_BEAMS), $(ESCRIPT_SYS_CONFIG)])),'\ +' Archive = Beams ++ [{ "static.gz", Zip("static.gz", Static)}],'\ +' escript:create(Escript, [ $(ESCRIPT_OPTIONS)'\ +' {archive, Archive, [memory]},'\ +' {shebang, "$(ESCRIPT_SHEBANG)"},'\ +' {comment, "$(ESCRIPT_COMMENT)"},'\ +' {emu_args, " $(ESCRIPT_EMU_ARGS)"}'\ +' ]),'\ +' file:change_mode(Escript, 8#755)'\ +'end,'\ +'Ez("$(ESCRIPT_NAME)").' +endef +ESCRIPT_COMMAND = $(subst ' ',,$(ESCRIPT_RAW)) + +escript:: distclean-escript deps app + $(gen_verbose) erl -noshell -eval $(ESCRIPT_COMMAND) -s init stop + +distclean-escript: + $(gen_verbose) rm -f $(ESCRIPT_NAME) -- cgit v1.2.3