jirutka / luapak

Easily build a standalone executable for any Lua program
MIT License
200 stars 7 forks source link
build-tool lua luarocks static-binary

= Luapak Jakub Jirutka https://github.com/jirutka[@jirutka] :toc: macro :toc-title: // custom :proj-name: luapak :gh-name: jirutka/{proj-name} :gh-branch: master :appveyor-id: qmkkk86ldwvkvdc9 :ldoc-url: https://jirutka.github.io/{proj-name}/ldoc/

ifdef::env-github[] image:https://travis-ci.org/{gh-name}.svg?branch={gh-branch}["Build Status", link="https://travis-ci.org/{gh-name}"] image:https://ci.appveyor.com/api/projects/status/{appveyor-id}/branch/{gh-branch}?svg=true["Windows Build Status", link="https://ci.appveyor.com/project/{gh-name}"] image:https://img.shields.io/badge/ldoc-docs-blue.svg["LDoc", link="{ldoc-url}"] endif::env-github[]

Luapak is a command-line tool that offers complete, multi-platform (Linux, macOS, and Windows), adjustable, all-in-one (yet modular) solution for building a standalone, zero-dependencies, possibly statically linked (only on Linux) executable for (almost) any Lua program. It Just Works!

. Resolves, builds and installs project’s Lua dependencies (declared in rockspec) from https://luarocks.org/[LuaRocks]. Lua/C modules (aka native extensions) are built as static libraries (.a archive files), so they can be statically linked into resulting executable.footnote:[Luapak includes LuaRocks package manager with rewritten https://github.com/luarocks/luarocks/wiki/Rockspec-format#builtin[builtin build backend] and modified settings to build Lua/C modules as static libraries. Other backends (make, cmake, …) are not supported in the sense that Luapak cannot alter build process to produce static libraries; it’s up to the user to ensure that.] . Resolves actually required Lua and Lua/C modules (.lua and .a files) using static code analysis of the project and its dependencies (recursively). . Merges all required Lua modules into a single Lua script. . Minifies the Lua script (i.e. removes unnecessary characters to shrink its size) using https://github.com/jirutka/luasrcdiet[LuaSrcDiet]. . Compresses the Lua script using https://github.com/jibsen/brieflz[BriefLZ] algorithm. . Embeds the Lua script into a generated C wrapper. . Compiles the C wrapper and links it with Lua interpreter (PUC Lua 5.1–5.3 and LuaJIT supported) and Lua/C libraries (aka native extensions) into a standalone executable.

All these steps can be run with single command luapak make <rockspec>, or separately if you need more control. You can discover available commands and their options in section <>.

[discrete] == Table of Contents

toc::[]

== Commands

=== luapak make

// include:help-make:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak make [options] [PACKAGE...]
       luapak make --help

Makes a standalone executable from Lua package(s). This is the main Luapak
command that handles entire process from installing dependencies to
compiling executable.
Arguments:
  PACKAGE                         Lua package to build specified as <source-dir>:<rockspec>.
                                  :<rockspec> may be omitted if the <source-dir> or
                                  <source-dir>/rockspec(s) contains single rockspec, or multiple
                                  rockspecs for the same package (i.e. with different version).
                                  In the further case rockspec with the highest version is used.
                                  <source-dir>: may be omitted if the <rockspec> is in the
                                  project's source directory or rockspec(s) subdirectory.
                                  If no argument is given, the current directory is used as
                                  <source-dir>.

Options:
  -s, --entry-script=FILE         The entry point of your program, i.e. the main Lua script. If not
                                  specified and the last PACKAGE defines exactly one CLI script,
                                  then it's used.

  -e, --exclude-modules=PATTERNS  Module(s) to exclude from dependencies analysis and the
                                  generated binary. PATTERNS is one or more glob patterns matching
                                  module name in dot notation (e.g. "pl.*"). Patterns may be
                                  delimited by comma or space. This option can be also specified
                                  multiple times.

  -g, --debug                     Enable debug mode, i.e. preserve line numbers, module names and
                                  local variable names for error messages and backtraces.

  -i, --include-modules=PATTERNS  Extra module(s) to include in dependencies analysis and add to
                                  the generated binary. PATTERNS has the same format as in
                                  "--exclude-module".

      --lua-impl=NAME             The Lua implementation that should be used - "PUC" (default),
                                  or "LuaJIT". This is currently used only as a hint to find the
                                  correct library and headers when auto-detection is used
                                  (i.e. --lua-incdir or --lua-lib is not specified).

      --lua-incdir=DIR            The directory that contains Lua (or LuaJIT) headers. If not
                                  specified, luapak will look for the lua.h (and luajit.h) file
                                  inside: Luarock's LUA_INCDIR, ./vendor/lua, ./deps/lua,
                                  /usr/local/include, and /usr/include. If --lua-version is
                                  specified, then it will also try subdirectories lua<version> and
                                  lua-<version> of each of the named directories and verify that
                                  the found lua.h (or luajit.h) is for the specified Lua
                                  (or LuaJIT) version.

      --lua-lib=FILE              The library of Lua interpreter to include in the binary. If not
                                  specified, luapak will try to find library with version
                                  corresponding to the headers inside Luarock's LUA_LIBDIR,
                                  ./vendor/lua, ./deps/lua, /usr/local/lib, /usr/local/lib64,
                                  /usr/lib, and /usr/lib64.

      --lua-version=VERSION       The version number of Lua (or LuaJIT) headers and library to try
                                  to find (e.g. "5.3", "2.0").

  -o, --output=FILE               Output file name or path. Defaults to base name of the main
                                  script with stripped .lua extension.

  -C, --no-compress               Disable BriefLZ compression of Lua sources.

  -M, --no-minify                 Disable minification of Lua sources.

  -t, --rocks-tree=DIR            The prefix where to install required modules. Default is
                                  ".luapak" in the current directory.
  -q, --quiet                     Be quiet, i.e. print only errors.

  -v, --verbose                   Be verbose, i.e. print debug messages.

  -h, --help                      Display this help message and exit.

Environment Variables:
  AR          Archive-maintaining program; default is "ar".
  CC          Command for compiling C; default is "gcc".
  CMAKE       Command for processing CMakeLists.txt files; default is "cmake".
  CFLAGS      Extra flags to give to the C compiler; default is "-Os -fPIC".
  LD          Command for linking object files and archive files; default is "ld".
  LDFLAGS     Extra flags to give to compiler when they are supposed to invoke the linker;
              default on macOS is "-pagezero_size 10000 -image_base 100000000".
  MAKE        Command for executing Makefile; default is "make".
  RANLIB      Command for generating index to the contents of an archive; default is "ranlib".
  STRIP       Command for discarding symbols from an object file; default is "strip".

++++ // include:help-make:end

=== luapak analyse-deps

// include:help-analyse-deps:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak analyse-deps [-a|-f|-m|-g] [options] FILE...
       luapak analyse-deps --help

Analyses dependency graph of Lua module(s) using static code analysis (looks
for "require" expressions).
Arguments:
  FILE                        The entry point(s); path(s) to Lua script(s) to analyse.

Options:
  -a, --all                   Print all information (default).
  -f, --found                 Print only found modules.
  -m, --missing               Print only missing modules.
  -g, --ignored               Print only excluded/ignored modules.

  -e, --excludes=PATTERNS     Module(s) to exclude from the dependencies analysis. PATTERNS is one
                              or more glob patterns matching module name in dot notation
                              (e.g. "pl.*"). Patterns may be delimited by comma or space. This
                              option can be also specified multiple times.

  -n, --ignore-errors         Ignore errors from dependencies resolution (like unredable or unparseable files).

  -P, --no-pcalls             Do not analyse pcall requires.

  -W, --no-wildcards          Do not expand "wildcard" requires.

  -p, --pkg-path=PATH         The path pattern where to search for Lua and C/Lua modules instead of
                              the default path.

  -v, --verbose               Be verbose, i.e. print debug messages.

  -h, --help                  Display this help message and exit.

++++ // include:help-analyse-deps:end

=== luapak build-rock

// include:help-build-rock:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak build-rock [options] ROCKSPEC...
       luapak build-rock --help

Builds Lua/C module as a library archive suitable for static linking
and installs it into rocks tree.
Arguments:
  ROCKSPEC                    Path of the rockspec file to build and install.

Options:
  -C, --directory=DIR         Change directory before doing anything.

  -i, --lua-impl=NAME         The Lua implementation that should be used - "PUC" (default), or
                              "LuaJIT". This is currently used only as a hint to find the correct
                              headers when auto-detection is used (i.e. --lua-incdir unspecified).

  -I, --lua-incdir=DIR        The directory that contains Lua (or LuaJIT) headers. If not
                              specified, luapak will look for the lua.h (and luajit.h) file inside:
                              Luarock's LUA_INCDIR, ./vendor/lua, ./deps/lua, /usr/local/include,
                              and /usr/include. If --lua-version is specified, then it will also
                              try subdirectories lua<version> and lua-<version> of each of the
                              named directories and verify that the found lua.h (or luajit.h) is
                              for the specified Lua (or LuaJIT) version.

  -l, --lua-version=VERSION   The version number of Lua (or LuaJIT) headers and library to try
                              to find (e.g. "5.3", "2.0").

  -t, --rocks-tree=DIR        The prefix where to install Lua/C modules Default is ".luapak" in
                              the current directory.

  -v, --verbose               Be verbose, i.e. print debug messages.

  -h, --help                  Display this help message and exit.

Environment Variables:
  AR          Archive-maintaining program; default is "ar".
  CC          Command for compiling C; default is "gcc".
  CMAKE       Command for processing CMakeLists.txt files; default is "cmake".
  CFLAGS      Extra flags to give to the C compiler; default is "-Os -fPIC".
  LD          Command for linking object files and archive files; default is "ld".
  LDFLAGS     Extra flags to give to compiler when they are supposed to invoke the linker;
              default on macOS is "-pagezero_size 10000 -image_base 100000000".
  MAKE        Command for executing Makefile; default is "make".
  RANLIB      Command for generating index to the contents of an archive; default is "ranlib".

++++ // include:help-build-rock:end

=== luapak merge

// include:help-merge:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak merge [options] MODULE...
       luapak merge --help

Combines multiple Lua modules into a single file. Each module is be wrapped in
a function, or string loaded by "load" (--debug), and assigned to
"package.preload" table.
Arguments:
  MODULE                    Name and path of Lua module delimited with "="
                            (e.g. "luapak.utils=luapak/utils.lua") or just path of module.

Options:
  -g, --debug               Preserve module names and line numbers in error backtraces?
  -o, --output=FILE         Where to write the generated code. Use "-" for stdout. Default is "-".
  -v, --verbose             Be verbose, i.e. print debug messages.
  -h, --help                Display this help message and exit.

++++ // include:help-merge:end

=== luapak minify

// include:help-minify:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak minify [options] [FILE]
       luapak minify --help

Minifies Lua source code - removes comments, unnecessary white spaces and
empty lines, shortens numbers and names of local variables.
Arguments:
  FILE                        Path of the Lua source file, or "-" for stdin.

Options:
  -l, --keep-lno              Do not affect line numbers.
  -n, --keep-names            Do not rename local variables.
  -o, --output=FILE           Where to write the output. Use "-" for stdout. Default is "-".
  -v, --verbose               Be verbose, i.e. print debug messages.
  -h, --help                  Display this help message and exit.

++++ // include:help-minify:end

=== luapak wrapper

// include:help-wrapper:start // This is a generated content, do not edit it! // Note: AsciiDoc supports includes, but it's not enabled on GitHub. ++++

Click here to expand…
Usage: luapak wrapper [options] FILE [MODULE_NAME...]
       luapak wrapper --help

Wraps Lua script into a generated C file that can be compiled and linked with
Lua interpreter and Lua/C native extensions into a standalone executable.
Arguments:
  FILE                        The Lua file to embed into the wrapper.
  MODULE_NAME                 Name of native module to preload (e.g. "cjson").

Options:
  -C, --no-compress           Do not compress FILE using BriefLZ algorithm.
  -o, --output=FILE           Where to write the generated code; "-" for stdout. Default is "-".
  -v, --verbose               Be verbose, i.e. print debug messages.
  -h, --help                  Display this help message and exit.

++++ // include:help-wrapper:end

== What Luapak Is Not?

== Installation

Note: If you want to bootstrap development environment for running tests, read the next section.

=== Using LuaRocks

You can install {proj-name} using https://luarocks.org[LuaRocks] (the Lua package manager):

[source, subs="+attributes"] luarocks install {proj-name}

or to get the latest development version:

[source, subs="+attributes"] luarocks install --server=http://luarocks.org/dev {proj-name}

=== Download Standalone Binary

You can also download standalone Luapak binaries for Linux, macOS and Windows from https://github.com/{gh-name}/releases/[Releases].

Note: Linux binaries are statically linked with http://www.musl-libc.org/[musl libc], so they should work on any Linux system.

== Set Up Development Environment

. Clone this repository: [source, subs="+attributes"] git clone https://github.com/{gh-name}.git cd {proj-name}

. Source file .envrc into your shell (or manually add $(pwd)/.venv/bin to your PATH): [source] source .envrc

. Install Lua and modules for running tests into directory .venv: [source] ./script/bootstrap

. Start hacking!

. Run linters: [source] ./script/test

== TODO

== Similar Projects

Luapak is not the first tool for packing Lua code into standalone executable, but it’s the most complete. Here’s a list of similar projects I know about, some of them served as an inspiration for Luapak.

== License

This project is licensed under http://opensource.org/licenses/MIT/[MIT License]. For the full text of the license, see the link:LICENSE[LICENSE] file.