Merge pull request #619 from Blizzard/per-file-config-C#

Add support in csproj backend to add files to certain configurations.
This commit is contained in:
Samuel Surtees 2016-11-23 14:05:38 +10:00 committed by GitHub
commit 4a0cebf0af
4 changed files with 125 additions and 66 deletions

View File

@ -114,82 +114,106 @@
end end
function cs2005.dofile(node, cfg, condition)
local filecfg = fileconfig.getconfig(node, cfg)
if filecfg then
local fname = path.translate(node.relpath)
-- Files that live outside of the project tree need to be "linked"
-- and provided with a project relative pseudo-path. Check for any
-- leading "../" sequences and, if found, remove them and mark this
-- path as external.
local link, count = node.relpath:gsub("%.%.%/", "")
local external = (count > 0)
-- Try to provide a little bit of flexibility by allowing virtual
-- paths for external files. Would be great to support them for all
-- files but Visual Studio chokes if file is already in project area.
if external and node.vpath ~= node.relpath then
link = node.vpath
end
-- Deduce what, if any, special attributes are required for this file.
-- For example, forms may have related source, designer, and resource
-- files which need to be associated.
local info = dotnet.fileinfo(filecfg)
-- Process any sub-elements required by this file; choose the write
-- element form to use based on the results.
local contents = premake.capture(function ()
-- Try to write file-level elements in the same order as Visual Studio
local elements = {
"AutoGen",
"CopyToOutputDirectory",
"DesignTime",
"DependentUpon",
"DesignTimeSharedInput",
"Generator",
"LastGenOutput",
"SubType",
}
for _, el in ipairs(elements) do
local value = info[el]
if value then
_p(3,"<%s>%s</%s>", el, value, el)
end
end
if info.action == "EmbeddedResource" and cfg.customtoolnamespace then
_p(3,"<CustomToolNamespace>%s</CustomToolNamespace>", cfg.customtoolnamespace)
end
end)
if #contents > 0 or external then
_p(2,'<%s%s Include="%s">', info.action, condition, fname)
if external then
_p(3,'<Link>%s</Link>', path.translate(link))
end
if #contents > 0 then
_p("%s", contents)
end
_p(2,'</%s>', info.action)
else
_p(2,'<%s%s Include="%s" />', info.action, condition, fname)
end
end
end
-- --
-- Write out the source files item group. -- Write out the source files item group.
-- --
function cs2005.files(prj) function cs2005.files(prj)
-- Some settings applied at project level; can't be changed in cfg local firstcfg = project.getfirstconfig(prj)
local cfg = project.getfirstconfig(prj)
-- Try to write file-level elements in the same order as Visual Studio
local elements = {
"AutoGen",
"CopyToOutputDirectory",
"DesignTime",
"DependentUpon",
"DesignTimeSharedInput",
"Generator",
"LastGenOutput",
"SubType",
}
local tr = project.getsourcetree(prj) local tr = project.getsourcetree(prj)
premake.tree.traverse(tr, { premake.tree.traverse(tr, {
onleaf = function(node, depth) onleaf = function(node, depth)
local filecfg = fileconfig.getconfig(node, cfg) -- test if all fileinfo's are going to be the same for each config.
local fname = path.translate(node.relpath) local allsame = true
local first = nil
for cfg in project.eachconfig(prj) do
local filecfg = fileconfig.getconfig(node, cfg)
local info = dotnet.fileinfo(filecfg)
-- Files that live outside of the project tree need to be "linked" if first == nil then
-- and provided with a project relative pseudo-path. Check for any first = info
-- leading "../" sequences and, if found, remove them and mark this elseif not table.equals(first, info) then
-- path as external. allsame = false
end
local link, count = node.relpath:gsub("%.%.%/", "")
local external = (count > 0)
-- Try to provide a little bit of flexibility by allowing virtual
-- paths for external files. Would be great to support them for all
-- files but Visual Studio chokes if file is already in project area.
if external and node.vpath ~= node.relpath then
link = node.vpath
end end
-- Deduce what, if any, special attributes are required for this file. -- output to csproj.
-- For example, forms may have related source, designer, and resource if allsame then
-- files which need to be associated. cs2005.dofile(node, firstcfg, '')
local info = dotnet.fileinfo(filecfg)
-- Process any sub-elements required by this file; choose the write
-- element form to use based on the results.
local contents = premake.capture(function ()
for _, el in ipairs(elements) do
local value = info[el]
if value then
_p(3,"<%s>%s</%s>", el, value, el)
end
end
end)
if #contents > 0 or external then
_p(2,'<%s Include="%s">', info.action, fname)
if external then
_p(3,'<Link>%s</Link>', path.translate(link))
end
if #contents > 0 then
_p("%s", contents)
end
if info.action == "EmbeddedResource" and cfg.customtoolnamespace then
_p(3,"<CustomToolNamespace>%s</CustomToolNamespace>", cfg.customtoolnamespace)
end
_p(2,'</%s>', info.action)
else else
_p(2,'<%s Include="%s" />', info.action, fname) for cfg in project.eachconfig(prj) do
cs2005.dofile(node, cfg, ' ' .. cs2005.condition(cfg))
end
end end
end end
}, false) }, false)
end end
@ -417,9 +441,9 @@
-- --
function cs2005.propertyGroup(cfg) function cs2005.propertyGroup(cfg)
local platform = vstudio.projectPlatform(cfg) p.push('<PropertyGroup %s>', cs2005.condition(cfg))
local arch = cs2005.arch(cfg) local arch = cs2005.arch(cfg)
p.push('<PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' ">', platform, arch)
if arch ~= "AnyCPU" or _ACTION > "vs2008" then if arch ~= "AnyCPU" or _ACTION > "vs2008" then
p.x('<PlatformTarget>%s</PlatformTarget>', arch) p.x('<PlatformTarget>%s</PlatformTarget>', arch)
end end
@ -450,7 +474,9 @@
-- --
function cs2005.condition(cfg) function cs2005.condition(cfg)
return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', premake.esc(vstudio.projectConfig(cfg))) local platform = vstudio.projectPlatform(cfg)
local arch = cs2005.arch(cfg)
return string.format('Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' "', platform, arch)
end end

View File

@ -514,3 +514,21 @@
end end
end) end)
end end
--
-- Compares two tables.
--
function table.equals(a, b)
for k, v in pairs(a) do
if b[k] ~= v then
return false
end
end
for k, v in pairs(b) do
if a[k] ~= v then
return false
end
end
return true
end

View File

@ -30,6 +30,9 @@
function dotnet.fileinfo(fcfg) function dotnet.fileinfo(fcfg)
local info = {} local info = {}
if (fcfg == nil) then
return info
end
local fname = fcfg.abspath local fname = fcfg.abspath
local ext = path.getextension(fname):lower() local ext = path.getextension(fname):lower()
@ -41,7 +44,7 @@
info.action = "Compile" info.action = "Compile"
elseif fcfg.buildaction == "Embed" or ext == ".resx" then elseif fcfg.buildaction == "Embed" or ext == ".resx" then
info.action = "EmbeddedResource" info.action = "EmbeddedResource"
elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" then elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" or ext == ".dll" then
info.action = "Content" info.action = "Content"
elseif fcfg.buildaction == "Resource" then elseif fcfg.buildaction == "Resource" then
info.action = "Resource" info.action = "Resource"

View File

@ -46,6 +46,18 @@
end end
function suite.PerConfigFile()
files { "Hello.cs" }
configuration { 'debug' }
files { "HelloTwo.cs" }
prepare()
test.capture [[
<Compile Include="Hello.cs" />
<Compile Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' " Include="HelloTwo.cs" />
]]
end
-- --
-- Test file dependencies -- Test file dependencies
-- --