Add more module and script search paths

Now uses same set of paths to locate both modules and individual scripts, in order:
  - the main script dir (_MAIN_SCRIPT_DIR)
  - the current working directory
  - ~/.premake
  - the --scripts=… argument, if present
  - the PREMAKE_PATH environment variable, if set
  - the folder containing the Premake executable (_PREMAKE_DIR)
  - ~/Library/Application Support/Premake
  - /usr/local/share/premake
  - /usr/share/premake

Prints a warning when embedded scripts are loaded from a debug build
This commit is contained in:
Jason Perkins 2014-09-29 18:00:52 -04:00
parent d9c87649f3
commit e2c1f5c430
5 changed files with 121 additions and 53 deletions

View File

@ -11,49 +11,6 @@
local DOC_URL = "See https://bitbucket.org/premake/premake-dev/wiki/"
-----------------------------------------------------------------------------
--
-- Prepare the global environment.
--
-----------------------------------------------------------------------------
-- Seed the random number generator so actions don't have to do it themselves
math.randomseed(os.time())
-- Set some globals to describe the runtime environment, building on
-- what was already set by the native code host
_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_DIR = path.getdirectory(_MAIN_SCRIPT)
else
_MAIN_SCRIPT_DIR = _WORKING_DIR
end
-- Set the default module search paths. Modules will generally live in
-- a folder of the same name: xcode/xcode.lua. The search order is the
-- same as what is specified here.
local home = os.getenv("HOME") or os.getenv("USERPROFILE")
local packagePaths = {
path.join(home, ".premake/?/?.lua"),
"./modules/?/?.lua",
path.join(_MAIN_SCRIPT_DIR, "modules/?/?.lua"),
path.join(path.getdirectory(_PREMAKE_COMMAND), "modules/?/?.lua"),
path.join(home, "Library/Application Support/Premake/?/?.lua"),
"/usr/local/share/premake/?/?.lua",
"/usr/share/premake/?/?.lua",
}
package.path = table.concat(packagePaths, ";")
-----------------------------------------------------------------------------
--
-- Register the core API functions.

View File

@ -16,16 +16,50 @@
end
-- Create namespaces for myself
local p = premake
p.main = {}
--
-- Script-side program entry point.
--
p.main.elements = function()
return {
p.main.installModuleLoader,
}
end
function _premake_main()
-- Clear out any configuration scoping left over from initialization
filter {}
-- Seed the random number generator so actions don't have to do it themselves
math.randomseed(os.time())
-- Set some global to describe the runtime environment, building on
-- what was already set by the native code host
_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_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
-- configuration scoping gets cleared before continuing
@ -119,3 +153,23 @@
return 0
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
-- naming convention.
---
function p.main.moduleLoader(name)
local moduleName = name .. "/" .. name .. ".lua"
local filename = os.locate(name, "modules/" .. moduleName)
if filename then
return assert(loadfile(filename))
end
return "module " .. name .. "not found"
end
function p.main.installModuleLoader()
table.insert(package.loaders, 2, p.main.moduleLoader)
end

View File

@ -62,9 +62,7 @@
if type(funcs) == "function" then
funcs = funcs(...)
end
local n = #funcs
for i = 1, n do
for i = 1, #funcs do
funcs[i](...)
end
end

View File

@ -1,6 +1,6 @@
/**
* \file os_locate.c
* \brief Locates a file, given a set of search paths.
* \brief Locates files along the standard built-in search paths.
* \author Copyright (c) 2014 Jason Perkins and the Premake project
*/
@ -10,10 +10,16 @@
int os_locate(lua_State* L)
{
int i, top;
int i, top, vars;
const char* premake_path = getenv("PREMAKE_PATH");
top = 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);
for (i = 1; i <= top; ++i) {
/* direct path to file? */
if (do_isfile(lua_tostring(L, i))) {
@ -24,11 +30,41 @@ int os_locate(lua_State* L)
/* 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 (vars) {
lua_getglobal(L, "_MAIN_SCRIPT_DIR");
}
lua_pushstring(L, ".");
if (vars) {
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/.premake");
lua_concat(L, 2);
}
if (scripts_path) {
lua_pushstring(L, scripts_path);
}
if (premake_path) {
lua_pushstring(L, premake_path);
}
if (vars) {
lua_getglobal(L, "_PREMAKE_DIR");
}
if (vars) {
lua_getglobal(L, "_USER_HOME_DIR");
lua_pushstring(L, "/Library/Application Support/Premake");
lua_concat(L, 2);
}
lua_pushstring(L, "/usr/local/share/premake");
lua_pushstring(L, "/usr/share/premake");
lua_call(L, lua_gettop(L) - top - 1, 1);
if (!lua_isnil(L, -1)) {
lua_pushcfunction(L, path_join);
lua_pushvalue(L, -2);
@ -36,6 +72,8 @@ int os_locate(lua_State* L)
lua_call(L, 2, 1);
return 1;
}
lua_pop(L, 1);
}
return 0;

View File

@ -121,6 +121,8 @@ int premake_init(lua_State* L)
int premake_execute(lua_State* L, int argc, const char** argv)
{
int iErrFunc;
/* push the absolute path to the Premake executable */
lua_pushcfunction(L, path_getabsolute);
premake_locate(L, argv[0]);
@ -138,9 +140,18 @@ int premake_execute(lua_State* L, int argc, const char** argv)
return !OKAY;
}
/* in debug mode, show full traceback on all errors */
#if defined(NDEBUG)
iErrFunc = 0;
#else
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
iErrFunc = -2;
#endif
/* and call the main entry point */
lua_getglobal(L, "_premake_main");
if (lua_pcall(L, 0, 1, 0) != OKAY) {
if (lua_pcall(L, 0, 1, iErrFunc) != OKAY) {
printf(ERROR_MESSAGE, lua_tostring(L, -1));
return !OKAY;
}
@ -281,6 +292,8 @@ int process_arguments(lua_State* L, int argc, const char** argv)
int premake_load_embedded_script(lua_State* L, const char* filename)
{
static int warned = 0;
/* locate a record matching the filename */
int i;
for (i = 0; builtin_scripts_index[i] != NULL; ++i) {
@ -289,6 +302,14 @@ int premake_load_embedded_script(lua_State* L, const char* filename)
}
}
/* debug builds probably want to be loading scripts from the disk */
#if !defined(NDEBUG)
if (!warned) {
warned = 1;
printf("** warning: using embedded scripts; use /scripts argument to load from files\n");
}
#endif
/* load its script */
if (builtin_scripts_index[i] != NULL) {
const char* chunk = builtin_scripts[i];