Jason Perkins avatar Jason Perkins committed 207eadb

Patch 3485071: Fixed _PREMAKE_COMMAND fallback when premake4 is not in PATH (Konstantin Tokarev)

Comments (0)

Files changed (7)

src/_premake_main.lua

 		end
 		
 
+		-- Now that the scripts are loaded, I can use path.getabsolute() to properly
+		-- canonicalize the executable path.
+		
+		_PREMAKE_COMMAND = path.getabsolute(_PREMAKE_COMMAND)
+
+
 		-- Set up the environment for the chosen action early, so side-effects
 		-- can be picked up by the scripts.
 

src/host/path_isabsolute.c

 
 
 int path_isabsolute(lua_State* L)
-{
-	const char* path = luaL_checkstring(L, 1);
+{	const char* path = luaL_checkstring(L, -1);
 	if (path[0] == '/' || 
 	    path[0] == '\\' || 
 	    path[0] == '$' || 

src/host/premake.c

 /**
  * \file   premake.c
  * \brief  Program entry point.
- * \author Copyright (c) 2002-2011 Jason Perkins and the Premake project
+ * \author Copyright (c) 2002-2012 Jason Perkins and the Premake project
  */
 
 #include <stdlib.h>
 #define ERROR_MESSAGE  "%s\n"
 
 
-static int find_premake_executable(lua_State* L, const char* argv0);
 static int process_arguments(lua_State* L, int argc, const char** argv);
 static int process_option(lua_State* L, const char* arg);
 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;
 	{ NULL, NULL }
 };
 
+
 /**
- * Program entry point.
+ * Initialize the Premake Lua environment.
  */
-int main(int argc, const char** argv)
+int premake_init(lua_State* L)
 {
-	lua_State* L;
-	int z = OKAY;
-
-	/* prepare Lua for use */
-	L = lua_open();
-	luaL_openlibs(L);
 	luaL_register(L, "path",   path_functions);
 	luaL_register(L, "os",     os_functions);
 	luaL_register(L, "string", string_functions);
 
-	/* push the location of the Premake executable */
-	find_premake_executable(L, argv[0]);
-	lua_setglobal(L, "_PREMAKE_COMMAND");
-
 	/* push the application metadata */
 	lua_pushstring(L, LUA_COPYRIGHT);
 	lua_setglobal(L, "_COPYRIGHT");
 	/* set the OS platform variable */
 	lua_pushstring(L, PLATFORM_STRING);
 	lua_setglobal(L, "_OS");
+		
+	return OKAY;
+}
 
+
+int premake_execute(lua_State* L, int argc, const char** argv)
+{
 	/* Parse the command line arguments */
-	if (z == OKAY)  z = process_arguments(L, argc, argv);
+	int z = process_arguments(L, argc, argv);
 
 	/* Run the built-in Premake scripts */
 	if (z == OKAY)  z = load_builtin_scripts(L);
-
-	/* Clean up and turn off the lights */
-	lua_close(L);
+	
 	return z;
 }
 
 
-
 /**
  * Locate the Premake executable, and push its full path to the Lua stack.
  * Based on:
  * 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 find_premake_executable(lua_State* L, const char* argv0)
+int premake_locate(lua_State* L, const char* argv0)
 {
 #if !defined(PATH_MAX)
 #define PATH_MAX  (4096)
 		lua_pushcfunction(L, os_pathsearch);
 		lua_pushstring(L, argv0);
 		lua_pushstring(L, getenv("PATH"));
-		if (lua_pcall(L, 2, 1, 0) == OKAY)
+		if (lua_pcall(L, 2, 1, 0) == OKAY && !lua_isnil(L, -1))
 		{
 			lua_pushstring(L, "/");
 			lua_pushstring(L, argv0);
 		}
 	}
 
+	/* If all else fails, use argv[0] as-is and hope for the best */
+	if (!path)
+	{
+		/* make it absolute, if needed */
+		os_getcwd(L);
+		lua_pushstring(L, "/");
+		lua_pushstring(L, argv0);
+		
+		if (!path_isabsolute(L)) {
+			lua_concat(L, 3);
+		}
+		else {
+			lua_pop(L, 1);
+		}
+		
+		path = lua_tostring(L, -1);
+	}
+
 	lua_pushstring(L, path);
 	return 1;
 }
 
 
 
-#if defined(_DEBUG)
+#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

src/host/premake.h

 int os_uuid(lua_State* L);
 int string_endswith(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);

src/host/premake_main.c

+/**
+ * \file   premake_main.c
+ * \brief  Program entry point.
+ * \author Copyright (c) 2002-2012 Jason Perkins and the Premake project
+ */
+
+#include "premake.h"
+
+int main(int argc, const char** argv)
+{
+	lua_State* L;
+	int z = OKAY;
+
+	L = lua_open();
+	luaL_openlibs(L);
+	z = premake_init(L);
+
+	/* push the location of the Premake executable */
+	premake_locate(L, argv[0]);
+	lua_setglobal(L, "_PREMAKE_COMMAND");
+
+	if (z == OKAY)
+	{
+		z = premake_execute(L, argc, argv);
+	}
+	
+	lua_close(L);
+	return z;
+}

tests/base/test_premake_command.lua

+--
+-- tests/base/test_premake_command.lua
+-- Test the initialization of the _PREMAKE_COMMAND global.
+-- Copyright (c) 2012 Jason Perkins and the Premake project
+--
+
+	T.premake_command = { }
+	local suite = T.premake_command
+
+
+	function suite.valueIsSet()
+		local filename = iif(os.is("windows"), "premake4.exe", "premake4")
+		test.isequal(path.getabsolute("../bin/debug/" .. filename), _PREMAKE_COMMAND)
+	end

tests/premake4.lua

 	dofile("base/test_location.lua")
 	dofile("base/test_os.lua")
 	dofile("base/test_path.lua")
+	dofile("base/test_premake_command.lua")
 	dofile("base/test_table.lua")
 	dofile("base/test_tree.lua")
 	dofile("base/test_config_bug.lua")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.