diff options
-rw-r--r-- | Premake4.vs8.vcproj | 4 | ||||
-rw-r--r-- | premake4.lua | 769 |
2 files changed, 384 insertions, 389 deletions
diff --git a/Premake4.vs8.vcproj b/Premake4.vs8.vcproj index 1a911b2..0e1382e 100644 --- a/Premake4.vs8.vcproj +++ b/Premake4.vs8.vcproj @@ -48,7 +48,6 @@ UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
- ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
DebugInformationFormat="0"
CompileAs="1"
/>
@@ -135,7 +134,6 @@ UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
- ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
DebugInformationFormat="4"
CompileAs="1"
/>
@@ -157,7 +155,6 @@ LinkIncremental="2"
AdditionalLibraryDirectories=""
GenerateDebugInformation="true"
- ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
SubSystem="1"
EntryPointSymbol="mainCRTStartup"
TargetMachine="1"
@@ -220,7 +217,6 @@ UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
- ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
DebugInformationFormat="0"
CompileAs="1"
/>
diff --git a/premake4.lua b/premake4.lua index 0d275bc..92719eb 100644 --- a/premake4.lua +++ b/premake4.lua @@ -12,292 +12,20 @@ ]] local action = _ACTION or "" if _OPTIONS["publish"] then - print "INFO: Creating 'Publish' build solution." - publish = true -end -do - -- This is mainly to support older premake4 builds - if not premake.project.getbasename then - print "Magic happens for old premake4 versions without premake.project.getbasename() ..." - -- override the function to establish the behavior we'd get after patching Premake to have premake.project.getbasename - premake.project.getbasename = function(prjname, pattern) - return pattern:gsub("%%%%", prjname) - end - -- obviously we also need to overwrite the following to generate functioning VS solution files - premake.vstudio.projectfile = function(prj) - local pattern - if prj.language == "C#" then - pattern = "%%.csproj" - else - pattern = iif(_ACTION > "vs2008", "%%.vcxproj", "%%.vcproj") - end - - local fname = premake.project.getbasename(prj.name, pattern) - fname = path.join(prj.location, fname) - return fname - end - -- we simply overwrite the original function on older Premake versions - premake.project.getfilename = function(prj, pattern) - local fname = premake.project.getbasename(prj.name, pattern) - fname = path.join(prj.location, fname) - return path.getrelative(os.getcwd(), fname) - end - end - -- This is mainly to support older premake4 in which CompileAs did not work - -- for VS2010 and newer - if not premake.vstudio.vc2010.individualSourceFile or not premake.vstudio.vc200x.individualSourceFile then - local vc2010 = premake.vstudio.vc2010 - local vc200x = premake.vstudio.vc200x - local tree = premake.tree - print "Magic happens for old premake4 versions faulty CompileAs handling for VS2010 and newer ..." - -- A boilerplate implementation - vc200x.individualSourceFile = function(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 - if cfginfo.isreal then - local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) - - local usePCH = (not prj.flags.NoPCH and prj.pchsource == node.cfg.name) - local isSourceCode = path.iscppfile(fname) - local needsCompileAs = (path.iscfile(fname) ~= premake.project.iscproject(prj)) - - if usePCH or (isSourceCode and needsCompileAs) then - _p(depth, '<FileConfiguration') - _p(depth, '\tName="%s"', cfginfo.name) - _p(depth, '\t>') - _p(depth, '\t<Tool') - _p(depth, '\t\tName="%s"', iif(cfg.system == "Xbox360", - "VCCLX360CompilerTool", - "VCCLCompilerTool")) - if needsCompileAs then - _p(depth, '\t\tCompileAs="%s"', iif(path.iscfile(fname), 1, 2)) - end - - if usePCH then - if cfg.system == "PS3" then - local options = table.join(premake.snc.getcflags(cfg), - premake.snc.getcxxflags(cfg), - cfg.buildoptions) - options = table.concat(options, " "); - options = options .. ' --create_pch="$(IntDir)/$(TargetName).pch"' - _p(depth, '\t\tAdditionalOptions="%s"', premake.esc(options)) - else - _p(depth, '\t\tUsePrecompiledHeader="1"') - end - end - - _p(depth, '\t/>') - _p(depth, '</FileConfiguration>') - end - - end - end - end - vc200x.Files = function(prj) - local tr = premake.project.buildsourcetree(prj) - - tree.traverse(tr, { - -- folders are handled at the internal nodes - onbranchenter = function(node, depth) - _p(depth, '<Filter') - _p(depth, '\tName="%s"', node.name) - _p(depth, '\tFilter=""') - _p(depth, '\t>') - end, - - onbranchexit = function(node, depth) - _p(depth, '</Filter>') - end, - - -- source files are handled at the leaves - onleaf = function(node, depth) - local fname = node.cfg.name - - _p(depth, '<File') - _p(depth, '\tRelativePath="%s"', path.translate(fname, "\\")) - _p(depth, '\t>') - depth = depth + 1 - - vc200x.individualSourceFile(prj, depth, fname, node) - - depth = depth - 1 - _p(depth, '</File>') - end, - }, false, 2) - - end - -- A boilerplate implementation - vc2010.individualSourceFile = function(prj, config_mappings, file) - local configs = prj.solution.vstudio_configs - local translatedpath = path.translate(file.name, "\\") - _p(2,'<ClCompile Include=\"%s\">', translatedpath) - for _, cfginfo in ipairs(configs) do - if config_mappings[cfginfo] and translatedpath == config_mappings[cfginfo] then - _p(3,'<PrecompiledHeader '.. if_config_and_platform() .. '>Create</PrecompiledHeader>', 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,'<CompileAs>%s</CompileAs>', iif(path.iscfile(file.name), 'CompileAsC', 'CompileAsCpp')) - end - _p(2,'</ClCompile>') - end - -- Overriding the function which calls the above - vc2010.compilerfilesgroup = function(prj) - local configs = prj.solution.vstudio_configs - local files = vc2010.getfilegroup(prj, "ClCompile") - if #files > 0 then - local config_mappings = {} - for _, cfginfo in ipairs(configs) do - local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) - if cfg.pchheader and cfg.pchsource and not cfg.flags.NoPCH then - config_mappings[cfginfo] = path.translate(cfg.pchsource, "\\") - end - end - - _p(1,'<ItemGroup>') - for _, file in ipairs(files) do - vc2010.individualSourceFile(prj, config_mappings, file) - end - _p(1,'</ItemGroup>') - end - end - end - -- Make UUID generation for filters deterministic - if os.str2uuid ~= nil then - local vc2010 = premake.vstudio.vc2010 - vc2010.filteridgroup = function(prj) - local filters = { } - local filterfound = false - - for file in premake.project.eachfile(prj) do - -- split the path into its component parts - local folders = string.explode(file.vpath, "/", true) - local path = "" - for i = 1, #folders - 1 do - -- element is only written if there *are* filters - if not filterfound then - filterfound = true - _p(1,'<ItemGroup>') - end - - path = path .. folders[i] - - -- have I seen this path before? - if not filters[path] then - local seed = path .. (prj.uuid or "") - local deterministic_uuid = os.str2uuid(seed) - filters[path] = true - _p(2, '<Filter Include="%s">', path) - _p(3, '<UniqueIdentifier>{%s}</UniqueIdentifier>', deterministic_uuid) - _p(2, '</Filter>') - end - - -- prepare for the next subfolder - path = path .. "\\" - end - end - - if filterfound then - _p(1,'</ItemGroup>') - end - end - end - -- Name the project files after their VS version - local orig_getbasename = premake.project.getbasename - premake.project.getbasename = function(prjname, pattern) - -- The below is used to insert the .vs(8|9|10|11|12|14|15|16|17) into the file names for projects and solutions - if _ACTION then - name_map = {vs2005 = "vs8", vs2008 = "vs9", vs2010 = "vs10", vs2012 = "vs11", vs2013 = "vs12", vs2015 = "vs14", vs2017 = "vs15", vs2019 = "vs16", vs2022 = "vs17"} - if name_map[_ACTION] then - pattern = pattern:gsub("%%%%", "%%%%." .. name_map[_ACTION]) - else - pattern = pattern:gsub("%%%%", "%%%%." .. _ACTION) - end - end - return orig_getbasename(prjname, pattern) - end - -- Older versions of Premake4 fail to set the proper entry point, although they could simply let it out entirely ... - local orig_vc2010_link = premake.vstudio.vc2010.link - premake.vstudio.vc2010.link = function(cfg) - if cfg.flags and cfg.flags.Unicode then - io.capture() - orig_vc2010_link(cfg) - local captured = io.endcapture() - captured = captured:gsub("(<EntryPointSymbol>)(mainCRTStartup)", "%1w%2") - io.write(captured) - else - orig_vc2010_link(cfg) - end - end - local orig_vc200x_VCLinkerTool = premake.vstudio.vc200x.VCLinkerTool - premake.vstudio.vc200x.VCLinkerTool = function(cfg) - if cfg.flags and cfg.flags.Unicode then - io.capture() - orig_vc200x_VCLinkerTool(cfg) - local captured = io.endcapture() - captured = captured:gsub('(EntryPointSymbol=")(mainCRTStartup)', "%1w%2") - io.write(captured) - else - orig_vc200x_VCLinkerTool(cfg) - end - end - premake.vstudio.vc200x.toolmap.VCLinkerTool = premake.vstudio.vc200x.VCLinkerTool - -- Make sure we can generate XP-compatible projects for newer Visual Studio versions - local orig_vc2010_configurationPropertyGroup = premake.vstudio.vc2010.configurationPropertyGroup - premake.vstudio.vc2010.configurationPropertyGroup = function(cfg, cfginfo) - io.capture() - orig_vc2010_configurationPropertyGroup(cfg, cfginfo) - local captured = io.endcapture() - local toolsets = { vs2012 = "v110", vs2013 = "v120", vs2015 = "v140", vs2017 = "v141" } - local toolset = toolsets[_ACTION] - if toolset then - if _OPTIONS["xp"] then - toolset = toolset .. "_xp" - captured = captured:gsub("(</PlatformToolset>)", "_xp%1") - end - end - io.write(captured) - end - -- Override the object directory paths ... don't make them "unique" inside premake4 - local orig_gettarget = premake.gettarget - premake.gettarget = function(cfg, direction, pathstyle, namestyle, system) - local r = orig_gettarget(cfg, direction, pathstyle, namestyle, system) - if (cfg.objectsdir) and (cfg.objdir) then - cfg.objectsdir = cfg.objdir - end - return r - end - -- Silently suppress generation of the .user files ... - local orig_generate = premake.generate - premake.generate = function(obj, filename, callback) - if filename:find('.vcproj.user') or filename:find('.vcxproj.user') then - return - end - orig_generate(obj, filename, callback) - end - -- We want to output the file with UTF-8 BOM - local orig_vc2010_header = premake.vstudio.vc2010.header - premake.vstudio.vc2010.header = function(targets) - io.capture() - orig_vc2010_header(targets) - local captured = io.endcapture() - io.write("\239\187\191") - io.write(captured) - end + print "INFO: Creating 'Publish' build solution." + publish = true end local function transformMN(input) -- transform the macro names for older Visual Studio versions - local new_map = { vs2002 = 0, vs2003 = 0, vs2005 = 0, vs2008 = 0 } - local replacements = { Platform = "PlatformName", Configuration = "ConfigurationName" } - if new_map[action] ~= nil then - for k,v in pairs(replacements) do - if input:find(k) then - input = input:gsub(k, v) - end - end - end - return input + local new_map = { vs2002 = 0, vs2003 = 0, vs2005 = 0, vs2008 = 0 } + local replacements = { Platform = "PlatformName", Configuration = "ConfigurationName" } + if new_map[action] ~= nil then + for k,v in pairs(replacements) do + if input:find(k) then + input = input:gsub(k, v) + end + end + end + return input end -- -- Define the project. Put the release configuration first so it will be the @@ -306,82 +34,82 @@ end -- solution "Premake4" - configurations { "Release", "Debug", "Publish" } - location ( _OPTIONS["to"] ) - - project "Premake4" - local int_dir = "intermediate/" .. action .. "_$(" .. transformMN("Platform") .. ")_$(" .. transformMN("Configuration") .. ")" - uuid "7F000221-EACC-2F4F-A07F-6A5D34AF10D0" - targetname "premake4" - language "C" - kind "ConsoleApp" - objdir (int_dir) - flags { "No64BitChecks", "ExtraWarnings", "StaticRuntime" } - includedirs { "src/host/lua-5.1.4/src" } - defines { "USE_KECCAK" } - - files - { - "*.txt", "**.lua", - "src/**.h", "src/**.c", - "src/host/scripts.c" - } - - excludes - { - "src/premake.lua", - "src/host/lua-5.1.4/src/lua.c", - "src/host/lua-5.1.4/src/luac.c", - "src/host/lua-5.1.4/src/print.c", - "src/host/lua-5.1.4/**.lua", - "src/host/lua-5.1.4/etc/*.c", - "src/host/hgtip.h", - "packages/**", - "samples/**", - "tests/**", - } - - configuration "Debug" - targetdir "bin/debug" - defines "_DEBUG" - flags { "Symbols" } - - configuration "Release or Publish" - targetdir "bin/release" - defines "NDEBUG" - flags { "OptimizeSize" } - - configuration "vs*" - defines { "_CRT_SECURE_NO_WARNINGS" } - - configuration "vs2005" - defines {"_CRT_SECURE_NO_DEPRECATE" } - - configuration "windows" - links { "ole32" } - files { "src/host/premake4.rc" } - - configuration {"windows", "Publish"} - defines { "HAVE_HGTIP", "PREMAKE_VERSION=4.4-wds"} - - configuration "linux or bsd" - defines { "LUA_USE_POSIX", "LUA_USE_DLOPEN" } - links { "m" } - linkoptions { "-rdynamic" } - - configuration "linux" - links { "dl" } - - configuration "macosx" - defines { "LUA_USE_MACOSX" } - links { "CoreServices.framework" } - - configuration { "macosx", "gmake" } - buildoptions { "-mmacosx-version-min=10.4" } - linkoptions { "-mmacosx-version-min=10.4" } - - configuration { "solaris" } - linkoptions { "-Wl,--export-dynamic" } + configurations { "Release", "Debug", "Publish" } + location ( _OPTIONS["to"] ) + + project "Premake4" + local int_dir = "intermediate/" .. action .. "_$(" .. transformMN("Platform") .. ")_$(" .. transformMN("Configuration") .. ")" + uuid "7F000221-EACC-2F4F-A07F-6A5D34AF10D0" + targetname "premake4" + language "C" + kind "ConsoleApp" + objdir (int_dir) + flags { "No64BitChecks", "ExtraWarnings", "StaticRuntime" } + includedirs { "src/host/lua-5.1.4/src" } + defines { "USE_KECCAK" } + + files + { + "*.txt", "**.lua", + "src/**.h", "src/**.c", + "src/host/scripts.c" + } + + excludes + { + "src/premake.lua", + "src/host/lua-5.1.4/src/lua.c", + "src/host/lua-5.1.4/src/luac.c", + "src/host/lua-5.1.4/src/print.c", + "src/host/lua-5.1.4/**.lua", + "src/host/lua-5.1.4/etc/*.c", + "src/host/hgtip.h", + "packages/**", + "samples/**", + "tests/**", + } + + configuration "Debug" + targetdir "bin/debug" + defines "_DEBUG" + flags { "Symbols" } + + configuration "Release or Publish" + targetdir "bin/release" + defines "NDEBUG" + flags { "OptimizeSize" } + + configuration "vs*" + defines { "_CRT_SECURE_NO_WARNINGS" } + + configuration "vs2005" + defines {"_CRT_SECURE_NO_DEPRECATE" } + + configuration "windows" + links { "ole32" } + files { "src/host/premake4.rc" } + + configuration {"windows", "Publish"} + defines { "HAVE_HGTIP", "PREMAKE_VERSION=4.4-wds"} + + configuration "linux or bsd" + defines { "LUA_USE_POSIX", "LUA_USE_DLOPEN" } + links { "m" } + linkoptions { "-rdynamic" } + + configuration "linux" + links { "dl" } + + configuration "macosx" + defines { "LUA_USE_MACOSX" } + links { "CoreServices.framework" } + + configuration { "macosx", "gmake" } + buildoptions { "-mmacosx-version-min=10.4" } + linkoptions { "-mmacosx-version-min=10.4" } + + configuration { "solaris" } + linkoptions { "-Wl,--export-dynamic" } @@ -389,10 +117,10 @@ solution "Premake4" -- A more thorough cleanup. -- - if _ACTION == "clean" then - os.rmdir("bin") - os.rmdir("build") - end + if _ACTION == "clean" then + os.rmdir("bin") + os.rmdir("build") + end @@ -402,15 +130,15 @@ solution "Premake4" -- in preparation for deployment. -- - newoption { - trigger = "to", - value = "path", - description = "Set the output location for the generated files" - } - newoption { - trigger = "xp", - description = "Enable XP-compatible build for newer Visual Studio versions." - } + newoption { + trigger = "to", + value = "path", + description = "Set the output location for the generated files" + } + newoption { + trigger = "xp", + description = "Enable XP-compatible build for newer Visual Studio versions." + } @@ -420,13 +148,13 @@ solution "Premake4" -- a release build. -- - dofile("scripts/embed.lua") + dofile("scripts/embed.lua") - newaction { - trigger = "embed", - description = "Embed scripts in scripts.c; required before release builds", - execute = doembed - } + newaction { + trigger = "embed", + description = "Embed scripts in scripts.c; required before release builds", + execute = doembed + } -- @@ -435,10 +163,281 @@ solution "Premake4" -- - dofile("scripts/release.lua") + dofile("scripts/release.lua") - newaction { - trigger = "release", - description = "Prepare a new release (incomplete)", - execute = dorelease - } + newaction { + trigger = "release", + description = "Prepare a new release (incomplete)", + execute = dorelease + } + +--[[ + This part of the premake4.lua modifies the core premake4 behavior a little. + + It does the following (in order of appearence below): + + - New option --sdkver to override <WindowsTargetPlatformVersion> on modern VS + - New option --clang to request ClangCL toolset on modern VS + - New option --xp to request XP-compatible toolset on modern VS + - On older premake4 versions it will provide a premake.project.getbasename + function, furthermore two other functions get patched to make use of it + - premake.project.getbasename() gets overridden to insert a marker into the + created file name, based on the chosen action + Example: foobar.vcxproj becomes foobar.vs2022.vcxproj etc ... + The purpose of this exercise is to allow for projects/solutions of several + Visual Studio versions to reside in the same folder + - Options "dotnet" gets removed + - The "platform" option has some allowed values removed + - The "os" option has some allowed values removed + - The actions are trimmed to what we know can work +]] + +newoption { trigger = "sdkver", value = "SDKVER", description = "Allows to override SDK version (VS2015 through VS2022)" } +newoption { trigger = "clang", description = "Allows to use clang-cl as compiler and lld-link as linker (VS2019 and VS2022)" } +newoption { trigger = "xp", description = "Allows to use a supported XP toolset for some VS versions" } + +do + -- This is mainly to support older premake4 builds + if not premake.project.getbasename then + print "Magic happens for old premake4 versions without premake.project.getbasename() ..." + -- override the function to establish the behavior we'd get after patching Premake to have premake.project.getbasename + premake.project.getbasename = function(prjname, pattern) + return pattern:gsub("%%%%", prjname) + end + -- obviously we also need to overwrite the following to generate functioning VS solution files + premake.vstudio.projectfile = function(prj) + local pattern + if prj.language == "C#" then + pattern = "%%.csproj" + else + pattern = iif(_ACTION > "vs2008", "%%.vcxproj", "%%.vcproj") + end + + local fname = premake.project.getbasename(prj.name, pattern) + fname = path.join(prj.location, fname) + return fname + end + -- we simply overwrite the original function on older Premake versions + premake.project.getfilename = function(prj, pattern) + local fname = premake.project.getbasename(prj.name, pattern) + fname = path.join(prj.location, fname) + return path.getrelative(os.getcwd(), fname) + end + end + -- Make UUID generation for filters deterministic + if os.str2uuid ~= nil then + local vc2010 = premake.vstudio.vc2010 + vc2010.filteridgroup = function(prj) + local filters = { } + local filterfound = false + + for file in premake.project.eachfile(prj) do + -- split the path into its component parts + local folders = string.explode(file.vpath, "/", true) + local path = "" + for i = 1, #folders - 1 do + -- element is only written if there *are* filters + if not filterfound then + filterfound = true + _p(1,"<ItemGroup>") + end + + path = path .. folders[i] + + -- have I seen this path before? + if not filters[path] then + local seed = path .. (prj.uuid or "") + local deterministic_uuid = os.str2uuid(seed) + filters[path] = true + _p(2, '<Filter Include="%s">', path) + _p(3, "<UniqueIdentifier>{%s}</UniqueIdentifier>", deterministic_uuid) + _p(2, "</Filter>") + end + + -- prepare for the next subfolder + path = path .. "\\" + end + end + + if filterfound then + _p(1,"</ItemGroup>") + end + end + end + -- Name the project files after their VS version + local orig_getbasename = premake.project.getbasename + premake.project.getbasename = function(prjname, pattern) + -- The below is used to insert the .vs(8|9|10|11|12|14|15|16|17) into the file names for projects and solutions + if _ACTION then + name_map = {vs2005 = "vs8", vs2008 = "vs9", vs2010 = "vs10", vs2012 = "vs11", vs2013 = "vs12", vs2015 = "vs14", vs2017 = "vs15", vs2019 = "vs16", vs2022 = "vs17"} + if name_map[_ACTION] then + pattern = pattern:gsub("%%%%", "%%%%." .. name_map[_ACTION]) + else + pattern = pattern:gsub("%%%%", "%%%%." .. _ACTION) + end + end + return orig_getbasename(prjname, pattern) + end + -- Premake4 sets the PDB file name for the compiler's PDB to the default + -- value used by the linker's PDB. This causes error C1052 on VS2017. Fix it. + -- But this also fixes up certain other areas of the generated project. The idea + -- here is to catch the original _p() invocations, evaluate the arguments and + -- then act based on those, using orig_p() as a standin during a call to the + -- underlying premake.vs2010_vcxproj() function ;-) + local orig_premake_vs2010_vcxproj = premake.vs2010_vcxproj + premake.vs2010_vcxproj = function(prj) + -- The whole stunt below is necessary in order to modify the resource_compile() + -- output. Given it's a local function we have to go through hoops. + local orig_p = _G._p + local besilent = false + -- We patch the global _p() function + _G._p = function(indent, msg, first, ...) + -- Look for non-empty messages and narrow it down by the indent values + if msg ~= nil then + if msg:match("<ProgramDataBaseFileName>[^<]+</ProgramDataBaseFileName>") then + return -- we want to suppress these + end + if indent == 2 then + if msg == '<ClCompile Include=\"%s\">' and first == "delayload-stubs\\ntdll-delayed-stubs.c" then + orig_p(indent, msg, first, ...) -- what was originally supposed to be output + orig_p(indent+1, "<ExcludedFromBuild>true</ExcludedFromBuild>") + return + end + if msg == "<RootNamespace>%s</RootNamespace>" then + local sdkmap = {vs2015 = "8.1", vs2017 = "10.0.17763.0", vs2019 = "10.0", vs2022 = "10.0"} + if (not _ACTION) or (not sdkmap[_ACTION]) then -- should not happen, but tread carefully anyway + orig_p(indent, msg, first, ...) -- what was originally supposed to be output + return + end + local sdkver = _OPTIONS["sdkver"] or sdkmap[_ACTION] + orig_p(indent, msg, first, ...) -- what was originally supposed to be output + orig_p(indent, "<WindowsTargetPlatformVersion>%s</WindowsTargetPlatformVersion>", sdkver) + return + end + if msg == "<PlatformToolset>%s</PlatformToolset>" then + if (_OPTIONS["clang"] ~= nil) and (_ACTION == "vs2017") then + if _OPTIONS["xp"] ~= nil then + print "WARNING: The --clang option takes precedence over --xp, therefore picking v141_clang_c2 toolset." + end + print "WARNING: If you are used to Clang support from VS2019 and newer, be sure to review your choice. It's not the same on older VS versions." + orig_p(indent, msg, "v141_clang_c2") + return + elseif (_OPTIONS["clang"] ~= nil) and (_ACTION >= "vs2019") then + if _OPTIONS["xp"] ~= nil then + print "WARNING: The --clang option takes precedence over --xp, therefore picking ClangCL toolset." + end + orig_p(indent, msg, "ClangCL") + return + elseif _OPTIONS["xp"] ~= nil then + local toolsets = { vs2012 = "v110", vs2013 = "v120", vs2015 = "v140", vs2017 = "v141", vs2019 = "v142", vs2022 = "v143" } + local toolset = toolsets[_ACTION] + if toolset then + if _OPTIONS["xp"] and toolset >= "v141" then + toolset = "v141" -- everything falls back to the VS2017 XP toolset for more recent VS + end + orig_p(indent,"<PlatformToolset>%s_xp</PlatformToolset>", toolset) + return + end + end + end + elseif indent == 3 then + -- This is what vanilla VS would output it as, so let's try to align with that + if msg == "<PrecompiledHeader></PrecompiledHeader>" then + orig_p(indent, "<PrecompiledHeader>") + orig_p(indent, "</PrecompiledHeader>") + return + end + end + end + if not besilent then -- should we be silent (i.e. suppress default output)? + orig_p(indent, msg, first, ...) + end + end + orig_premake_vs2010_vcxproj(prj) + _G._p = orig_p -- restore in any case + end + -- ... same as above but for VS200x this time + local function wrap_remove_pdb_attribute(origfunc) + local fct = function(cfg) + local old_captured = io.captured -- save io.captured state + io.capture() -- this sets io.captured = "" + origfunc(cfg) + local captured = io.endcapture() + assert(captured ~= nil) + captured = captured:gsub('%s+ProgramDataBaseFileName=\"[^"]+\"', "") + if old_captured ~= nil then + io.captured = old_captured .. captured -- restore outer captured state, if any + else + io.write(captured) + end + end + return fct + end + premake.vstudio.vc200x.VCLinkerTool = wrap_remove_pdb_attribute(premake.vstudio.vc200x.VCLinkerTool) + premake.vstudio.vc200x.toolmap.VCLinkerTool = premake.vstudio.vc200x.VCLinkerTool -- this is important as well + premake.vstudio.vc200x.VCCLCompilerTool = wrap_remove_pdb_attribute(premake.vstudio.vc200x.VCCLCompilerTool) + premake.vstudio.vc200x.toolmap.VCCLCompilerTool = premake.vstudio.vc200x.VCCLCompilerTool -- this is important as well + -- Override the object directory paths ... don't make them "unique" inside premake4 + local orig_gettarget = premake.gettarget + premake.gettarget = function(cfg, direction, pathstyle, namestyle, system) + local r = orig_gettarget(cfg, direction, pathstyle, namestyle, system) + if (cfg.objectsdir) and (cfg.objdir) then + cfg.objectsdir = cfg.objdir + end + return r + end + -- Silently suppress generation of the .user files ... + local orig_generate = premake.generate + premake.generate = function(obj, filename, callback) + if filename:find(".vcproj.user") or filename:find(".vcxproj.user") then + return + end + orig_generate(obj, filename, callback) + end + -- Fix up premake.getlinks() to not do stupid stuff with object files we pass + local orig_premake_getlinks = premake.getlinks + premake.getlinks = function(cfg, kind, part) + local origret = orig_premake_getlinks(cfg, kind, part) + local ret = {} + for k,v in ipairs(origret) do + local dep = v:gsub(".obj.lib", ".obj") + dep = dep:gsub(".lib.lib", ".lib") + table.insert(ret, dep) + end + return ret + end + + -- Remove an option altogether or some otherwise accepted values for that option + local function remove_allowed_optionvalues(option, values_toremove) + if premake.option.list[option] ~= nil then + if values_toremove == nil then + premake.option.list[option] = nil + return + end + if premake.option.list.platform["allowed"] ~= nil then + local allowed = premake.option.list[option].allowed + for i = #allowed, 1, -1 do + if values_toremove[allowed[i][1]] then + table.remove(allowed, i) + end + end + end + end + end + + local function remove_action(action) + if premake.action.list[action] ~= nil then + premake.action.list[action] = nil + end + end + + -- Remove some unwanted/outdated options + remove_allowed_optionvalues("dotnet") + remove_allowed_optionvalues("platform", { universal = 0, universal32 = 0, universal64 = 0, ps3 = 0, xbox360 = 0, }) + remove_allowed_optionvalues("os") -- ... , { bsd = 0, haiku = 0, linux = 0, macosx = 0, solaris = 0, } + remove_allowed_optionvalues("cc") + -- ... and actions (mainly because they are untested) + for k,v in pairs({codeblocks = 0, codelite = 0, xcode3 = 0, xcode4 = 0, vs2002 = 0, vs2003 = 0, }) do -- vs2005 = 0, vs2008 = 0, vs2010 = 0, vs2012 = 0, vs2013 = 0 + remove_action(k) + end +end |