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 LuaRocks.
Lua/C modules (aka native extensions) are built as static libraries (.a archive files), so they can be statically linked into resulting executable.[1]
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 LuaSrcDiet.
Compresses the Lua script using 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 Commands.
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".
luapak analyse-deps
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.
luapak build-rock
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".
luapak merge
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.
luapak minify
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.
luapak wrapper
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.
What Luapak Is Not?
Luapak is not a transpiler from Lua to C, nor compiler to a native code.
It does not save you from runtime errors in your Lua code, nor increase its performance.
Installation
Note: If you want to bootstrap development environment for running tests, read the next section.
Using LuaRocks
You can install luapak using LuaRocks (the Lua package manager):
You can also download standalone Luapak binaries for Linux, macOS and Windows from Releases.
Note: Linux binaries are statically linked with musl libc, so they should work on any Linux system.
Set Up Development Environment
Clone this repository:
git clone https://github.com/jirutka/luapak.git
cd luapak
Source file .envrc into your shell (or manually add $(pwd)/.venv/bin to your PATH):
source .envrc
Install Lua and modules for running tests into directory .venv:
./script/bootstrap
Start hacking!
Run linters:
./script/test
TODO
Write documentation into README.
Write integration tests.
Analyse usage of Lua standard modules and exclude unused from the binary.
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.
This project is licensed under MIT License.
For the full text of the license, see the LICENSE file.
1. Luapak includes LuaRocks package manager with rewritten 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.
请发表评论