unimportant

This commit is contained in:
Cosmin Apreutesei
2014-11-13 06:26:25 +02:00
parent 3ff96b0b70
commit bfabb62265
10 changed files with 273 additions and 122 deletions
+83 -69
View File
@@ -1,4 +1,4 @@
# go@ sh bundle.sh -v --alibs "socket_core clipper" --modules "glue socket"
# go@ sh bundle.sh -v -o c:/1/a.exe -a --all
#!/bin/sh
#
# Compile and link together LuaJIT, Lua modules, Lua/C modules, C libraries,
@@ -9,6 +9,7 @@
#
say() { [ "$VERBOSE" ] && echo "$@"; }
verbose() { say "$@"; "$@"; }
# defaults -------------------------------------------------------------------
@@ -16,7 +17,7 @@ EXE_mingw=a.exe
EXE_linux=a.out
EXE_osx=a.out
# note: only the mingw linker is smart to ommit dlibs which no code uses.
# note: only the mingw linker is smart to ommit dlibs that are not used.
DLIBS_mingw="gdi32 msimg32 opengl32 winmm ws2_32"
DLIBS_linux=""
DLIBS_osx=""
@@ -27,44 +28,40 @@ APREFIX_linux=lib
APREFIX_osx=lib
ALIBS="luajit"
MODULES="bundle_loader"
ICON=csrc/bundle/luajit2.ico
# list modules and libs ------------------------------------------------------
# usage: $0 ./dir/file.lua -> file.lua
# note: skips test and demo modules.
# usage: $0 basedir/file.lua|.dasl -> file.lua|.dasl
# note: skips test and demo modules, and other platforms modules.
lua_module() {
local f=$1
local ext=${f##*.}
[ "$ext" != lua ] && return
[ "$ext" != lua -a "$ext" != dasl ] && return
[ "${f%_test.lua}" != $f ] && return
[ "${f%_demo.lua}" != $f ] && return
f=${f:2} # ./a/b.lua -> a/b.lua
[ "${f#bin/}" != $f -a "${f#bin/$P/}" == $f ] && return
echo $f
}
# usage: $0 <dir> -> module1.lua ...
# usage: $0 [dir] -> module1.lua|.dasl ...
# note: skips looking in special dirs.
lua_modules_in() {
for f in $1/*; do
lua_modules() {
for f in $1*; do
if [ -d $f ]; then
[ "${f:2:1}" != "_" \
-a "${f:2:1}" != "." \
-a "${f:2:3}" != bin \
-a "${f:2:4}" != csrc \
-a "${f:2:5}" != media \
[ "${f:0:1}" != "_" \
-a "${f:0:1}" != "." \
-a "${f:0:4}" != csrc \
-a "${f:0:5}" != media \
] && \
lua_modules_in $f
lua_modules $f/
else
lua_module $f
fi
done
}
# usage: $0 -> a/b.lua ...
lua_modules() {
lua_modules_in .
}
# usage: P=<platform> $0 -> lib1 ...
alibs() {
(cd bin/$P &&
@@ -76,76 +73,83 @@ alibs() {
# compiling ------------------------------------------------------------------
# usage: f=<file.lua> o=<file.o> m=<module> $0 CFLAGS... -> file.o
compile_lua_module() {
# we compile with gcc for compatibility with mingw, and also because
# we want to replace the luaJIT_BC_ prefix with luaJIT_BCF_.
# using luaJIT_BCF_ ensures that our loader is used, which runs last.
./luajit -b $f -n $m -t c - | \
sed 's/luaJIT_BC_/luaJIT_BCF_/g' | \
gcc -c -xc - -o $o "$@"
}
# usage: f=<file.c> o=<file.o> $0 CFLAGS... -> file.o
# usage: f=file.c o=file.o $0 CFLAGS... -> file.o
compile_c_module() {
gcc -c $f -o $o "$@"
gcc -c -xc $f -o $o $CFLAGS "$@"
}
set_module_vars() {
f=$1
x=${f##*.} # a/b.lua -> lua
[ "$x" = $f ] && { x=lua; f=$f.lua; }
m=${f%*.*} # a/b.lua -> a/b
m=`echo $m | tr / _` # a/b -> a_b (posix compliant)
o=$ODIR/${x}_$m.o # a_b -> $ODIR/lua_a_b.o
# usage: f='file1.lua ...' o=file.o $0 CFLAGS... -> file.o
compile_lua_module() {
./luajit csrc/bundle/bcfsave.lua $f | f=- compile_c_module "$@"
}
# usage: $0 module1[.lua]|.c CFLAGS...
# usage: f=file.dasl o=file.o $0 CFLAGS... -> file.o
compile_dasl_module() {
./luajit dynasm.lua $f | m=$f f=- compile_lua_module "$@"
}
# usage: osuffix=suffix $0 file[.lua]|.c|.dasl CFLAGS... -> file.o
compile_module() {
set_module_vars $1; shift
local f=$1; shift
local x=${f##*.} # a.lua -> lua
[ "$x" = $f ] && { x=lua; f=$f.lua; }
local o=$ODIR/$f$osuffix.o # a -> $ODIR/a.o
OFILES="$OFILES $o"
[ -f $o -a $o -nt $f ] && return # does it need (re)compiling?
[ -f $o -a $o -nt $f ] && return # does it need (re)compiling?
mkdir -p `dirname $o`
f=$f o=$o compile_${x}_module "$@"
say " $f"
f=$f o=$o m=$m compile_${x}_module $CFLAGS "$@"
}
# usage: $0 <file.c>
# usage: $0 file.c
compile_bundle_module() {
compile_module csrc/bundle/$1 -Icsrc/bundle -Icsrc/luajit/src/src
local f=$1; shift
compile_module csrc/bundle/$f -Icsrc/bundle -Icsrc/luajit/src/src
}
# usage: o=file.o $0
compile_resource() {
OFILES="$OFILES $o"
say " $o"
echo "$s" | windres -o $o
}
# add an icon file for the exe file and main window (Windows only)
# usage: ICON=<file> $0 -> _icon.o
# usage: ICON=file $0 -> _icon.o
compile_icon() {
[ "$OS" = mingw ] || return
rm -f $ODIR/_icon.o
[ "$ICON" ] || return
echo -n "0 ICON \"$ICON\"" | windres -o $ODIR/_icon.o
o=$ODIR/_icon.o s="0 ICON \"$ICON\"" compile_resource
}
# add a manifest file to enable the exe to use comctl 6.0
# usage: $0 -> _manifest.o
compile_manifest() {
[ "$OS" = mingw ] || return
echo "\
s="\
#include \"winuser.h\"
1 RT_MANIFEST bin/mingw32/luajit.exe.manifest
" | windres -o $ODIR/_manifest.o
" o=$ODIR/_manifest.o compile_resource
}
# usage: MODULES=<mod1...> $0 -> $ODIR/*.o
# usage: MODULES='mod1 ...' $0 -> $ODIR/*.o
compile_all() {
say "Compiling modules..."
ODIR=_o/$P
OFILES=""
mkdir -p $ODIR || { echo "Cannot mkdir $ODIR"; exit 1; }
compile_icon # the icon has to be first, believe it!
compile_manifest
for m in $MODULES; do
compile_module $m
done
compile_bundle_module bundle_loaders.c
compile_bundle_module luajit.c
compile_manifest
compile_icon
local osuffix; local copt
[ "$MAIN" ] && {
osuffix=_$MAIN
copt=-DBUNDLE_MAIN=$MAIN
}
osuffix=$osuffix compile_bundle_module bundle.c $copt
}
# linking --------------------------------------------------------------------
@@ -154,8 +158,8 @@ aopt() { for f in $1; do echo "bin/$P/$APREFIX$f.a"; done; }
lopt() { for f in $1; do echo "-l$f"; done; }
fopt() { for f in $1; do echo "-framework $f"; done; }
# usage: P=<platform> ALIBS=<lib1...> DLIBS=<lib1...>
# EXE=<exe_file> NOCONSOLE=1 $0
# usage: P=platform ALIBS='lib1 ...' DLIBS='lib1 ...'
# EXE=exe_file NOCONSOLE=1 $0
link_mingw() {
local mingw_lib_dir
@@ -168,17 +172,17 @@ link_mingw() {
# make a windows app or a console app
local opt; [ "$NOCONSOLE" ] && opt=-mwindows
g++ $opt $CFLAGS $OFILES -o "$EXE" \
verbose g++ $opt $CFLAGS $OFILES -o "$EXE" \
-static -static-libgcc -static-libstdc++ \
-Wl,--enable-stdcall-fixup \
-Wl,--export-all-symbols \
-Lbin/$P \
-Wl,--whole-archive `aopt "$ALIBS"` \
-Wl,--no-whole-archive "$mingw_lib_dir"/libmingw32.a \
-Wl,--no-whole-archive \
"$mingw_lib_dir"/libmingw32.a \
`lopt "$DLIBS"`
}
# usage: P=<platform> ALIBS=<lib1...> DLIBS=<lib1...> EXE=<exe_file>
# usage: P=platform ALIBS='lib1 ...' DLIBS='lib1 ...' EXE=exe_file
link_linux() {
g++ $CFLAGS $OFILES -o "$EXE" \
-static-libgcc -static-libstdc++ \
@@ -189,7 +193,7 @@ link_linux() {
&& chmod +x "$EXE"
}
# usage: P=<platform> ALIBS=<lib1...> DLIBS=<lib1...> EXE=<exe_file>
# usage: P=platform ALIBS='lib1 ...' DLIBS='lib1 ...' EXE=exe_file
link_osx() {
gcc $CFLAGS $OFILES -o "$EXE" \
-stdlib=libstdc++ \
@@ -211,14 +215,16 @@ compress_exe() {
which upx >/dev/null && upx -qqq "$EXE"
}
# usage: P=<platform> MODULES=<mod1...> ALIBS=<lib1...> DLIBS=<lib1...>
# MAIN=<module> EXE=<exe_file> NOCONSOLE=1 ICON=<icon> COMPRESS_EXE=1 $0
# usage: P=platform MODULES='mod1 ...' ALIBS='lib1 ...' DLIBS='lib1 ...'
# MAIN=module EXE=exe_file NOCONSOLE=1 ICON=icon COMPRESS_EXE=1 $0
bundle() {
say "Bundle parameters:"
say " Platform: " "$OS ($P)"
say " Modules: " $MODULES
say " Static libs: " $ALIBS
say " Dynamic libs: " $DLIBS
say " Main module: " $MAIN
say " Icon: " $ICON
compile_all
link_all
compress_exe
@@ -233,8 +239,10 @@ usage() {
echo " -o --output <file> Output executable [$EXE]"
echo
echo " -m --modules \"file1 ...\"|--all Lua (or C) modules to bundle"
echo " -a --alibs \"lib1 ...\"|--all Static libs to bundle [1]"
echo " -a --alibs \"lib1 ...\"|--all Static libs to bundle [1]"
echo " -d --dlibs \"lib1 ...\" Dynamic libs to link against [2]"
[ $OS = osx ] && \
echo " -f --frameworks \"frm1 ...\" Frameworks to link against [3]"
echo
echo " -M --main <module> Module to run on start-up"
#echo " -pl --package.path <spec> Set package.path"
@@ -245,11 +253,15 @@ usage() {
echo
echo " -m32 Force 32bit platform"
echo " -z --compress Compress the executable"
echo " -i --icon <file> Set icon (for Windows and OSX)"
echo " -w --no-console Do not show the terminal / console"
[ $OS = mingw ] && \
echo " -i --icon <file> Set icon"
[ $OS = mingw ] && \
echo " -w --no-console Hide the terminal / console"
echo
echo " [1] default static libs: "$ALIBS
echo " [2] default dynamic libs: "$DLIBS
echo " [1] implicit static libs: "$ALIBS
echo " [2] implicit dynamic libs: "$DLIBS
[ $OS = osx ] && \
echo " [3] implicit frameworks: "$FRAMEWORKS
echo
}
@@ -291,6 +303,8 @@ parse_cmdline() {
;;
-d | --dlibs)
DLIBS="$DLIBS $1"; shift;;
-f | --frameworks)
FRAMEWORKS="$FRAMEWORKS $1"; shift;;
-ll | --list-lua-modules)
lua_modules; exit;;
-la | --list-alibs)
+42
View File
@@ -0,0 +1,42 @@
-- bundle loader module: runs when a luajit bundle starts.
-- returns a "main" function which is called with the args from cmdline.
-- Written by Cosmin Apreutesei. Public domain.
local ffi = require'ffi'
--overload ffi.load to fallback to ffi.C when the lib is not found.
local ffi_load = ffi.load
function ffi.load(...)
local ok, C = pcall(ffi_load, ...)
if not ok then
return ffi.C
else
return C
end
end
--find a module in package.loaders, like require() does.
local function find_module(name)
for _, loader in ipairs(package.loaders) do
local chunk = loader(name)
if type(chunk) == 'function' then
return chunk
end
end
end
return function(...)
local m = arg[-1]
if not m then
return true --no module specified: fallback to luajit frontend
end
m = find_module(m)
if not m then
return true --module not found: fallback to luajit frontend
end
local ok, err = xpcall(m, debug.traceback, ...)
if not ok then
error(err, 2)
end
end
+60
View File
@@ -0,0 +1,60 @@
-- part of bcsave.lua from luajit that outputs a module's bytecode as
-- C code to stdout, with two modifications:
-- 1) the symbol prefix is luaJIT_BCF_ instead of luaJIT_BC_, and
-- 2) the first 4 bytes represent the bytecode size encoded as a int32_t.
local ffi = require'ffi'
local function out(...)
io.stdout:write(...)
end
local function symname(s)
if s=='-' then s = os.getenv'm' end
return s:gsub('[\\%-/%.]', '_'):gsub('%.lua$', '')
end
local function bcout(file)
local code
if file == '-' then --stdin
code = loadstring(io.stdin:read'*a')
else
code = loadfile(file)
end
local s = string.dump(code)
out(string.format([[
#ifdef _cplusplus
extern "C"
#endif
#ifdef _WIN32
__declspec(dllexport)
#endif
const char luaJIT_BCF_%s[] = {
]], symname(file)))
local sz = ffi.new('int32_t[1]', #s)
local psz = ffi.cast('uint8_t*', sz)
for i=3,0,-1 do
s = string.char(psz[i])..s
end
local t, n, m = {}, 0, 0
for i=1,#s do
local b = tostring(string.byte(s, i))
m = m + #b + 1
if m > 78 then
out(table.concat(t, ",", 1, n), ",\n")
n, m = 0, #b + 1
end
n = n + 1
t[n] = b
end
out(table.concat(t, ",", 1, n).."\n};\n")
end
for i=1,select('#', ...) do
bcout(select(i, ...))
end
@@ -1,3 +1,4 @@
//go@ sh run.sh
/*
** Package loaders for bundled Lua and Lua/C modules.
** By Cosmin Apreutesei, no (c) claimed.
@@ -111,8 +112,8 @@ static const char *mksymname(lua_State *L, const char *modname,
static void loaderror(lua_State *L)
{
luaL_error(L, "error loading module " LUA_QS ":\n\t%s",
lua_tostring(L, 1), lua_tostring(L, -1));
luaL_error(L, "error loading module " LUA_QS ":\n\t%s",
lua_tostring(L, 1), lua_tostring(L, -1));
}
/* load a C module bundled in the running executable */
@@ -125,8 +126,10 @@ extern int bundle_loader_c(lua_State *L)
lua_CFunction f = (lua_CFunction)ll_sym(sym);
if (!f) {
lua_pushfstring(L, "\n\tno symbol "LUA_QS, sym);
lua_remove(L, -2); /* remove bcname */
return 1;
}
lua_pop(L, 1);
lua_pushcfunction(L, f);
return 1;
}
@@ -140,9 +143,11 @@ extern int bundle_loader_lua(lua_State *L)
const char *bcdata = (const char *)ll_sym(bcname);
if (bcdata == NULL) {
lua_pushfstring(L, "\n\tno symbol "LUA_QS, bcname);
lua_remove(L, -2); /* remove bcname */
return 1;
}
if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0) {
lua_pop(L, 1); /* remove bcname */
if (luaL_loadbuffer(L, bcdata+4, *((int32_t*)bcdata), name) != 0) {
lua_pushfstring(L, "error loading chunk");
loaderror(L);
}
@@ -154,15 +159,70 @@ extern int bundle_loader_lua(lua_State *L)
/* add our two bundle loaders at the end of package.loaders */
extern void bundle_add_loaders(lua_State* L)
{
int top = lua_gettop(L);
/* push package.loaders table into the stack */
lua_getglobal(L, LUA_LOADLIBNAME); /* get _G.package */
lua_getfield(L, -1, "loaders"); /* get _G.package.loaders */
lua_getglobal(L, LUA_LOADLIBNAME); /* get _G.package */
lua_getfield(L, -1, "loaders"); /* get _G.package.loaders */
lua_pushcclosure(L, bundle_loader_lua, 0); /* push as lua_CFunction */
lua_pushcfunction(L, bundle_loader_lua); /* push as lua_CFunction */
lua_rawseti(L, -2, lua_objlen(L, -2)+1); /* append to loaders table */
lua_pushcclosure(L, bundle_loader_c, 0); /* push as lua_CFunction */
lua_pushcfunction(L, bundle_loader_c); /* push as lua_CFunction */
lua_rawseti(L, -2, lua_objlen(L, -2)+1); /* append to loaders table */
lua_pop(L, 2); /* remove loaders and package tables */
lua_settop(L, top);
}
/* ------------------------------------------------------------------------ */
/* call require("bundle_loader") and if it returns a function, run it
passing it the command line args (also sets _G.arg).
fallback to the luajit frontend if either:
1) bundle_loader module is not found,
2) bundle_loader module returns a true value,
3) the function returned by bundle_loader returns a true value.
*/
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
extern int bundle_main(lua_State *L, int argc, char** argv)
{
int status;
int i;
int top = lua_gettop(L);
lua_getglobal(L, "require");
lua_pushliteral(L, "bundle_loader");
if (lua_pcall(L, 1, 1, 0)) {
const char *msg = lua_tostring(L, -1);
if (msg && !strncmp(msg, "module ", 7)) { /* module not found? */
lua_settop(L, top);
return 1; /* fallback to luajit frontend */
}
lua_error(L);
}
if (lua_isfunction(L, -1)) {
/* create and fill up _G.arg */
lua_createtable(L, argc, 2);
/* add BUNDLE_MAIN to arg[-1] */
#ifdef BUNDLE_MAIN
lua_pushliteral(L, STR(BUNDLE_MAIN));
lua_rawseti(L, -2, -1);
#endif
/* add argv */
for (i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i);
}
lua_setglobal(L, "arg");
/* add varargs */
luaL_checkstack(L, argc - 1, "too many arguments");
for (i = 1; i < argc; i++)
lua_pushstring(L, argv[i]);
lua_call(L, argc-1, 1);
}
/* returning true from the module or from main means fallback to luajit */
status = lua_toboolean(L, -1);
lua_settop(L, top);
return status;
}
@@ -1,3 +1,4 @@
extern int bundle_loader_c(lua_State *L);
extern int bundle_loader_lua(lua_State *L);
extern void bundle_add_loaders(lua_State* L);
extern int bundle_main(lua_State *L, int argc, char** argv);
-18
View File
@@ -1,18 +0,0 @@
-- bundle init module: loaded automaticaly when the luajit bundle starts.
-- Written by Cosmin Apreutesei. Public domain.
local ffi = require'ffi'
--overload ffi.load to fallback on ffi.C where our embedded symbols are.
local ffi_load = ffi.load
function ffi.load(lib, ...)
local ok, clib = pcall(ffi_load, lib, ...)
if not ok then
return ffi.C
else
return clib
end
end
require'bundle_main'
View File
+19 -27
View File
@@ -1,3 +1,4 @@
//go@ sh run.sh
/*
** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc.
** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
@@ -5,7 +6,7 @@
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
**
** Changed by Cosmin Apreutesei to add bundle_loaders (no (c) claimed).
** Modified by Cosmin Apreutesei for luapower.com/bundle project.
*/
#include <stdio.h>
@@ -21,7 +22,7 @@
#include "lj_arch.h"
#include "bundle_loaders.h"
#include "bundle.h"
#if LJ_TARGET_POSIX
#include <unistd.h>
@@ -65,8 +66,9 @@ static void laction(int i)
static void print_usage(void)
{
fprintf(stderr,
"usage: %s [options]... [script [args]...].\n"
fputs("usage: ", stderr);
fputs(progname, stderr);
fputs(" [options]... [script [args]...].\n"
"Available options are:\n"
" -e chunk Execute string " LUA_QL("chunk") ".\n"
" -l name Require library " LUA_QL("name") ".\n"
@@ -77,16 +79,14 @@ static void print_usage(void)
" -v Show version information.\n"
" -E Ignore environment variables.\n"
" -- Stop handling options.\n"
" - Execute stdin and stop handling options.\n"
,
progname);
" - Execute stdin and stop handling options.\n", stderr);
fflush(stderr);
}
static void l_message(const char *pname, const char *msg)
{
if (pname) fprintf(stderr, "%s: ", pname);
fprintf(stderr, "%s\n", msg);
if (pname) { fputs(pname, stderr); fputc(':', stderr); fputc(' ', stderr); }
fputs(msg, stderr); fputc('\n', stderr);
fflush(stderr);
}
@@ -518,6 +518,16 @@ static int pmain(lua_State *L)
globalL = L;
if (argv[0] && argv[0][0]) progname = argv[0];
LUAJIT_VERSION_SYM(); /* linker-enforced version check */
/* load libs early to make require() available */
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, -1);
/* load bundle loaders */
bundle_add_loaders(L);
/* load bundle main routine */
if (!bundle_main(L, s->argc, argv))
return 0;
/* end of bundle extensions */
script = collectargs(argv, &flags);
if (script < 0) { /* invalid args? */
print_usage();
@@ -528,10 +538,6 @@ static int pmain(lua_State *L)
lua_pushboolean(L, 1);
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, -1);
bundle_add_loaders(L);
if (!(flags & FLAGS_NOENV)) {
s->status = handle_luainit(L);
if (s->status != 0) return 0;
@@ -574,17 +580,3 @@ int main(int argc, char **argv)
return (status || smain.status) ? EXIT_FAILURE : EXIT_SUCCESS;
}
/*
// main() wrapper that inserts "-lbundle_init" in argv[1]
int main(int argc, char **argv)
{
char** argv_ = malloc((argc + 1) * sizeof(char*));
if (!argv)
return EXIT_FAILURE;
argv_[0] = argv[0];
argv_[1] = "-lbundle_init";
memcpy(argv_ + 2, argv + 1, (argc - 1) * sizeof(char*));
return _main(argc + 1, argv_);
}
*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB