From 70ea51579ca93b3ea7e11002f930197258e18d83 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 10 Feb 2022 00:14:20 +0100 Subject: Backporting VS2017 through VS2022 support There are also minor fixes, such as for CompileAs and other conditions. It actually also required changing two test cases, because implicitly the default are C++ projects, so adding .c files should add CompileAs, but didn't in the past. --- src/_manifest.lua | 3 + src/actions/vstudio/vs2005_csproj.lua | 2 +- src/actions/vstudio/vs2005_solution.lua | 4 + src/actions/vstudio/vs200x_vcproj.lua | 70 +++++---- src/actions/vstudio/vs2010_vcxproj.lua | 34 ++-- src/actions/vstudio/vs2015.lua | 1 + src/actions/vstudio/vs2017.lua | 58 +++++++ src/actions/vstudio/vs2019.lua | 58 +++++++ src/actions/vstudio/vs2022.lua | 58 +++++++ src/host/os_getversion.c | 172 ++++++++++++++------- src/host/os_is64bit.c | 18 ++- src/host/os_match.c | 29 +++- src/host/os_uuid.c | 4 +- src/host/path_translate.c | 8 +- src/host/premake.c | 33 +++- tests/actions/vstudio/sln2005/header.lua | 63 +++++++- tests/actions/vstudio/vc2010/test_config_props.lua | 39 +++++ tests/actions/vstudio/vc2010/test_files.lua | 2 + tests/testfx.lua | 2 +- 19 files changed, 548 insertions(+), 110 deletions(-) create mode 100644 src/actions/vstudio/vs2017.lua create mode 100644 src/actions/vstudio/vs2019.lua create mode 100644 src/actions/vstudio/vs2022.lua diff --git a/src/_manifest.lua b/src/_manifest.lua index 19f497a..30daba3 100644 --- a/src/_manifest.lua +++ b/src/_manifest.lua @@ -66,6 +66,9 @@ "actions/vstudio/vs2012.lua", "actions/vstudio/vs2013.lua", "actions/vstudio/vs2015.lua", + "actions/vstudio/vs2017.lua", + "actions/vstudio/vs2019.lua", + "actions/vstudio/vs2022.lua", -- Xcode action "actions/xcode/_xcode.lua", diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua index 6b6238c..0b45c82 100644 --- a/src/actions/vstudio/vs2005_csproj.lua +++ b/src/actions/vstudio/vs2005_csproj.lua @@ -38,7 +38,7 @@ local basename = fname:sub(1, -9) local testname = basename .. ".xaml" if premake.findfile(prj, testname) then - return "SubTypeCode", path.getname(testname) + return "SubTypeCode", testname end else -- is there a *.Designer.cs file? diff --git a/src/actions/vstudio/vs2005_solution.lua b/src/actions/vstudio/vs2005_solution.lua index b0942db..bbfa685 100644 --- a/src/actions/vstudio/vs2005_solution.lua +++ b/src/actions/vstudio/vs2005_solution.lua @@ -40,7 +40,11 @@ function sln2005.header(sln) local action = premake.action.current() _p('Microsoft Visual Studio Solution File, Format Version %d.00', action.vstudio.solutionVersion) + if action.vstudio.shortSlnVersion ~= nil then + _p('# Visual Studio %s', action.vstudio.shortSlnVersion) + else _p('# Visual Studio %s', _ACTION:sub(3)) + end end diff --git a/src/actions/vstudio/vs200x_vcproj.lua b/src/actions/vstudio/vs200x_vcproj.lua index 3ef4e8b..a36d8ae 100644 --- a/src/actions/vstudio/vs200x_vcproj.lua +++ b/src/actions/vstudio/vs200x_vcproj.lua @@ -102,36 +102,9 @@ _p(3,'>') end + vc200x.individualSourceFileOptions = nil --- --- Write out the element. --- - - function vc200x.Files(prj) - local tr = premake.project.buildsourcetree(prj) - - tree.traverse(tr, { - -- folders are handled at the internal nodes - onbranchenter = function(node, depth) - _p(depth, '') - end, - - onbranchexit = function(node, depth) - _p(depth, '') - end, - - -- source files are handled at the leaves - onleaf = function(node, depth) - local fname = node.cfg.name - - _p(depth, '') - depth = depth + 1 - + function vc200x.individualSourceFile(prj, depth, fname, node) -- handle file configuration stuff. This needs to be cleaned up and simplified. -- configurations are cached, so this isn't as bad as it looks for _, cfginfo in ipairs(prj.solution.vstudio_configs) do @@ -142,7 +115,7 @@ local isSourceCode = path.iscppfile(fname) local needsCompileAs = (path.iscfile(fname) ~= premake.project.iscproject(prj)) - if usePCH or (isSourceCode and needsCompileAs) then + if usePCH or (isSourceCode and needsCompileAs) or (type(vc200x.individualSourceFileOptions) == 'function') then _p(depth, '') @@ -166,6 +139,9 @@ _p(depth, '\t\tUsePrecompiledHeader="1"') end end + if (type(vc200x.individualSourceFileOptions) == 'function') then + vc200x.individualSourceFileOptions(prj, depth, fname, node) + end _p(depth, '\t/>') _p(depth, '') @@ -173,6 +149,38 @@ end end + end + +-- +-- Write out the element. +-- + + function vc200x.Files(prj) + local tr = premake.project.buildsourcetree(prj) + + tree.traverse(tr, { + -- folders are handled at the internal nodes + onbranchenter = function(node, depth) + _p(depth, '') + end, + + onbranchexit = function(node, depth) + _p(depth, '') + end, + + -- source files are handled at the leaves + onleaf = function(node, depth) + local fname = node.cfg.name + + _p(depth, '') + depth = depth + 1 + + vc200x.individualSourceFile(prj, depth, fname, node) depth = depth - 1 _p(depth, '') @@ -388,7 +396,7 @@ end if (cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp") and not cfg.flags.WinMain then - _p(4,'EntryPointSymbol="mainCRTStartup"') + _p(4,'EntryPointSymbol="%s"', iif(cfg.flags.Unicode, "wmainCRTStartup", "mainCRTStartup")) end if cfg.kind == "SharedLib" then diff --git a/src/actions/vstudio/vs2010_vcxproj.lua b/src/actions/vstudio/vs2010_vcxproj.lua index dcff220..6af05db 100644 --- a/src/actions/vstudio/vs2010_vcxproj.lua +++ b/src/actions/vstudio/vs2010_vcxproj.lua @@ -79,7 +79,7 @@ _p(2,'%s', iif(optimisation(cfg) == "Disabled","true","false")) _p(2,'%s',iif(cfg.flags.Unicode,"Unicode","MultiByte")) - local toolsets = { vs2012 = "v110", vs2013 = "v120", vs2015 = "v140" } + local toolsets = { vs2012 = "v110", vs2013 = "v120", vs2015 = "v140", vs2017 = "v141", vs2019 = "v142", vs2022 = "v143" } local toolset = toolsets[_ACTION] if toolset then _p(2,'%s', toolset) @@ -417,7 +417,7 @@ end if vc2010.config_type(cfg) == 'Application' and not cfg.flags.WinMain and not cfg.flags.Managed then - _p(3,'mainCRTStartup') + _p(3,'%s', iif(cfg.flags.Unicode, "wmainCRTStartup", "mainCRTStartup")) end import_lib(cfg) @@ -526,6 +526,26 @@ end end + vc2010.individualSourceFileOptions = nil + + function vc2010.individualSourceFile(prj, config_mappings, file) + local configs = prj.solution.vstudio_configs + local translatedpath = path.translate(file.name, "\\") + _p(2,'', translatedpath) + for _, cfginfo in ipairs(configs) do + if config_mappings[cfginfo] and translatedpath == config_mappings[cfginfo] then + _p(3,'Create', premake.esc(cfginfo.name)) + config_mappings[cfginfo] = nil --only one source file per pch + end + end + if path.iscfile(file.name) ~= premake.project.iscproject(prj) then + _p(3,'%s', iif(path.iscfile(file.name), 'CompileAsC', 'CompileAsCpp')) + end + if (type(vc2010.individualSourceFileOptions) == 'function') then + vc2010.individualSourceFileOptions(prj, config_mappings, file) + end + _p(2,'') + end function vc2010.compilerfilesgroup(prj) local configs = prj.solution.vstudio_configs @@ -541,15 +561,7 @@ _p(1,'') for _, file in ipairs(files) do - local translatedpath = path.translate(file.name, "\\") - _p(2,'', translatedpath) - for _, cfginfo in ipairs(configs) do - if config_mappings[cfginfo] and translatedpath == config_mappings[cfginfo] then - _p(3,'Create', premake.esc(cfginfo.name)) - config_mappings[cfginfo] = nil --only one source file per pch - end - end - _p(2,'') + vc2010.individualSourceFile(prj, config_mappings, file) end _p(1,'') end diff --git a/src/actions/vstudio/vs2015.lua b/src/actions/vstudio/vs2015.lua index 8fa0ca9..9a8ba02 100644 --- a/src/actions/vstudio/vs2015.lua +++ b/src/actions/vstudio/vs2015.lua @@ -53,5 +53,6 @@ solutionVersion = "12", targetFramework = "4.5.2", toolsVersion = "14.0", + shortSlnVersion = "14", } } diff --git a/src/actions/vstudio/vs2017.lua b/src/actions/vstudio/vs2017.lua new file mode 100644 index 0000000..0bc0a02 --- /dev/null +++ b/src/actions/vstudio/vs2017.lua @@ -0,0 +1,58 @@ +-- +-- vs2017.lua +-- Baseline support for Visual Studio 2017. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + premake.vstudio.vc2017 = {} + local vc2017 = premake.vstudio.vc2017 + local vstudio = premake.vstudio + + +--- +-- Register a command-line action for Visual Studio 2017. +--- + + newaction + { + trigger = "vs2017", + shortname = "Visual Studio 2017", + description = "Generate Microsoft Visual Studio 2017 project files", + os = "windows", + + valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, + + valid_languages = { "C", "C++", "C#"}, + + valid_tools = { + cc = { "msc" }, + dotnet = { "msnet" }, + }, + + onsolution = function(sln) + premake.generate(sln, "%%.sln", vstudio.sln2005.generate) + end, + + onproject = function(prj) + if premake.isdotnetproject(prj) then + premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + else + premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) + premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) + premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) + end + end, + + + oncleansolution = premake.vstudio.cleansolution, + oncleanproject = premake.vstudio.cleanproject, + oncleantarget = premake.vstudio.cleantarget, + + vstudio = { + solutionVersion = "12", + targetFramework = "4.5.2", + toolsVersion = "15.0", + shortSlnVersion = "15", + } + } diff --git a/src/actions/vstudio/vs2019.lua b/src/actions/vstudio/vs2019.lua new file mode 100644 index 0000000..acfb924 --- /dev/null +++ b/src/actions/vstudio/vs2019.lua @@ -0,0 +1,58 @@ +-- +-- vs2019.lua +-- Baseline support for Visual Studio 2019. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + premake.vstudio.vc2019 = {} + local vc2019 = premake.vstudio.vc2019 + local vstudio = premake.vstudio + + +--- +-- Register a command-line action for Visual Studio 2019. +--- + + newaction + { + trigger = "vs2019", + shortname = "Visual Studio 2019", + description = "Generate Microsoft Visual Studio 2019 project files", + os = "windows", + + valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, + + valid_languages = { "C", "C++", "C#"}, + + valid_tools = { + cc = { "msc" }, + dotnet = { "msnet" }, + }, + + onsolution = function(sln) + premake.generate(sln, "%%.sln", vstudio.sln2005.generate) + end, + + onproject = function(prj) + if premake.isdotnetproject(prj) then + premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + else + premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) + premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) + premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) + end + end, + + + oncleansolution = premake.vstudio.cleansolution, + oncleanproject = premake.vstudio.cleanproject, + oncleantarget = premake.vstudio.cleantarget, + + vstudio = { + solutionVersion = "12", + targetFramework = "4.7", + toolsVersion = "16.0", + shortSlnVersion = "16", + } + } diff --git a/src/actions/vstudio/vs2022.lua b/src/actions/vstudio/vs2022.lua new file mode 100644 index 0000000..0df82ae --- /dev/null +++ b/src/actions/vstudio/vs2022.lua @@ -0,0 +1,58 @@ +-- +-- vs2022.lua +-- Baseline support for Visual Studio 2022. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + premake.vstudio.vc2022 = {} + local vc2022 = premake.vstudio.vc2022 + local vstudio = premake.vstudio + + +--- +-- Register a command-line action for Visual Studio 2022. +--- + + newaction + { + trigger = "vs2022", + shortname = "Visual Studio 2022", + description = "Generate Microsoft Visual Studio 2022 project files", + os = "windows", + + valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, + + valid_languages = { "C", "C++", "C#"}, + + valid_tools = { + cc = { "msc" }, + dotnet = { "msnet" }, + }, + + onsolution = function(sln) + premake.generate(sln, "%%.sln", vstudio.sln2005.generate) + end, + + onproject = function(prj) + if premake.isdotnetproject(prj) then + premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + else + premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) + premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) + premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) + end + end, + + + oncleansolution = premake.vstudio.cleansolution, + oncleanproject = premake.vstudio.cleanproject, + oncleantarget = premake.vstudio.cleantarget, + + vstudio = { + solutionVersion = "12", + targetFramework = "4.7", + toolsVersion = "17.0", + shortSlnVersion = "17", + } + } diff --git a/src/host/os_getversion.c b/src/host/os_getversion.c index 446848f..c0787b5 100755 --- a/src/host/os_getversion.c +++ b/src/host/os_getversion.c @@ -63,82 +63,148 @@ int os_getversion(lua_State* L) SYSTEM_INFO getsysteminfo() { - typedef void (WINAPI *GetNativeSystemInfoSig)(LPSYSTEM_INFO); - GetNativeSystemInfoSig nativeSystemInfo = (GetNativeSystemInfoSig) - GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetNativeSystemInfo"); + static SYSTEM_INFO systemInfo; + HMODULE hKrnl32 = GetModuleHandle(TEXT("kernel32")); + memset(&systemInfo, 0, sizeof(systemInfo)); + if (hKrnl32) + { + typedef void (WINAPI* GetNativeSystemInfoSig)(LPSYSTEM_INFO); + GetNativeSystemInfoSig nativeSystemInfo = (GetNativeSystemInfoSig)GetProcAddress(hKrnl32, "GetNativeSystemInfo"); - SYSTEM_INFO systemInfo = {{0}}; - if ( nativeSystemInfo ) nativeSystemInfo(&systemInfo); - else GetSystemInfo(&systemInfo); + if (nativeSystemInfo) + nativeSystemInfo(&systemInfo); + else + GetSystemInfo(&systemInfo); + } return systemInfo; } -void getversion(struct OsVersionInfo* info) -{ - OSVERSIONINFOEX versionInfo = {0}; - - versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((OSVERSIONINFO*)&versionInfo); - - info->majorversion = versionInfo.dwMajorVersion; - info->minorversion = versionInfo.dwMinorVersion; - info->revision = versionInfo.wServicePackMajor; +#ifndef NT_SUCCESS +# define NT_SUCCESS(x) ((x) >= 0) +#endif - if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 0) +OSVERSIONINFOEXW const * GetOSVersionInfo() +{ + static OSVERSIONINFOEXW* posvix = NULL; + if (!posvix) { - info->description = "Windows 2000"; + static OSVERSIONINFOEXW osvix = { sizeof(OSVERSIONINFOEXW), 0, 0, 0, 0,{ 0 } }; // not an error, this has to be the W variety! + static LONG(WINAPI * RtlGetVersion)(OSVERSIONINFOEXW*) = NULL; + static HMODULE hNtDll = NULL; + hNtDll = GetModuleHandle(TEXT("ntdll.dll")); + if (hNtDll) + { + *(FARPROC*)&RtlGetVersion = GetProcAddress(hNtDll, "RtlGetVersion"); + if (NULL != RtlGetVersion) + { + if (NT_SUCCESS(RtlGetVersion(&osvix))) + { + posvix = &osvix; } - else if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 1) - { - info->description = "Windows XP"; } - else if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 2) - { - SYSTEM_INFO systemInfo = getsysteminfo(); - if (versionInfo.wProductType == VER_NT_WORKSTATION && - systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - { - info->description = "Windows XP Professional x64"; } - else if (versionInfo.wSuiteMask & VER_SUITE_WH_SERVER) - { - info->description = "Windows Home Server"; } - else if (GetSystemMetrics(SM_SERVERR2) == 0) + return posvix; +} + +void getversion(struct OsVersionInfo* info) +{ + static OSVERSIONINFOEXW const* posvix = NULL; + static struct OsVersionInfo s_info; + s_info.majorversion = 0; + s_info.minorversion = 0; + s_info.revision = 0; + s_info.description = "Windows"; + + if (!posvix) + { + posvix = GetOSVersionInfo(); + if (posvix) { - info->description = "Windows Server 2003"; - } + s_info.majorversion = posvix->dwMajorVersion; + s_info.minorversion = posvix->dwMinorVersion; + s_info.revision = posvix->wServicePackMajor; + switch (posvix->dwMajorVersion) + { + case 5: + switch (posvix->dwMinorVersion) + { + case 0: + s_info.description = "Windows 2000"; + break; + case 1: + s_info.description = "Windows XP"; + break; + case 2: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows XP x64"; else + if (posvix->wSuiteMask == VER_SUITE_WH_SERVER) + s_info.description = "Windows Home Server"; + else { - info->description = "Windows Server 2003 R2"; + if (GetSystemMetrics(SM_SERVERR2) == 0) + s_info.description = "Windows Server 2003"; + else + s_info.description = "Windows Server 2003 R2"; } + break; + default: + s_info.description = "Windows [5.x]"; + break; } - else if (versionInfo.dwMajorVersion == 6 && versionInfo.dwMinorVersion == 0) - { - if (versionInfo.wProductType == VER_NT_WORKSTATION) + break; + case 6: + switch (posvix->dwMinorVersion) { - info->description = "Windows Vista"; - } + case 0: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows Vista"; else - { - info->description = "Windows Server 2008"; - } + s_info.description = "Windows Server 2008"; + break; + case 1: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows 7"; + else + s_info.description = "Windows Server 2008 R2"; + break; + case 2: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows 8"; + else + s_info.description = "Windows Server 2012"; + break; + case 3: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows 8.1"; + else + s_info.description = "Windows Server 2012 R2"; + break; + default: + s_info.description = "Windows [6.x]"; + break; } - else if (versionInfo.dwMajorVersion == 6 && versionInfo.dwMinorVersion == 1 ) - { - if (versionInfo.wProductType != VER_NT_WORKSTATION) + break; + case 10: + switch (posvix->dwMinorVersion) { - info->description = "Windows Server 2008 R2"; - } + case 0: + if (posvix->wProductType == VER_NT_WORKSTATION) + s_info.description = "Windows 10"; else - { - info->description = "Windows 7"; + s_info.description = "Windows Server 2016/2019"; + break; + default: + s_info.description = "Windows [10.x]"; + break; } + break; + } } - else - { - info->description = "Windows"; } + + memmove(info, &s_info, sizeof(struct OsVersionInfo)); } /*************************************************************/ diff --git a/src/host/os_is64bit.c b/src/host/os_is64bit.c index 3134751..e572dbc 100755 --- a/src/host/os_is64bit.c +++ b/src/host/os_is64bit.c @@ -6,14 +6,27 @@ #include "premake.h" +#if PLATFORM_WINDOWS +typedef BOOL(WINAPI* WowFuncSig)(HANDLE, PBOOL); +#endif + int os_is64bit(lua_State* L) { +#if PLATFORM_WINDOWS + HMODULE hKrnl32 = GetModuleHandle(TEXT("kernel32")); +#endif + if (sizeof(void*) == 8) // our premake build is 64-bit, so the runtime environment must be also (at least) 64-bit ... + { + lua_pushboolean(L, 1); + return 1; + } // If this code returns true, then the platform is 64-bit. If it // returns false, the platform might still be 64-bit, but more // checking will need to be done on the Lua side of things. #if PLATFORM_WINDOWS - typedef BOOL (WINAPI* WowFuncSig)(HANDLE, PBOOL); - WowFuncSig func = (WowFuncSig)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + if (hKrnl32) + { + WowFuncSig func = (WowFuncSig)GetProcAddress(hKrnl32, "IsWow64Process"); if (func) { BOOL isWow = FALSE; @@ -21,6 +34,7 @@ int os_is64bit(lua_State* L) { lua_pushboolean(L, isWow); return 1; + } } } #endif diff --git a/src/host/os_match.c b/src/host/os_match.c index 5ccc04d..e307ab0 100644 --- a/src/host/os_match.c +++ b/src/host/os_match.c @@ -8,6 +8,17 @@ #include #include "premake.h" +static int skip_dot_entries(const char* name) +{ + if (name[0] == '.') + { + if (name[1] == '\0') + return 1; + if (name[1] == '.' && name[2] == '\0') + return 1; + } + return 0; +} #if PLATFORM_WINDOWS @@ -25,9 +36,16 @@ int os_matchstart(lua_State* L) { const char* mask = luaL_checkstring(L, 1); MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo)); - m->handle = FindFirstFile(mask, &m->entry); + if (m) + { + m->handle = FindFirstFile(mask, &m->entry); /* error handling happens in os_matchnext() below */ m->is_first = 1; lua_pushlightuserdata(L, m); + } + else + { + lua_pushnil(L); + } return 1; } @@ -57,9 +75,8 @@ int os_matchisfile(lua_State* L) int os_matchnext(lua_State* L) { MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1); - if (m->handle == INVALID_HANDLE_VALUE) { + if (m->handle == INVALID_HANDLE_VALUE) return 0; - } while (m) /* loop forever */ { @@ -70,6 +87,10 @@ int os_matchnext(lua_State* L) } m->is_first = 0; + /* Ignore the directory entries for . and .. only */ + if (m->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if (skip_dot_entries(m->entry.cFileName)) + continue; lua_pushboolean(L, 1); return 1; } @@ -167,6 +188,8 @@ int os_matchnext(lua_State* L) while (m->entry != NULL) { const char* name = m->entry->d_name; + /* Ignore the directory entries for . and .. only */ + if (!skip_dot_entries(name)) if (fnmatch(m->mask, name, 0) == 0) { lua_pushboolean(L, 1); diff --git a/src/host/os_uuid.c b/src/host/os_uuid.c index 28be4e8..e3bee6b 100644 --- a/src/host/os_uuid.c +++ b/src/host/os_uuid.c @@ -15,7 +15,9 @@ int os_uuid(lua_State* L) char uuid[38]; #if PLATFORM_WINDOWS - CoCreateGuid((GUID*)bytes); + HRESULT hr = CoCreateGuid((GUID*)bytes); + if (FAILED(hr)) + return 0; #else int result; diff --git a/src/host/path_translate.c b/src/host/path_translate.c index 8996b37..0833341 100644 --- a/src/host/path_translate.c +++ b/src/host/path_translate.c @@ -43,9 +43,11 @@ int path_translate(lua_State* L) lua_newtable(L); lua_pushnil(L); while (lua_next(L, 1)) { - const char* value = luaL_checkstring(L, 4); - translate(buffer, value, sep[0]); - lua_pop(L, 1); + const char* key; + lua_pushvalue(L, 4); // copy the key + key = luaL_checkstring(L, 5); + translate(buffer, key, sep[0]); + lua_pop(L, 2); lua_pushstring(L, buffer); lua_rawseti(L, -3, ++i); diff --git a/src/host/premake.c b/src/host/premake.c index 9e30d50..ac4bc04 100755 --- a/src/host/premake.c +++ b/src/host/premake.c @@ -322,12 +322,22 @@ static int load_file_scripts(lua_State* L) if (lua_isnil(L, -1)) { + /* call os.pathsearch() to locate _premake_main.lua */ + lua_pushcfunction(L, os_pathsearch); + lua_pushstring(L, "_premake_main.lua"); + lua_pushstring(L, "src"); + 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" + "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; } + } /* run the bootstrapping script */ scripts_path = lua_tostring(L, -1); @@ -356,6 +366,10 @@ static int load_file_scripts(lua_State* L) } } +extern const char* builtin_script_fnames[]; + +#define luaL_dobuffer(L, s, n) \ + (luaL_loadbuffer(L, s, strlen(s), n) || lua_pcall(L, 0, LUA_MULTRET, 0)) /** * When running in release mode, the scripts are loaded from a static data @@ -367,16 +381,31 @@ static int load_builtin_scripts(lua_State* L) int i; for (i = 0; builtin_scripts[i]; ++i) { + if (builtin_script_fnames[i]) + { + if (luaL_dobuffer(L, builtin_scripts[i], builtin_script_fnames[i]) != OKAY) + { + printf(ERROR_MESSAGE, lua_tostring(L, -1)); + return !OKAY; + } + } + else + { if (luaL_dostring(L, builtin_scripts[i]) != OKAY) { printf(ERROR_MESSAGE, lua_tostring(L, -1)); return !OKAY; } } + } + + /* in release mode, also 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, 0) != OKAY) + if (lua_pcall(L, 0, 1, -2) != OKAY) { printf(ERROR_MESSAGE, lua_tostring(L, -1)); return !OKAY; diff --git a/tests/actions/vstudio/sln2005/header.lua b/tests/actions/vstudio/sln2005/header.lua index a959677..61aae75 100755 --- a/tests/actions/vstudio/sln2005/header.lua +++ b/tests/actions/vstudio/sln2005/header.lua @@ -76,6 +76,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 ]] +--[[ +VS 2013 seems to add something like: + +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 + +which don't seem to be mandatory, though. +]] end function suite.On2015() @@ -83,14 +91,65 @@ Microsoft Visual Studio Solution File, Format Version 12.00 prepare() test.capture [[ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2015 +# Visual Studio 14 ]] --[[ -VS2015 seems to add: +VS 2015 seems to add something like: VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 +which don't seem to be mandatory, though. +]] + end + + function suite.On2017() + _ACTION = "vs2017" + prepare() + test.capture [[ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 + ]] +--[[ +VS 2017 seems to add something like: + +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 + +which don't seem to be mandatory, though. +]] + end + + function suite.On2019() + _ACTION = "vs2019" + prepare() + test.capture [[ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 16 + ]] +--[[ +VS 2019 seems to add something like: + +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 + +which don't seem to be mandatory, though. +]] + end + + function suite.On2022() + _ACTION = "vs2022" + prepare() + test.capture [[ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 17 + ]] +--[[ +VS 2022 seems to add something like: + +VisualStudioVersion = 17.0.0.0 +MinimumVisualStudioVersion = 10.0.40219.1 + which don't seem to be mandatory, though. ]] end diff --git a/tests/actions/vstudio/vc2010/test_config_props.lua b/tests/actions/vstudio/vc2010/test_config_props.lua index 2970ad4..a5b05e1 100644 --- a/tests/actions/vstudio/vc2010/test_config_props.lua +++ b/tests/actions/vstudio/vc2010/test_config_props.lua @@ -89,3 +89,42 @@ ]] end + + function suite.structureIsCorrect_onDefaultValues_on2017() + _ACTION = "vs2017" + prepare() + test.capture [[ + + Application + true + MultiByte + v141 + + ]] + end + + function suite.structureIsCorrect_onDefaultValues_on2019() + _ACTION = "vs2019" + prepare() + test.capture [[ + + Application + true + MultiByte + v142 + + ]] + end + + function suite.structureIsCorrect_onDefaultValues_on2022() + _ACTION = "vs2022" + prepare() + test.capture [[ + + Application + true + MultiByte + v143 + + ]] + end diff --git a/tests/actions/vstudio/vc2010/test_files.lua b/tests/actions/vstudio/vc2010/test_files.lua index 6cd1a16..330c35e 100755 --- a/tests/actions/vstudio/vc2010/test_files.lua +++ b/tests/actions/vstudio/vc2010/test_files.lua @@ -48,6 +48,7 @@ test.capture [[ + CompileAsC ]] @@ -86,6 +87,7 @@ test.capture [[ + CompileAsC ]] diff --git a/tests/testfx.lua b/tests/testfx.lua index 8342086..5a0f33b 100644 --- a/tests/testfx.lua +++ b/tests/testfx.lua @@ -23,7 +23,7 @@ function test.string_does_not_contain(buffer, expected) if string.find(buffer,expected) then - test.fail("\n==Fail==: Did not expected to find :\n%s\nyet it was found in buffer:\n%s\n", expected,buffer) + test.fail("\n==Fail==: Did not expect to find :\n%s\nyet it was found in buffer:\n%s\n", expected,buffer) end end -- cgit v1.2.3