Add support in csproj backend to add files to certain configurations.

This commit is contained in:
Tom van Dijck 2016-09-01 16:28:34 -07:00
parent 24f2da8842
commit 5bb7c54e3f
4 changed files with 125 additions and 66 deletions

View File

@ -114,82 +114,106 @@
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.
--
function cs2005.files(prj)
-- Some settings applied at project level; can't be changed in cfg
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 firstcfg = project.getfirstconfig(prj)
local tr = project.getsourcetree(prj)
premake.tree.traverse(tr, {
onleaf = function(node, depth)
local filecfg = fileconfig.getconfig(node, cfg)
local fname = path.translate(node.relpath)
-- test if all fileinfo's are going to be the same for each config.
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"
-- 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
if first == nil then
first = info
elseif not table.equals(first, info) then
allsame = false
end
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 ()
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)
-- output to csproj.
if allsame then
cs2005.dofile(node, firstcfg, '')
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
}, false)
end
@ -417,9 +441,9 @@
--
function cs2005.propertyGroup(cfg)
local platform = vstudio.projectPlatform(cfg)
p.push('<PropertyGroup %s>', cs2005.condition(cfg))
local arch = cs2005.arch(cfg)
p.push('<PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' ">', platform, arch)
if arch ~= "AnyCPU" or _ACTION > "vs2008" then
p.x('<PlatformTarget>%s</PlatformTarget>', arch)
end
@ -450,7 +474,9 @@
--
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

View File

@ -514,3 +514,21 @@
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)
local info = {}
if (fcfg == nil) then
return info
end
local fname = fcfg.abspath
local ext = path.getextension(fname):lower()
@ -41,7 +44,7 @@
info.action = "Compile"
elseif fcfg.buildaction == "Embed" or ext == ".resx" then
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"
elseif fcfg.buildaction == "Resource" then
info.action = "Resource"

View File

@ -46,6 +46,18 @@
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
--