Port VS200x from walksources() to trees

This commit is contained in:
Jason Perkins 2011-01-22 14:51:54 -05:00
parent 02aa571d53
commit ad515a7ac3
6 changed files with 252 additions and 151 deletions

View File

@ -59,17 +59,6 @@
end
--
-- Process the solution's list of configurations and platforms, creates a list
-- of build configuration/platform pairs in a Visual Studio compatible format.
--
-- @param sln
-- The solution containing the configuration and platform lists.
-- @param with_pseudo
-- If true, Visual Studio's "Any CPU" and "Mixed Platforms" platforms will
-- be added for .NET and mixed mode solutions.
--
--
-- Process the solution's list of configurations and platforms, creates a list
-- of build configuration/platform pairs in a Visual Studio compatible format.
@ -181,74 +170,6 @@
--
-- Write out entries for the files element; called from premake.walksources().
-- (this should probably go in vs200x_vcproj.lua)
--
local function output(indent, value)
-- io.write(indent .. value .. "\r\n")
_p(indent .. value)
end
local function attrib(indent, name, value)
-- io.write(indent .. "\t" .. name .. '="' .. value .. '"\r\n')
_p(indent .. "\t" .. name .. '="' .. value .. '"')
end
function _VS.files(prj, fname, state, nestlevel)
local indent = string.rep("\t", nestlevel + 2)
if (state == "GroupStart") then
output(indent, "<Filter")
attrib(indent, "Name", path.getname(fname))
attrib(indent, "Filter", "")
output(indent, "\t>")
elseif (state == "GroupEnd") then
output(indent, "</Filter>")
else
output(indent, "<File")
attrib(indent, "RelativePath", path.translate(fname, "\\"))
output(indent, "\t>")
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 == fname)
if (usePCH) then
output(indent, "\t<FileConfiguration")
attrib(indent, "\tName", cfginfo.name)
output(indent, "\t\t>")
output(indent, "\t\t<Tool")
attrib(indent, "\t\tName", iif(cfg.system == "Xbox360", "VCCLX360CompilerTool", "VCCLCompilerTool"))
if (usePCH) then
if (cfg.system == "PS3") then
-- TODO: do we really need all the build flags here? Or can we just
-- add the additional option --create_pch, and let the rest of the
-- flags get picked up from the main compiler config block?
local buildoptions = table.join(premake.snc.getcflags(cfg), premake.snc.getcxxflags(cfg), cfg.buildoptions)
local additionalOptions = table.concat(buildoptions, " ");
additionalOptions = additionalOptions .. ' --create_pch="$(IntDir)/$(TargetName).pch"'
attrib(indent, "\t\tAdditionalOptions", premake.esc(additionalOptions))
else
attrib(indent, "\t\tUsePrecompiledHeader", "1")
end
end
output(indent, "\t\t/>")
output(indent, "\t</FileConfiguration>")
end
end
end
output(indent, "</File>")
end
end
--
-- Return the optimization code.
-- (this should probably go in vs200x_vcproj.lua)

View File

@ -1,11 +1,17 @@
--
-- vs200x_vcproj.lua
-- Generate a Visual Studio 2002-2008 C/C++ project.
-- Copyright (c) 2009, 2010 Jason Perkins and the Premake project
-- Copyright (c) 2009-2011 Jason Perkins and the Premake project
--
premake.vstudio.vcproj = { }
local vcproj = premake.vstudio.vcproj
--
-- Set up a namespace for this file
--
premake.vstudio.vcproj = { }
local vcproj = premake.vstudio.vcproj
local tree = premake.tree
--
@ -28,6 +34,71 @@ local vcproj = premake.vstudio.vcproj
_p(3,'>')
end
--
-- Write out the <Files> element.
--
function vcproj.Files(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)
_p(depth, '<File')
_p(depth, '\tRelativePath="%s"', path.translate(node.path, "\\"))
_p(depth, '\t>')
depth = depth + 1
-- 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.path)
if (usePCH) 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 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
_p(depth, '\t/>')
_p(depth, '</FileConfiguration>')
end
end
end
depth = depth - 1
_p(depth, '</File>')
end,
}, false, 2)
end
--
-- Write out the <Platforms> element; ensures that each target platform
@ -650,7 +721,7 @@ local vcproj = premake.vstudio.vcproj
_p(1,'</References>')
_p(1,'<Files>')
premake.walksources(prj, _VS.files)
vcproj.Files(prj)
_p(1,'</Files>')
_p(1,'<Globals>')

View File

@ -143,31 +143,50 @@
-- @param t
-- The tree to traverse.
-- @param fn
-- A collection of callback functions, which may contain:
-- A collection of callback functions, which may contain any or all of the
-- following entries. Entries are called in this order.
--
-- onnode(node, depth) - called on each node encountered
-- onleaf(node, depth) - called only on leaf nodes
-- onbranch(node, depth) - called only on branch nodes
-- onnode - called on each node encountered
-- onbranchenter - called on branches, before processing children
-- onbranch - called only on branch nodes
-- onleaf - called only on leaf nodes
-- onbranchexit - called on branches, after processing children
--
-- Callbacks receive two arguments: the node being processed, and the
-- current traversal depth.
--
-- @param includeroot
-- True to include the root node in the traversal, otherwise it will be skipped.
-- @param initialdepth
-- An optional starting value for the traversal depth; defaults to zero.
--
function premake.tree.traverse(t, fn, includeroot)
function premake.tree.traverse(t, fn, includeroot, initialdepth)
-- forward declare my handlers, which call each other
local donode, dochildren
-- process an individual node
donode = function(node, fn, depth)
if node.isremoved then
return
end
if fn.onnode then
fn.onnode(node, depth)
end
if #node.children > 0 then
if fn.onbranchenter then
fn.onbranchenter(node, depth)
end
if fn.onbranch then
fn.onbranch(node, depth)
end
dochildren(node, fn, depth + 1)
if fn.onbranchexit then
fn.onbranchexit(node, depth)
end
else
if fn.onleaf then
fn.onleaf(node, depth)
@ -175,8 +194,8 @@
end
end
-- this goofy iterator allows nodes to be removed during the traversal
dochildren = function(parent, fn, depth)
-- this goofy iterator allows nodes to be removed during the traversal
local i = 1
while i <= #parent.children do
local node = parent.children[i]
@ -187,9 +206,14 @@
end
end
-- set a default initial traversal depth, if one wasn't set
if not initialdepth then
initialdepth = 0
end
if includeroot then
donode(t, fn, 0)
donode(t, fn, initialdepth)
else
dochildren(t, fn, 0)
dochildren(t, fn, initialdepth)
end
end

View File

@ -490,66 +490,6 @@
]]
end
function suite.Files_OnPCH_OnWindows()
files { "afxwin.cpp" }
pchsource "afxwin.cpp"
prepare()
_VS.files(prj, "afxwin.cpp", "Item", 1)
test.capture [[
<File
RelativePath="afxwin.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
]]
end
function suite.Files_OnPCH_OnXbox360()
files { "afxwin.cpp" }
pchsource "afxwin.cpp"
platforms { "Xbox360" }
prepare()
sln.vstudio_configs = premake.vstudio_buildconfigs(sln)
_VS.files(prj, "afxwin.cpp", "Item", 1)
test.capture [[
<File
RelativePath="afxwin.cpp"
>
<FileConfiguration
Name="Debug|Xbox 360"
>
<Tool
Name="VCCLX360CompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Xbox 360"
>
<Tool
Name="VCCLX360CompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
]]
end
--
-- Floating point flag tests

View File

@ -0,0 +1,144 @@
--
-- tests/actions/vstudio/vs200x/files.lua
-- Validate generation of <files/> block in Visual Studio 200x projects.
-- Copyright (c) 2009-2011 Jason Perkins and the Premake project
--
T.vstudio_200x_files = { }
local suite = T.vstudio_200x_files
local vcproj = premake.vstudio.vcproj
--
-- Setup
--
local sln, prj
function suite.setup()
sln = test.createsolution()
end
local function prepare()
io.capture()
premake.buildconfigs()
prj = premake.solution.getproject(sln, 1)
sln.vstudio_configs = premake.vstudio_buildconfigs(sln)
vcproj.Files(prj)
end
--
-- Test grouping and nesting
--
function suite.SimpleSourceFile()
files { "hello.c" }
prepare()
test.capture [[
<File
RelativePath="hello.c"
>
</File>
]]
end
function suite.SingleFolderLevel()
files { "src/hello.c" }
prepare()
test.capture [[
<Filter
Name="src"
Filter=""
>
<File
RelativePath="src\hello.c"
>
</File>
</Filter>
]]
end
function suite.MultipleFolderLevels()
files { "src/greetings/hello.c" }
prepare()
test.capture [[
<Filter
Name="src"
Filter=""
>
<Filter
Name="greetings"
Filter=""
>
<File
RelativePath="src\greetings\hello.c"
>
</File>
</Filter>
</Filter>
]]
end
--
-- PCH support
--
function suite.OnPCH_OnWindows()
files { "afxwin.cpp" }
pchsource "afxwin.cpp"
prepare()
test.capture [[
<File
RelativePath="afxwin.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
]]
end
function suite.Files_OnPCH_OnXbox360()
files { "afxwin.cpp" }
pchsource "afxwin.cpp"
platforms { "Xbox360" }
prepare()
test.capture [[
<File
RelativePath="afxwin.cpp"
>
<FileConfiguration
Name="Debug|Xbox 360"
>
<Tool
Name="VCCLX360CompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Xbox 360"
>
<Tool
Name="VCCLX360CompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
]]
end

View File

@ -73,6 +73,7 @@
dofile("actions/vstudio/test_vs2010_links.lua")
dofile("actions/vstudio/test_vs2010_filters.lua")
dofile("actions/vstudio/test_vs2010_project_kinds.lua")
dofile("actions/vstudio/vs200x/files.lua")
-- Makefile tests
dofile("actions/make/test_make_escaping.lua")