Resource defines not applied for VC201x projects (at all!)
assarbad opened this issue · 3 comments
The current code, namely vs2010_vcxproj.lua doesn't use resdefines
at all. I just noticed this by accident. I'll definitely write a Lua-only workaround for this, but I still need to set up myself to contribute back changes from my (still Mercurial based) repo.
Unfortunately the function preprocessor
is a local
one, which makes the planned workaround more cumbersome than it would otherwise be. Likely another case where io.capture()
is called for.
do -- local scope ...
-- Borrowed from setLocal() at https://stackoverflow.com/a/22752379
local function getLocal(stkidx, name)
local index = 1
while true do
local var_name, var_value = debug.getlocal(stkidx, index)
if not var_name then break end
if var_name == name then
return var_value
end
index = index + 1
end
end
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, ...)
-- Look for indent values of 2
if indent == 2 and msg ~= nil then
-- ... with msg value of <ResourceCompile>
if msg == "<ResourceCompile>" then
local cfg = getLocal(3, "e") -- with LuaSrcDiet
if cfg == nil then
cfg = getLocal(3, "cfg") -- without LuaSrcDiet
end
assert(type(cfg) == "table" and cfg["resdefines"] ~= nil)
orig_p(indent, msg, ...) -- spit the original line out
local indent = indent + 1
if #cfg.defines > 0 or #cfg.resdefines then
local defines = table.join(cfg.defines, cfg.resdefines)
orig_p(indent,'<PreprocessorDefinitions>%s;%%(PreprocessorDefinitions)</PreprocessorDefinitions>'
,premake.esc(table.concat(premake.esc(defines), ";")))
else
orig_p(indent,'<PreprocessorDefinitions></PreprocessorDefinitions>')
end
if #cfg.includedirs > 0 or #cfg.resincludedirs > 0 then
local dirs = table.join(cfg.includedirs, cfg.resincludedirs)
orig_p(indent,'<AdditionalIncludeDirectories>%s;%%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>'
,premake.esc(path.translate(table.concat(dirs, ";"), '\\')))
end
besilent = true
end
-- ... or msg value of <ResourceCompile>
if msg == "</ResourceCompile>" then
besilent = false
-- fall through
end
end
if not besilent then -- should we be silent?
orig_p(indent, msg, ...)
end
end
-- do whatever else is called for ...
orig_premake_vs2010_vcxproj(prj)
_G._p = orig_p -- restore in any case
end
end
Other solutions are obviously possible, notably io.capture()
, but I have noticed that this method seems to be lighter on resources, despite using introspection features.
We're looking for the name "e" first, because LuaSrcDiet shortens the variable name "cfg" to that. If we fail, we try again with the original name. After that we assert that it's non-nil
and contains the key resdefines
... voila, problem solved.
If you submit this as a PR (as a direct modification of the core core, rather than a patch) I'll be happy to merge it.
Hey @starkos , of course this above solution makes no sense as PR. Because it should be fixed in Premake4 so that above workaround isn't necessary anymore (simply by patching vs2010_vcxproj.lua
). What I'm trying with these workarounds is to patch the behavior of Premake4 with what I have, without having to recompile the binary all the time. And also in absence of some real patch management it's kinda hard to keep track. Premake would need something like in Vim where you can check which patches or features are available and execute something based on that condition. In the past I've done this by keeping some of the new symbols global so I could look out for them in my scripts and keep my scripts compatible across a wide range of Premake4 patch levels. No idea if you have something like this patch management planned for Premake5, but it'd definitely make sense to have this.
I'll try to submit the patches I have ready in my fork until the end of the year. No promises, though.
Until then I am keeping that cookbook article in the Wiki up-to-date. I hope that this will be valuable to others running into similar issues.