mirror of
https://github.com/vxcontrol/lualibs-bundle.git
synced 2026-07-01 08:51:04 -04:00
unimportant
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user