Merge module and script loading improvements

This commit is contained in:
Jason Perkins 2015-02-05 16:12:01 -05:00
commit 0f4e94f19c
6 changed files with 125 additions and 76 deletions

View File

@ -1,7 +1,7 @@
--
-- _premake_main.lua
-- Script-side entry point for the main program logic.
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
--
local shorthelp = "Type 'premake5 --help' for help"
@ -48,16 +48,13 @@
_PREMAKE_DIR = path.getdirectory(_PREMAKE_COMMAND)
local file = _OPTIONS["file"] or "premake5.lua"
local script = os.locate(file, file .. ".lua", "premake4.lua")
if script then
_MAIN_SCRIPT = path.getabsolute(script)
_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
_USER_HOME_DIR = os.getenv("HOME") or os.getenv("USERPROFILE")
p.callArray(p.main.elements)
-- Look for and run the system-wide configuration script; make sure any

View File

@ -1,9 +1,9 @@
---
-- Base definitions required by all the other scripts.
-- @copyright 2002-2013 Jason Perkins and the Premake project
-- @copyright 2002-2015 Jason Perkins and the Premake project
---
premake = {}
premake = premake or {}
premake.modules = {}
premake.tools = {}

View File

@ -45,7 +45,7 @@ LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
lua_pushstring(L, filename);
lua_pushvalue(L, -3);
lua_call(L, 2, 1);
test_name = lua_tostring(L, -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 "$/" */
@ -62,15 +62,21 @@ LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
lua_pushcfunction(L, os_locate);
lua_pushstring(L, filename);
lua_call(L, 1, 1);
test_name = lua_tostring(L, -1);
if (!lua_isnil(L, -1)) {
z = original_luaL_loadfile(L, lua_tostring(L, -1));
test_name = lua_tostring(L, -1);
if (test_name) {
z = original_luaL_loadfile(L, test_name);
}
/* on failure, remove test_name */
/* If the file exists but errors, pass that through */
if (z != OKAY && z != LUA_ERRFILE) {
return z;
}
/* If the file didn't exist, remove the result and the test
* name from the stack before checking embedded scripts */
if (z != OKAY) {
lua_pop(L, 1);
lua_pop(L, 2);
}
}

View File

@ -1,7 +1,7 @@
/**
* \file os_locate.c
* \brief Locates files along the standard built-in search paths.
* \author Copyright (c) 2014 Jason Perkins and the Premake project
* \author Copyright (c) 2014-2015 Jason Perkins and the Premake project
*/
#include <stdlib.h>
@ -10,18 +10,15 @@
int os_locate(lua_State* L)
{
int i, nArgs, vars;
const char* premake_path = getenv("PREMAKE_PATH");
int i;
int nArgs = lua_gettop(L);
nArgs = lua_gettop(L);
/* see if the global environment variables have been set yet */
lua_getglobal(L, "_USER_HOME_DIR");
vars = !lua_isnil(L, -1);
lua_pop(L, 1);
/* Fetch premake.path */
lua_getglobal(L, "premake");
lua_getfield(L, -1, "path");
for (i = 1; i <= nArgs; ++i) {
/* Direct path to file? Return fully qualified version */
/* Direct path to file? Return as absolute path */
if (do_isfile(lua_tostring(L, i))) {
lua_pushcfunction(L, path_getabsolute);
lua_pushvalue(L, i);
@ -29,57 +26,18 @@ int os_locate(lua_State* L)
return 1;
}
/* Search for it... */
/* 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);
/* ...relative to the main project script */
if (vars) {
lua_getglobal(L, "_MAIN_SCRIPT_DIR");
}
/* ...relative to the CWD */
lua_pushstring(L, ".");
/* ...on the paths specified by --scripts, if set */
if (scripts_path) {
lua_pushstring(L, scripts_path);
}
/* ... relative to ~/.premake */
if (vars) {
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/.premake");
lua_concat(L, 2);
}
/* ...on the PREMAKE_PATH environment variable, if set */
if (premake_path) {
lua_pushstring(L, premake_path);
}
/* ...relative to the Premake executable */
if (vars) {
lua_getglobal(L, "_PREMAKE_DIR");
}
/* ...in ~/Library/Application Support/Premake (for OS X) */
if (vars) {
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/Library/Application Support/Premake");
lua_concat(L, 2);
}
/* ...in the expected Unix-y places */
lua_pushstring(L, "/usr/local/share/premake");
lua_pushstring(L, "/usr/share/premake");
lua_call(L, lua_gettop(L) - nArgs - 1, 1);
/* os.pathsearch() returns the directory containing the file;
* append the filename to complete the path */
if (!lua_isnil(L, -1)) {
lua_pushcfunction(L, path_join);
lua_pushvalue(L, -2);
lua_pushvalue(L, i);
lua_call(L, 2, 1);
lua_pushstring(L, "/");
lua_pushvalue(L, 1);
lua_concat(L, 3);
return 1;
}

View File

@ -1,7 +1,7 @@
/**
* \file os_pathsearch.c
* \brief Locates a file, given a set of search paths.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
* \author Copyright (c) 2002-2015 Jason Perkins and the Premake project
*
* \note This function is required by the bootstrapping code; it must be
* implemented here in the host and not scripted.
@ -66,10 +66,13 @@ int os_pathsearch(lua_State* L)
lua_pushvalue(L, 1);
lua_concat(L, 3);
/* test it - if it exists return the path */
/* 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;
}

View File

@ -1,7 +1,7 @@
/**
* \file premake.c
* \brief Program entry point.
* \author Copyright (c) 2002-2014 Jason Perkins and the Premake project
* \author Copyright (c) 2002-2015 Jason Perkins and the Premake project
*/
#include <stdlib.h>
@ -20,6 +20,7 @@
#define ERROR_MESSAGE "Error: %s\n"
static void build_premake_path(lua_State* L);
static int process_arguments(lua_State* L, int argc, const char** argv);
@ -88,6 +89,8 @@ static const luaL_Reg string_functions[] = {
*/
int premake_init(lua_State* L)
{
const char* value;
luaL_register(L, "criteria", criteria_functions);
luaL_register(L, "debug", debug_functions);
luaL_register(L, "path", path_functions);
@ -111,10 +114,20 @@ int premake_init(lua_State* L)
lua_pushstring(L, PLATFORM_STRING);
lua_setglobal(L, "_OS");
/* find the user's home directory */
value = getenv("HOME");
if (!value) value = getenv("USERPROFILE");
lua_pushstring(L, value);
lua_setglobal(L, "_USER_HOME_DIR");
/* publish the initial working directory */
os_getcwd(L);
lua_setglobal(L, "_WORKING_DIR");
/* start the premake namespace */
lua_newtable(L);
lua_setglobal(L, "premake");
return OKAY;
}
@ -134,6 +147,9 @@ int premake_execute(lua_State* L, int argc, const char** argv, const char* scrip
return !OKAY;
}
/* Use --scripts and PREMAKE_PATH to populate premake.path */
build_premake_path(L);
/* load the main script */
if (luaL_dofile(L, script) != OKAY) {
printf(ERROR_MESSAGE, lua_tostring(L, -1));
@ -246,7 +262,7 @@ int premake_locate(lua_State* L, const char* argv0)
const char* set_scripts_path(const char* relativePath)
static const char* set_scripts_path(const char* relativePath)
{
char* path = (char*)malloc(PATH_MAX);
do_getabsolute(path, relativePath, NULL);
@ -256,13 +272,82 @@ const char* set_scripts_path(const char* relativePath)
/**
* Set the premake.path variable, pulling from the --scripts argument
* and PREMAKE_PATH environment variable if present.
*/
static void build_premake_path(lua_State* L)
{
int top;
const char* value;
lua_getglobal(L, "premake");
top = lua_gettop(L);
/* Start by searching the current working directory */
lua_pushstring(L, ".");
/* The --scripts argument goes next, if present */
if (scripts_path) {
lua_pushstring(L, ";");
lua_pushstring(L, scripts_path);
}
/* Then the PREMAKE_PATH environment variable */
value = getenv("PREMAKE_PATH");
if (value) {
lua_pushstring(L, ";");
lua_pushstring(L, value);
}
/* Then in ~/.premake */
lua_pushstring(L, ";");
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/.premake");
/* In the user's Application Support folder */
#if defined(PLATFORM_MACOSX)
lua_pushstring(L, ";");
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/Library/Application Support/Premake");
#endif
/* In the /usr tree */
lua_pushstring(L, ";/usr/local/share/premake;/usr/share/premake");
/* Put it all together */
lua_concat(L, lua_gettop(L) - top);
/* Match Lua's package.path; use semicolon separators */
#if !defined(PLATFORM_WINDOWS)
lua_getglobal(L, "string");
lua_getfield(L, -1, "gsub");
lua_pushvalue(L, -3);
lua_pushstring(L, ":");
lua_pushstring(L, ";");
lua_call(L, 3, 1);
/* remove the string global table */
lua_remove(L, -2);
/* remove the previously concatonated result */
lua_remove(L, -2);
#endif
/* Store it in premake.path */
lua_setfield(L, -2, "path");
/* Remove the premake namespace table */
lua_pop(L, 1);
}
/**
* Copy all command line arguments into the script-side _ARGV global, and
* check for the presence of a /scripts=<path> argument to help locate
* the manifest if needed.
* \returns OKAY if successful.
*/
int process_arguments(lua_State* L, int argc, const char** argv)
static int process_arguments(lua_State* L, int argc, const char** argv)
{
int i;