Merge script path searching restrictions for release builds and user project scripts
This commit is contained in:
commit
5e51b54c3d
@ -28,6 +28,7 @@
|
||||
|
||||
p.main.elements = function()
|
||||
return {
|
||||
p.main.locateUserScript,
|
||||
p.main.installModuleLoader,
|
||||
}
|
||||
end
|
||||
@ -48,14 +49,6 @@
|
||||
_PREMAKE_DIR = path.getdirectory(_PREMAKE_COMMAND)
|
||||
premake.path = premake.path .. ";" .. _PREMAKE_DIR
|
||||
|
||||
local file = _OPTIONS["file"] or "premake5.lua"
|
||||
_MAIN_SCRIPT = os.locate(file, file .. ".lua", "premake4.lua")
|
||||
if _MAIN_SCRIPT then
|
||||
_MAIN_SCRIPT_DIR = path.getdirectory(_MAIN_SCRIPT)
|
||||
else
|
||||
_MAIN_SCRIPT_DIR = _WORKING_DIR
|
||||
end
|
||||
|
||||
p.callArray(p.main.elements)
|
||||
|
||||
-- Look for and run the system-wide configuration script; make sure any
|
||||
@ -79,7 +72,7 @@
|
||||
-- If there is a project script available, run it to get the
|
||||
-- project information, available options and actions, etc.
|
||||
|
||||
if _MAIN_SCRIPT then
|
||||
if os.isfile(_MAIN_SCRIPT) then
|
||||
dofile(_MAIN_SCRIPT)
|
||||
end
|
||||
|
||||
@ -119,8 +112,8 @@
|
||||
return 1
|
||||
end
|
||||
|
||||
if not _MAIN_SCRIPT then
|
||||
print("No Premake script (premake5.lua) found!")
|
||||
if not os.isfile(_MAIN_SCRIPT) then
|
||||
print(string.format("No Premake script (%s) found!", path.getname(_MAIN_SCRIPT)))
|
||||
return 1
|
||||
end
|
||||
end
|
||||
@ -153,6 +146,34 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Look for a user project script, and set up the related global
|
||||
-- variables if I can find one.
|
||||
---
|
||||
|
||||
function p.main.locateUserScript()
|
||||
local defaults = { "premake5.lua", "premake4.lua" }
|
||||
for i = 1, #defaults do
|
||||
if os.isfile(defaults[i]) then
|
||||
_MAIN_SCRIPT = defaults[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not _MAIN_SCRIPT then
|
||||
_MAIN_SCRIPT = defaults[1]
|
||||
end
|
||||
|
||||
if _OPTIONS.file then
|
||||
_MAIN_SCRIPT = _OPTIONS.file
|
||||
end
|
||||
|
||||
_MAIN_SCRIPT = path.getabsolute(_MAIN_SCRIPT)
|
||||
_MAIN_SCRIPT_DIR = path.getdirectory(_MAIN_SCRIPT)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Add a new module loader that knows how to use the Premake paths like
|
||||
-- PREMAKE_PATH and the --scripts option, and follows the module/module.lua
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file lua_auxlib.c
|
||||
* \brief Modifications and extensions to Lua's library functions.
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
* \author Copyright (c) 2014-2015 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
@ -33,29 +33,38 @@ LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
|
||||
int bottom = lua_gettop(L);
|
||||
int z = !OKAY;
|
||||
|
||||
/* If the currently running script was embedded, try to load this file
|
||||
* as it if were embedded too. */
|
||||
lua_getglobal(L, "_SCRIPT_DIR");
|
||||
script_dir = lua_tostring(L, -1);
|
||||
|
||||
if (script_dir && script_dir[0] == '$') {
|
||||
/* Call `path.getabsolute(filename, _SCRIPT_DIR)` to resolve any
|
||||
* "../" sequences in the filename */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_call(L, 2, 1);
|
||||
test_name = lua_tostring(L, -1);
|
||||
|
||||
/* if successful, filename and chunk will be on top of stack */
|
||||
z = premake_load_embedded_script(L, test_name + 2); /* Skip over leading "$/" */
|
||||
|
||||
/* remove test_name */
|
||||
lua_remove(L, bottom + 1);
|
||||
/* If filename is starts with "$/" then we want to load the version that
|
||||
* was embedded into the executable and skip the local file system */
|
||||
if (filename[0] == '$') {
|
||||
z = premake_load_embedded_script(L, filename + 2); /* Skip over leading "$/" */
|
||||
if (z != OKAY) return z;
|
||||
}
|
||||
|
||||
/* remove _SCRIPT_DIR */
|
||||
lua_remove(L, bottom);
|
||||
/* If the currently running script was embedded, try to load this file
|
||||
* as it if were embedded too. */
|
||||
if (z != OKAY) {
|
||||
lua_getglobal(L, "_SCRIPT_DIR");
|
||||
script_dir = lua_tostring(L, -1);
|
||||
|
||||
if (script_dir && script_dir[0] == '$') {
|
||||
/* Call `path.getabsolute(filename, _SCRIPT_DIR)` to resolve any
|
||||
* "../" sequences in the filename */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_call(L, 2, 1);
|
||||
test_name = lua_tostring(L, -1);
|
||||
|
||||
/* if successful, filename and chunk will be on top of stack */
|
||||
z = premake_load_embedded_script(L, test_name + 2); /* Skip over leading "$/" */
|
||||
|
||||
/* remove test_name */
|
||||
lua_remove(L, bottom + 1);
|
||||
}
|
||||
|
||||
/* remove _SCRIPT_DIR */
|
||||
lua_remove(L, bottom);
|
||||
}
|
||||
|
||||
/* Try to locate the script on the filesystem */
|
||||
if (z != OKAY) {
|
||||
|
@ -8,6 +8,20 @@
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int do_locate(lua_State* L, const char* filename, const char* path)
|
||||
{
|
||||
if (do_pathsearch(L, filename, path)) {
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_locate(lua_State* L)
|
||||
{
|
||||
int i;
|
||||
@ -26,22 +40,10 @@ int os_locate(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Call os.pathsearch(arg[i], premake.path) */
|
||||
lua_pushcfunction(L, os_pathsearch);
|
||||
lua_pushvalue(L, i);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_call(L, 2, 1);
|
||||
|
||||
/* os.pathsearch() returns the directory containing the file;
|
||||
* append the filename to complete the path */
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushvalue(L, 1);
|
||||
lua_concat(L, 3);
|
||||
/* do_locate(arg[i], premake.path) */
|
||||
if (do_locate(L, lua_tostring(L, i), lua_tostring(L, -1))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -11,76 +11,82 @@
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int do_pathsearch(lua_State* L, const char* filename, const char* path)
|
||||
{
|
||||
do
|
||||
{
|
||||
const char* split;
|
||||
|
||||
/* look for the closest path separator ; or : */
|
||||
/* can't use : on windows because it breaks on C:\path */
|
||||
const char* semi = strchr(path, ';');
|
||||
#if !defined(PLATFORM_WINDOWS)
|
||||
const char* full = strchr(path, ':');
|
||||
#else
|
||||
const char* full = NULL;
|
||||
#endif
|
||||
|
||||
if (!semi)
|
||||
{
|
||||
split = full;
|
||||
}
|
||||
else if (!full)
|
||||
{
|
||||
split = semi;
|
||||
}
|
||||
else
|
||||
{
|
||||
split = (semi < full) ? semi : full;
|
||||
}
|
||||
|
||||
/* push this piece of the full search string onto the stack */
|
||||
if (split)
|
||||
{
|
||||
lua_pushlstring(L, path, split - path);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, path);
|
||||
}
|
||||
|
||||
/* keep an extra copy around, so I can return it if I have a match */
|
||||
lua_pushvalue(L, -1);
|
||||
|
||||
/* append the filename to make the full test path */
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 3);
|
||||
|
||||
/* test it - if it exists, return the absolute path */
|
||||
if (do_isfile(lua_tostring(L, -1)))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no match, set up the next try */
|
||||
lua_pop(L, 2);
|
||||
path = (split) ? split + 1 : NULL;
|
||||
}
|
||||
while (path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_pathsearch(lua_State* L)
|
||||
{
|
||||
int i;
|
||||
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
for (i = 2; i <= lua_gettop(L); ++i)
|
||||
{
|
||||
const char* path;
|
||||
|
||||
if (lua_isnil(L, i))
|
||||
continue;
|
||||
|
||||
path = luaL_checkstring(L, i);
|
||||
do
|
||||
{
|
||||
const char* split;
|
||||
|
||||
/* look for the closest path separator ; or : */
|
||||
/* can't use : on windows because it breaks on C:\path */
|
||||
const char* semi = strchr(path, ';');
|
||||
#if !defined(PLATFORM_WINDOWS)
|
||||
const char* full = strchr(path, ':');
|
||||
#else
|
||||
const char* full = NULL;
|
||||
#endif
|
||||
|
||||
if (!semi)
|
||||
{
|
||||
split = full;
|
||||
}
|
||||
else if (!full)
|
||||
{
|
||||
split = semi;
|
||||
}
|
||||
else
|
||||
{
|
||||
split = (semi < full) ? semi : full;
|
||||
}
|
||||
|
||||
/* push this piece of the full search string onto the stack */
|
||||
if (split)
|
||||
{
|
||||
lua_pushlstring(L, path, split - path);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, path);
|
||||
}
|
||||
|
||||
/* keep an extra copy around, so I can return it if I have a match */
|
||||
lua_pushvalue(L, -1);
|
||||
|
||||
/* append the filename to make the full test path */
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushvalue(L, 1);
|
||||
lua_concat(L, 3);
|
||||
|
||||
/* test it - if it exists, return the absolute path */
|
||||
if (do_isfile(lua_tostring(L, -1)))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no match, set up the next try */
|
||||
lua_pop(L, 2);
|
||||
path = (split) ? split + 1 : NULL;
|
||||
}
|
||||
while (path);
|
||||
if (lua_isnil(L, i)) continue;
|
||||
if (do_pathsearch(L, filename, luaL_checkstring(L, i))) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
static void build_premake_path(lua_State* L);
|
||||
static int process_arguments(lua_State* L, int argc, const char** argv);
|
||||
static int run_premake_main(lua_State* L, const char* script);
|
||||
|
||||
|
||||
/* A search path for script files */
|
||||
@ -132,13 +133,14 @@ int premake_init(lua_State* L)
|
||||
}
|
||||
|
||||
|
||||
|
||||
int premake_execute(lua_State* L, int argc, const char** argv, const char* script)
|
||||
{
|
||||
int iErrFunc;
|
||||
|
||||
/* push the absolute path to the Premake executable */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
premake_locate(L, argv[0]);
|
||||
premake_locate_executable(L, argv[0]);
|
||||
lua_call(L, 1, 1);
|
||||
lua_setglobal(L, "_PREMAKE_COMMAND");
|
||||
|
||||
@ -150,8 +152,8 @@ int premake_execute(lua_State* L, int argc, const char** argv, const char* scrip
|
||||
/* Use --scripts and PREMAKE_PATH to populate premake.path */
|
||||
build_premake_path(L);
|
||||
|
||||
/* load the main script */
|
||||
if (luaL_dofile(L, script) != OKAY) {
|
||||
/* Find and run the main Premake bootstrapping script */
|
||||
if (run_premake_main(L, script) != OKAY) {
|
||||
printf(ERROR_MESSAGE, lua_tostring(L, -1));
|
||||
return !OKAY;
|
||||
}
|
||||
@ -185,7 +187,7 @@ int premake_execute(lua_State* L, int argc, const char** argv, const char* scrip
|
||||
* http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
|
||||
* http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
|
||||
*/
|
||||
int premake_locate(lua_State* L, const char* argv0)
|
||||
int premake_locate_executable(lua_State* L, const char* argv0)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
const char* path = NULL;
|
||||
@ -262,6 +264,50 @@ int premake_locate(lua_State* L, const char* argv0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks one or more of the standard script search locations to locate the
|
||||
* specified file. If found, returns the discovered path to the script on
|
||||
* the top of the Lua stack.
|
||||
*/
|
||||
int premake_test_file(lua_State* L, const char* filename, int searchMask)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (searchMask & TEST_LOCAL) {
|
||||
if (do_isfile(filename)) {
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_call(L, 1, 1);
|
||||
return OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
if (scripts_path && (searchMask & TEST_SCRIPTS)) {
|
||||
if (do_locate(L, filename, scripts_path)) return OKAY;
|
||||
}
|
||||
|
||||
if (searchMask & TEST_PATH) {
|
||||
const char* path = getenv("PREMAKE_PATH");
|
||||
if (path && do_locate(L, filename, path)) return OKAY;
|
||||
}
|
||||
|
||||
if ((searchMask & TEST_EMBEDDED) != 0) {
|
||||
/* Try to locate a record matching the filename */
|
||||
for (i = 0; builtin_scripts_index[i] != NULL; ++i) {
|
||||
if (strcmp(builtin_scripts_index[i], filename) == 0) {
|
||||
lua_pushstring(L, "$/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 2);
|
||||
return OKAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char* set_scripts_path(const char* relativePath)
|
||||
{
|
||||
char* path = (char*)malloc(PATH_MAX);
|
||||
@ -376,6 +422,41 @@ static int process_arguments(lua_State* L, int argc, const char** argv)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find and run the main Premake bootstrapping script. The loading of the
|
||||
* bootstrap and the other core scripts use a limited set of search paths
|
||||
* to avoid mismatches between the native host code and the scripts
|
||||
* themselves.
|
||||
*/
|
||||
static int run_premake_main(lua_State* L, const char* script)
|
||||
{
|
||||
/* Release builds want to load the embedded scripts, with --scripts
|
||||
* argument allowed as an override. Debug builds will look at the
|
||||
* local file system first, then fall back to embedded. */
|
||||
#if defined(NDEBUG)
|
||||
int z = premake_test_file(L, script,
|
||||
TEST_SCRIPTS | TEST_EMBEDDED);
|
||||
#else
|
||||
int z = premake_test_file(L, script,
|
||||
TEST_LOCAL | TEST_SCRIPTS | TEST_PATH | TEST_EMBEDDED);
|
||||
#endif
|
||||
|
||||
/* If no embedded script can be found, release builds will then
|
||||
* try to fall back to the local file system, just in case */
|
||||
#if defined(NDEBUG)
|
||||
if (z != OKAY) {
|
||||
z = premake_test_file(L, script, TEST_LOCAL | TEST_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (z == OKAY) {
|
||||
z = luaL_dofile(L, lua_tostring(L, -1));
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load a script that was previously embedded into the executable. If
|
||||
* successful, a function containing the new script chunk is pushed to
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file premake.h
|
||||
* \brief Program-wide constants and definitions.
|
||||
* \author Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
* \author Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#define lua_c
|
||||
@ -60,6 +60,13 @@
|
||||
#define OKAY (0)
|
||||
|
||||
|
||||
/* Bitmasks for the different script file search locations */
|
||||
#define TEST_LOCAL (0x01)
|
||||
#define TEST_SCRIPTS (0x02)
|
||||
#define TEST_PATH (0x04)
|
||||
#define TEST_EMBEDDED (0x08)
|
||||
|
||||
|
||||
/* If a /scripts argument is present, its value */
|
||||
extern const char* scripts_path;
|
||||
|
||||
@ -71,7 +78,9 @@ void do_getabsolute(char* result, const char* value, const char* relative_to);
|
||||
int do_getcwd(char* buffer, size_t size);
|
||||
int do_isabsolute(const char* path);
|
||||
int do_isfile(const char* filename);
|
||||
int do_locate(lua_State* L, const char* filename, const char* path);
|
||||
void do_normalize(lua_State* L, char* buffer, const char* path);
|
||||
int do_pathsearch(lua_State* L, const char* filename, const char* path);
|
||||
void do_translate(char* value, const char sep);
|
||||
|
||||
|
||||
@ -113,10 +122,10 @@ int string_startswith(lua_State* L);
|
||||
|
||||
/* Engine interface */
|
||||
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, const char* script);
|
||||
int premake_find_exe(lua_State* L, const char* argv0);
|
||||
int premake_load_embedded_script(lua_State* L, const char* filename);
|
||||
int premake_locate_executable(lua_State* L, const char* argv0);
|
||||
int premake_test_file(lua_State* L, const char* filename, int searchMask);
|
||||
|
||||
|
||||
extern const char* builtin_scripts_index[];
|
||||
|
Reference in New Issue
Block a user