unimportant

This commit is contained in:
Cosmin Apreutesei
2019-10-27 23:36:46 +02:00
parent 67d9bd4822
commit f62aaeb871
2 changed files with 31 additions and 21 deletions
+16 -8
View File
@@ -125,22 +125,30 @@ The standard LuaJIT frontend, slightly modified to run stuff from `bundle.c`.
The bundle loader (C part):
* installs require() loaders on startup for loading embedded Lua
* installs `require()` loaders on startup for loading embedded Lua
and C modules
* fills `_G.arg` with command-line args
* fills `_G.arg` with the command-line args
* sets `_G.arg[-1]` to the name of the main script (`-M` option)
* calls `require'bundle_loader'`
* (which means bundle_loader itself can be upgraded without a rebuild)
* calls `require'bundle_loader'`, which means bundle_loader itself can be
upgraded without a rebuild.
#### bundle_loader.lua
The bundle loader (Lua part):
* sets `package.path` and `package.cpath` to load modules relative
to the exe's dir
* overrides `ffi.load` to return `ffi.C` when a library is not found
* sets `package.path` and `package.cpath` to only load modules relative
to the exe's dir and not look into the current directory.
* overrides `ffi.load` to return `ffi.C` when a library is not found.
* loads the main module, if any, per `arg[-1]`
* falls back to LuaJIT REPL if there's no main module
* falls back to LuaJIT REPL if there's no main module.
One subtle point about `ffi.load` is that if a library was found in a system
path but that library is also bundled, the bundled one will be used instead.
So the search order is:
1. external shared library in the directory of the executable.
2. bundled library inside the executable.
3. external shared library in the system's search path.
#### bundle.lua
+15 -13
View File
@@ -8,17 +8,22 @@ local ffi = require'ffi'
return function(...)
local function S(s)
return ffi.abi'win' and s:gsub('/', '\\') or s
end
--remove current directory and luapower's dir (../..) from search paths.
--keep only $exedir/lua and $exedir/clib.
local function strip(s)
return s
:gsub('^%.[\\/][^;]+;', '') --remove current dir
:gsub(';%.[\\/][^;]+', '') --remove current dir
:gsub('[^;]-[\\/]%.%.[\\/]%.%.[^;]+;', '') --remove luapower dir
:gsub(';[^;]-[\\/]%.%.[\\/]%.%.[^;]+', '') --remove luapower dir
:gsub(S'^%./[^;]+;', '') --remove current dir
:gsub(S';[^;]-/%.%./%.%.[^;]+', '') --remove luapower dir
end
package.path = strip(package.path)
package.cpath = strip(package.cpath)
print(package.path)
print(package.cpath)
local exedir = package.path:match(S'^(.-)/lua/%?%.lua;')
local so_ext = package.cpath:match'%.([%w]+);'
local rel_path
if ffi.os == 'Windows' then
@@ -33,8 +38,8 @@ return function(...)
local function in_exe_dir(name)
if rel_path(name) then
local filename = name:find('%.'..ext..'$') and name or name..'.'..ext
local filepath = dir..'/'..filename
local filename = name:find('%.'..so_ext..'$') and name or name..'.'..so_ext
local filepath = exedir..'/'..filename
local f = io.open(filepath, 'rb')
if f then
f:close()
@@ -49,21 +54,18 @@ return function(...)
for lib in libs_str:gmatch'[^%s]+' do
libs[lib] = true
end
local function bundled(name)
return libs[name] or false
end
--overload ffi.load to fallback to ffi.C for bundled libs.
local ffi_load = ffi.load
function ffi.load(name, ...)
local ok, C = xpcall(ffi_load, debug.traceback, name, ...)
if not ok then
if bundled(name) then
if libs[name] then
return ffi.C
else
error(C, 2)
end
elseif bundled(name) and not in_exe_dir(name) then
elseif libs[name] and not in_exe_dir(name) then
--prevent loading bundled libs from system paths
return ffi.C
else