Rework embedded scripts to be loaded on-demand and by name
This will be required in order to migrate modules into the executable for binary releases
This commit is contained in:
parent
ee305d4ff1
commit
90ae7aaa70
70
premake5.lua
70
premake5.lua
@ -29,6 +29,24 @@
|
||||
-- Register supporting actions and options.
|
||||
--
|
||||
|
||||
newaction {
|
||||
trigger = "embed",
|
||||
description = "Embed scripts in scripts.c; required before release builds",
|
||||
execute = function ()
|
||||
include (path.join(corePath, "scripts/embed.lua"))
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
newaction {
|
||||
trigger = "release",
|
||||
description = "Prepare a new release (incomplete)",
|
||||
execute = function ()
|
||||
include (path.join(corePath, "scripts/release.lua"))
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
newaction {
|
||||
trigger = "test",
|
||||
description = "Run the automated test suite",
|
||||
@ -44,6 +62,13 @@
|
||||
}
|
||||
|
||||
|
||||
newoption {
|
||||
trigger = "to",
|
||||
value = "path",
|
||||
description = "Set the output location for the generated files"
|
||||
}
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Define the project. Put the release configuration first so it will be the
|
||||
@ -134,48 +159,3 @@
|
||||
os.rmdir("bin")
|
||||
os.rmdir("build")
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Use the --to=path option to control where the project files get generated. I use
|
||||
-- this to create project files for each supported toolset, each in their own folder,
|
||||
-- in preparation for deployment.
|
||||
--
|
||||
|
||||
newoption {
|
||||
trigger = "to",
|
||||
value = "path",
|
||||
description = "Set the output location for the generated files"
|
||||
}
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Use the embed action to convert all of the Lua scripts into C strings, which
|
||||
-- can then be built into the executable. Always embed the scripts before creating
|
||||
-- a release build.
|
||||
--
|
||||
|
||||
dofile("scripts/embed.lua")
|
||||
|
||||
newaction {
|
||||
trigger = "embed",
|
||||
description = "Embed scripts in scripts.c; required before release builds",
|
||||
execute = doembed
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
-- Use the release action to prepare source and binary packages for a new release.
|
||||
-- This action isn't complete yet; a release still requires some manual work.
|
||||
--
|
||||
|
||||
|
||||
dofile("scripts/release.lua")
|
||||
|
||||
newaction {
|
||||
trigger = "release",
|
||||
description = "Prepare a new release (incomplete)",
|
||||
execute = dorelease
|
||||
}
|
||||
|
@ -5,10 +5,8 @@
|
||||
-- issues in Mac OS X Universal builds.
|
||||
--
|
||||
|
||||
-- remember where I live, so I can find the files I need
|
||||
local basedir = path.getdirectory(os.getcwd())
|
||||
|
||||
local function stripfile(fname)
|
||||
local function loadScript(fname)
|
||||
local f = io.open(fname)
|
||||
local s = assert(f:read("*a"))
|
||||
f:close()
|
||||
@ -46,9 +44,7 @@
|
||||
end
|
||||
|
||||
|
||||
local function appendfile(result, fname, contents)
|
||||
table.insert(result, "\t/* " .. fname .. " */\n")
|
||||
|
||||
local function appendScript(result, contents)
|
||||
-- break up large strings to fit in Visual Studio's string length limit
|
||||
local max = 4096
|
||||
local start = 1
|
||||
@ -64,62 +60,105 @@
|
||||
end
|
||||
|
||||
local s = contents:sub(start, finish)
|
||||
table.insert(result, "\t\"" .. s .. iif(finish < len, "\"\n", "\",\n"))
|
||||
table.insert(result, "\t\"" .. s .. iif(finish < len, '"', '",'))
|
||||
|
||||
start = finish + 1
|
||||
end
|
||||
|
||||
table.insert(result, "\n")
|
||||
table.insert(result, "")
|
||||
end
|
||||
|
||||
|
||||
function doembed()
|
||||
|
||||
-- Find and run the manifest file. Checks the normal search paths to
|
||||
-- allow for manifest and _premake_main customizations, then falls
|
||||
-- back to the canonical version at ../src if not found.
|
||||
-- Prepare the file header
|
||||
|
||||
local dir = os.pathsearch("_manifest.lua", _OPTIONS["scripts"], os.getenv("PREMAKE_PATH"))
|
||||
if not dir then
|
||||
dir = path.join(basedir, "src")
|
||||
end
|
||||
local result = {}
|
||||
table.insert(result, "/* Premake's Lua scripts, as static data buffers for release mode builds */")
|
||||
table.insert(result, "/* DO NOT EDIT - this file is autogenerated - see BUILD.txt */")
|
||||
table.insert(result, "/* To regenerate this file, run: premake5 embed */")
|
||||
table.insert(result, "")
|
||||
table.insert(result, '#include "premake.h"')
|
||||
table.insert(result, "")
|
||||
|
||||
scripts = dofile(path.join(dir, "_manifest.lua"))
|
||||
|
||||
-- Main script always goes first
|
||||
table.insert(scripts, 1, "_premake_main.lua")
|
||||
-- Find all of the _manifest.lua files within the project
|
||||
|
||||
-- Convert all scripts to single in-memory string
|
||||
local result = {}
|
||||
table.insert(result, "/* Premake's Lua scripts, as static data buffers for release mode builds */\n")
|
||||
table.insert(result, "/* DO NOT EDIT - this file is autogenerated - see BUILD.txt */\n")
|
||||
table.insert(result, "/* To regenerate this file, run: premake5 embed */ \n\n")
|
||||
table.insert(result, "const char* builtin_scripts[] = {\n")
|
||||
local mask = path.join(_MAIN_SCRIPT_DIR, "**/_manifest.lua")
|
||||
local manifests = os.matchfiles(mask)
|
||||
|
||||
for i, fn in ipairs(scripts) do
|
||||
local s = stripfile(path.join(dir, fn))
|
||||
appendfile(result, fn, s)
|
||||
end
|
||||
|
||||
table.insert(result, "\t0\n};\n");
|
||||
result = table.concat(result)
|
||||
-- Generate an index of the script file names. Script names are stored
|
||||
-- relative to the directory containing the manifest, i.e. the main
|
||||
-- Xcode script, which is at $/modules/xcode/xcode.lua is stored as
|
||||
-- "xcode/xcode.lua". Core scripts currently get special treatment and
|
||||
-- are stored as "base/os.lua" instead of "core/base/os.lua"; I would
|
||||
-- like to treat core like just another module eventually.
|
||||
|
||||
-- Compare it to the current contents of scripts.c; only write out
|
||||
-- a new scripts.c if there have been changes
|
||||
table.insert(result, "const char* builtin_scripts_index[] = {")
|
||||
|
||||
local oldVersion
|
||||
local scriptsFile = path.join(basedir, "src/host/scripts.c")
|
||||
for mi = 1, #manifests do
|
||||
local manifestName = manifests[mi]
|
||||
local manifestDir = path.getdirectory(manifestName)
|
||||
local baseDir = path.getdirectory(manifestDir)
|
||||
|
||||
local file = io.open(scriptsFile, "r")
|
||||
if file then
|
||||
oldVersion = file:read("*a")
|
||||
file:close()
|
||||
end
|
||||
local files = dofile(manifests[mi])
|
||||
for fi = 1, #files do
|
||||
local filename = path.join(manifestDir, files[fi])
|
||||
filename = path.getrelative(baseDir, filename)
|
||||
|
||||
if oldVersion ~= result then
|
||||
print("Writing scripts.c")
|
||||
file = io.open(scriptsFile, "w+b")
|
||||
file:write(result)
|
||||
file:close()
|
||||
-- core files fix-up for backward compatibility
|
||||
if filename:startswith("src/") then
|
||||
filename = filename:sub(5)
|
||||
end
|
||||
|
||||
table.insert(result, '\t"' .. filename .. '",')
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(result, "\tNULL")
|
||||
table.insert(result, "};")
|
||||
table.insert(result, "")
|
||||
|
||||
|
||||
-- Embed the actual script contents
|
||||
|
||||
table.insert(result, "const char* builtin_scripts[] = {")
|
||||
|
||||
for mi = 1, #manifests do
|
||||
local manifestName = manifests[mi]
|
||||
local manifestDir = path.getdirectory(manifestName)
|
||||
|
||||
local files = dofile(manifests[mi])
|
||||
for fi = 1, #files do
|
||||
local filename = path.join(manifestDir, files[fi])
|
||||
|
||||
local scr = loadScript(filename)
|
||||
appendScript(result, scr)
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(result, "\tNULL")
|
||||
table.insert(result, "};")
|
||||
table.insert(result, "")
|
||||
|
||||
|
||||
-- Write it all out. Check against the current contents of scripts.c first,
|
||||
-- and only overwrite it if there are actual changes.
|
||||
|
||||
result = table.concat(result, "\n")
|
||||
|
||||
local scriptsFile = path.getabsolute(path.join(_SCRIPT_DIR, "../src/host/scripts.c"))
|
||||
|
||||
local oldVersion
|
||||
local file = io.open(scriptsFile, "r")
|
||||
if file then
|
||||
oldVersion = file:read("*a")
|
||||
file:close()
|
||||
end
|
||||
|
||||
if oldVersion ~= result then
|
||||
print("Writing scripts.c")
|
||||
file = io.open(scriptsFile, "w+b")
|
||||
file:write(result)
|
||||
file:close()
|
||||
end
|
||||
|
@ -15,11 +15,11 @@
|
||||
-- Find and load all of the test file manifests
|
||||
--
|
||||
|
||||
local mask = path.join(_MAIN_SCRIPT_DIR, "**/tests/_manifest.lua")
|
||||
local mask = path.join(_MAIN_SCRIPT_DIR, "**/tests/_tests.lua")
|
||||
local manifests = os.matchfiles(mask)
|
||||
|
||||
-- Hmm, "**" should probably also match against "."?
|
||||
local top = path.join(_MAIN_SCRIPT_DIR, "tests/_manifest.lua")
|
||||
local top = path.join(_MAIN_SCRIPT_DIR, "tests/_tests.lua")
|
||||
if os.isfile(top) then
|
||||
table.insert(manifests, 1, top)
|
||||
end
|
||||
|
@ -8,6 +8,14 @@
|
||||
local versionhelp = "premake5 (Premake Build Script Generator) %s"
|
||||
|
||||
|
||||
-- Load the collection of core scripts, required for everything else to work
|
||||
|
||||
local manifest = dofile("_manifest.lua")
|
||||
for i = 1, #manifest do
|
||||
dofile(manifest[i])
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Script-side program entry point.
|
||||
--
|
||||
|
@ -5,22 +5,6 @@
|
||||
--
|
||||
|
||||
|
||||
---
|
||||
-- A replacement for Lua's built-in dofile() function that knows how to
|
||||
-- search for script files. Note that I've also modified luaL_loadfile()
|
||||
-- in src/host/lua_auxlib.c to set the _SCRIPT variable and adjust the
|
||||
-- working directory.
|
||||
---
|
||||
|
||||
local builtin_dofile = dofile
|
||||
|
||||
function dofile(fname)
|
||||
fname = os.locate(fname) or fname
|
||||
return builtin_dofile(fname)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Find and execute a Lua source file present on the filesystem, but
|
||||
-- continue without error if the file is not present. This is used to
|
||||
|
@ -207,43 +207,6 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Locate a file on one of Premake's search paths: 1) the --script command
|
||||
-- line argument, 2) the PREMAKE_PATH environment variable, 3) relative to
|
||||
-- the Premake executable.
|
||||
--
|
||||
-- @param ...
|
||||
-- A list of file names for which to search. The first one discovered
|
||||
-- is the one that will be returned.
|
||||
-- @return
|
||||
-- The path to file if found, or nil if not.
|
||||
---
|
||||
|
||||
function os.locate(...)
|
||||
local function find(fname)
|
||||
-- is this a direct path to a file?
|
||||
if os.isfile(fname) then
|
||||
return fname
|
||||
end
|
||||
|
||||
-- find it on my paths
|
||||
local dir = os.pathsearch(fname, _OPTIONS["scripts"], os.getenv("PREMAKE_PATH"), path.getdirectory(_PREMAKE_COMMAND))
|
||||
if dir then
|
||||
return path.join(dir, fname)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, select("#",...) do
|
||||
local fname = select(i, ...)
|
||||
local result = find(fname)
|
||||
if result then
|
||||
return result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Perform a wildcard search for files or directories.
|
||||
--
|
||||
|
@ -7,19 +7,72 @@
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
static int chunk_wrapper(lua_State* L);
|
||||
|
||||
|
||||
|
||||
/* Pull in Lua's aux lib implementation, but rename luaL_loadfile() so I
|
||||
* can replace it with my own implementation. */
|
||||
|
||||
#define luaL_loadfile original_luaL_loadfile
|
||||
|
||||
#include "lua-5.1.4/src/lauxlib.c"
|
||||
|
||||
#undef luaL_loadfile
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute a chunk of code previous loaded by my customized version of
|
||||
* luaL_loadfile(), below. Sets the _SCRIPT global variable to the
|
||||
* absolute path of the loaded chunk, and makes its enclosing directory
|
||||
* current so that relative path references to other files or scripts
|
||||
* can be used.
|
||||
* Extend the default implementation of luaL_loadfile() to call my chunk
|
||||
* wrapper, above, before executing any scripts loaded from a file.
|
||||
*/
|
||||
|
||||
LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
|
||||
{
|
||||
int z;
|
||||
|
||||
/* try to locate the script on the filesystem */
|
||||
|
||||
if (do_isfile(filename)) {
|
||||
lua_pushstring(L, filename);
|
||||
}
|
||||
else {
|
||||
lua_pushcfunction(L, os_pathsearch);
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushstring(L, scripts_path);
|
||||
lua_pushstring(L, getenv("PREMAKE_PATH"));
|
||||
lua_call(L, 3, 1);
|
||||
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!lua_isnil(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
z = original_luaL_loadfile(L, lua_tostring(L, -1));
|
||||
lua_remove(L, i);
|
||||
}
|
||||
else {
|
||||
lua_pop(L, 1);
|
||||
z = premake_load_embedded_script(L, filename);
|
||||
}
|
||||
|
||||
if (z == OKAY) {
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushcclosure(L, chunk_wrapper, 2);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute a chunk of code previously loaded by my customized version of
|
||||
* luaL_loadfile(), below. Sets the _SCRIPT global variable to the absolute
|
||||
* path of the loaded chunk, and makes its enclosing directory current so
|
||||
* that relative path references to other files or scripts can be used.
|
||||
*/
|
||||
|
||||
static int chunk_wrapper(lua_State* L)
|
||||
@ -33,10 +86,11 @@ static int chunk_wrapper(lua_State* L)
|
||||
args = lua_gettop(L);
|
||||
|
||||
/* Remember the current _SCRIPT and working directory so I can
|
||||
* restore them after the script chunk has been run. */
|
||||
* restore them after this new chunk has been run. */
|
||||
|
||||
do_getcwd(cwd, PATH_MAX);
|
||||
lua_getglobal(L, "_SCRIPT");
|
||||
lua_getglobal(L, "_SCRIPT_DIR");
|
||||
|
||||
/* Set the new _SCRIPT variable... */
|
||||
|
||||
@ -70,24 +124,8 @@ static int chunk_wrapper(lua_State* L)
|
||||
do_chdir(cwd);
|
||||
lua_pushvalue(L, args + 1);
|
||||
lua_setglobal(L, "_SCRIPT");
|
||||
lua_pushvalue(L, args + 2);
|
||||
lua_setglobal(L, "_SCRIPT_DIR");
|
||||
|
||||
return lua_gettop(L) - args - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extend the default implementation of luaL_loadfile() to call my chunk
|
||||
* wrapper, above, before executing any scripts loaded from a file.
|
||||
*/
|
||||
|
||||
LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
|
||||
{
|
||||
int z = original_luaL_loadfile(L, filename);
|
||||
if (z == 0) {
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushcclosure(L, chunk_wrapper, 2);
|
||||
}
|
||||
|
||||
return z;
|
||||
return lua_gettop(L) - args - 2;
|
||||
}
|
||||
|
42
src/host/os_locate.c
Normal file
42
src/host/os_locate.c
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* \file os_locate.c
|
||||
* \brief Locates a file, given a set of search paths.
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int os_locate(lua_State* L)
|
||||
{
|
||||
int i, top;
|
||||
const char* premake_path = getenv("PREMAKE_PATH");
|
||||
|
||||
top = lua_gettop(L);
|
||||
for (i = 1; i <= top; ++i) {
|
||||
/* direct path to file? */
|
||||
if (do_isfile(lua_tostring(L, i))) {
|
||||
lua_pushvalue(L, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* search for it */
|
||||
lua_pushcfunction(L, os_pathsearch);
|
||||
lua_pushvalue(L, i);
|
||||
lua_getglobal(L, "_MAIN_SCRIPT_DIR");
|
||||
lua_pushstring(L, scripts_path);
|
||||
lua_pushstring(L, premake_path);
|
||||
lua_call(L, 4, 1);
|
||||
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_pushcfunction(L, path_join);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, i);
|
||||
lua_call(L, 2, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -17,21 +17,14 @@
|
||||
#define VERSION "HEAD"
|
||||
#define COPYRIGHT "Copyright (C) 2002-2014 Jason Perkins and the Premake Project"
|
||||
#define PROJECT_URL "https://bitbucket.org/premake/premake-dev/wiki"
|
||||
#define ERROR_MESSAGE "%s\n"
|
||||
#define ERROR_MESSAGE "Error: %s\n"
|
||||
|
||||
|
||||
static int process_arguments(lua_State* L, int argc, const char** argv);
|
||||
static int load_builtin_scripts(lua_State* L);
|
||||
|
||||
int premake_locate(lua_State* L, const char* argv0);
|
||||
|
||||
|
||||
/* A search path for script files */
|
||||
static const char* scripts_path = NULL;
|
||||
|
||||
|
||||
/* precompiled bytecode buffer; in bytecode.c */
|
||||
extern const char* builtin_scripts[];
|
||||
const char* scripts_path = NULL;
|
||||
|
||||
|
||||
/* Built-in functions */
|
||||
@ -67,6 +60,7 @@ static const luaL_Reg os_functions[] = {
|
||||
{ "getversion", os_getversion },
|
||||
{ "isfile", os_isfile },
|
||||
{ "islink", os_islink },
|
||||
{ "locate", os_locate },
|
||||
{ "matchdone", os_matchdone },
|
||||
{ "matchisfile", os_matchisfile },
|
||||
{ "matchname", os_matchname },
|
||||
@ -127,8 +121,6 @@ int premake_init(lua_State* L)
|
||||
|
||||
int premake_execute(lua_State* L, int argc, const char** argv)
|
||||
{
|
||||
int z;
|
||||
|
||||
/* push the absolute path to the Premake executable */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
premake_locate(L, argv[0]);
|
||||
@ -136,15 +128,31 @@ int premake_execute(lua_State* L, int argc, const char** argv)
|
||||
lua_setglobal(L, "_PREMAKE_COMMAND");
|
||||
|
||||
/* Parse the command line arguments */
|
||||
z = process_arguments(L, argc, argv);
|
||||
if (process_arguments(L, argc, argv) != OKAY) {
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* Run the built-in Premake scripts */
|
||||
if (z == OKAY) z = load_builtin_scripts(L);
|
||||
/* load the main script */
|
||||
if (luaL_dofile(L, "_premake_main.lua") != OKAY) {
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
return z;
|
||||
/* and call the main entry point */
|
||||
lua_getglobal(L, "_premake_main");
|
||||
if (lua_pcall(L, 0, 1, 0) != OKAY) {
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
else {
|
||||
return (int)lua_tonumber(L, -1);
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Locate the Premake executable, and push its full path to the Lua stack.
|
||||
* Based on:
|
||||
@ -264,112 +272,34 @@ int process_arguments(lua_State* L, int argc, const char** argv)
|
||||
|
||||
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
/**
|
||||
* When running in debug mode, the scripts are loaded from the disk. The path to
|
||||
* the scripts must be provided via either the /scripts command line option or
|
||||
* the PREMAKE_PATH environment variable.
|
||||
* Load a script that was previously embedded into the executable. If
|
||||
* successful, a function containing the new script chunk is pushed to
|
||||
* the stack, just like luaL_loadfile would do had the chunk been loaded
|
||||
* from a file.
|
||||
*/
|
||||
int load_builtin_scripts(lua_State* L)
|
||||
{
|
||||
const char* filename;
|
||||
|
||||
/* call os.pathsearch() to locate _premake_main.lua */
|
||||
lua_pushcfunction(L, os_pathsearch);
|
||||
lua_pushstring(L, "_premake_main.lua");
|
||||
lua_pushstring(L, scripts_path);
|
||||
lua_pushstring(L, getenv("PREMAKE_PATH"));
|
||||
lua_call(L, 3, 1);
|
||||
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
printf(ERROR_MESSAGE,
|
||||
"Unable to find _premake_main.lua; use /scripts option when in debug mode!\n"
|
||||
"Please refer to the documentation (or build in release mode instead)."
|
||||
);
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* set the _SCRIPTS variable for the manifest, so it can locate everything */
|
||||
scripts_path = lua_tostring(L, -1);
|
||||
filename = lua_pushfstring(L, "%s/_manifest.lua", scripts_path);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "_SCRIPT");
|
||||
|
||||
/* load the manifest, which includes all the required scripts */
|
||||
if (luaL_dofile(L, filename))
|
||||
{
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2))
|
||||
{
|
||||
filename = lua_pushfstring(L, "%s/%s", scripts_path, lua_tostring(L, -1));
|
||||
if (luaL_dofile(L, filename)) {
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* run the bootstrapping script */
|
||||
filename = lua_pushfstring(L, "%s/_premake_main.lua", scripts_path);
|
||||
if (luaL_dofile(L, filename))
|
||||
{
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* in debug mode, show full traceback on all errors */
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
|
||||
/* hand off control to the scripts */
|
||||
lua_getglobal(L, "_premake_main");
|
||||
if (lua_pcall(L, 0, 1, -2) != OKAY)
|
||||
{
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)lua_tonumber(L, -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(NDEBUG)
|
||||
/**
|
||||
* When running in release mode, the scripts are loaded from a static data
|
||||
* buffer, where they were stored by a preprocess. To update these embedded
|
||||
* scripts, run `premake5 embed` then rebuild.
|
||||
*/
|
||||
int load_builtin_scripts(lua_State* L)
|
||||
|
||||
int premake_load_embedded_script(lua_State* L, const char* filename)
|
||||
{
|
||||
/* locate a record matching the filename */
|
||||
int i;
|
||||
for (i = 0; builtin_scripts[i]; ++i)
|
||||
{
|
||||
if (luaL_dostring(L, builtin_scripts[i]) != OKAY)
|
||||
{
|
||||
for (i = 0; builtin_scripts_index[i] != NULL; ++i) {
|
||||
if (strcmp(builtin_scripts_index[i], filename) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* load its script */
|
||||
if (builtin_scripts_index[i] != NULL) {
|
||||
const char* chunk = builtin_scripts[i];
|
||||
if (luaL_loadbuffer(L, chunk, strlen(chunk), filename) == OKAY) {
|
||||
return OKAY;
|
||||
}
|
||||
else {
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
/* hand off control to the scripts */
|
||||
lua_getglobal(L, "_premake_main");
|
||||
if (lua_pcall(L, 0, 1, 0) != OKAY)
|
||||
{
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)lua_tonumber(L, -1);
|
||||
}
|
||||
return !OKAY;
|
||||
}
|
||||
#endif
|
||||
|
@ -60,6 +60,10 @@
|
||||
#define OKAY (0)
|
||||
|
||||
|
||||
/* If a /scripts argument is present, its value */
|
||||
extern const char* scripts_path;
|
||||
|
||||
|
||||
/* Bootstrapping helper functions */
|
||||
int do_chdir(const char* path);
|
||||
unsigned long do_hash(const char* str, int seed);
|
||||
@ -91,6 +95,7 @@ int os_is64bit(lua_State* L);
|
||||
int os_isdir(lua_State* L);
|
||||
int os_isfile(lua_State* L);
|
||||
int os_islink(lua_State* L);
|
||||
int os_locate(lua_State* L);
|
||||
int os_matchdone(lua_State* L);
|
||||
int os_matchisfile(lua_State* L);
|
||||
int os_matchname(lua_State* L);
|
||||
@ -110,3 +115,9 @@ int string_startswith(lua_State* L);
|
||||
int premake_init(lua_State* L);
|
||||
int premake_locate(lua_State* L, const char* argv0);
|
||||
int premake_execute(lua_State* L, int argc, const char** argv);
|
||||
int premake_find_exe(lua_State* L, const char* argv0);
|
||||
int premake_load_embedded_script(lua_State* L, const char* filename);
|
||||
|
||||
|
||||
extern const char* builtin_scripts_index[];
|
||||
extern const char* builtin_scripts[];
|
||||
|
@ -1,6 +1,5 @@
|
||||
return {
|
||||
-- Base API tests
|
||||
"test_dofile.lua",
|
||||
"test_string.lua",
|
||||
"base/test_configset.lua",
|
||||
"base/test_context.lua",
|
@ -42,7 +42,7 @@
|
||||
--
|
||||
|
||||
function suite.isfile_ReturnsTrue_OnExistingFile()
|
||||
test.istrue(os.isfile("_manifest.lua"))
|
||||
test.istrue(os.isfile("_tests.lua"))
|
||||
end
|
||||
|
||||
function suite.isfile_ReturnsFalse_OnNonexistantFile()
|
||||
@ -120,13 +120,13 @@
|
||||
end
|
||||
|
||||
function suite.pathsearch_ReturnsPath_OnFound()
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_manifest.lua", _TESTS_DIR))
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", _TESTS_DIR))
|
||||
end
|
||||
|
||||
function suite.pathsearch_FindsFile_OnComplexPath()
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_manifest.lua", "aaa;" .. _TESTS_DIR .. ";bbb"))
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", "aaa;" .. _TESTS_DIR .. ";bbb"))
|
||||
end
|
||||
|
||||
function suite.pathsearch_NilPathsAllowed()
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_manifest.lua", nil, _TESTS_DIR, nil))
|
||||
test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", nil, _TESTS_DIR, nil))
|
||||
end
|
||||
|
@ -1,33 +0,0 @@
|
||||
--
|
||||
-- tests/test_dofile.lua
|
||||
-- Automated test suite for the extended dofile() functions.
|
||||
-- Copyright (c) 2008, 2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
local suite = test.declare("do_file")
|
||||
|
||||
|
||||
local os_getenv
|
||||
|
||||
function suite.setup()
|
||||
os_getenv = os.getenv
|
||||
end
|
||||
|
||||
function suite.teardown()
|
||||
os.getenv = os_getenv
|
||||
end
|
||||
|
||||
|
||||
|
||||
function suite.searchesPath()
|
||||
os.getenv = function() return _TESTS_DIR .. "/folder" end
|
||||
result = dofile("ok.lua")
|
||||
test.isequal("ok", result)
|
||||
end
|
||||
|
||||
function suite.searchesScriptsOption()
|
||||
_OPTIONS["scripts"] = _TESTS_DIR .. "/folder"
|
||||
result = dofile("ok.lua")
|
||||
test.isequal("ok", result)
|
||||
end
|
Loading…
Reference in New Issue
Block a user