Snapshot recent project format changesMore reconciliation with Visual Studio project formats:

- fix dummy configurations for makefile projects
- remove manifest and app verifier tools from static library configurations
- improve sorting of source tree (still needs work)
This commit is contained in:
Jason Perkins 2013-05-21 11:55:00 -04:00
parent e0e4b23a5d
commit 01531cde9e
5 changed files with 128 additions and 33 deletions

View File

@ -22,41 +22,64 @@
vc200x.xmlElement() vc200x.xmlElement()
vc200x.visualStudioProject(prj) vc200x.visualStudioProject(prj)
-- output the list of configuration/architecture pairs used by -- Output the list of configuration/architecture pairs used by the project.
-- the project; sends back list of unique architectures -- Returns the set of unique architectures, to be used in the configuration
-- enumeration loop below.
local architectures = vc200x.platforms(prj) local architectures = vc200x.platforms(prj)
if _ACTION > "vs2003" then vc200x.toolFiles(prj)
_p(1,'<ToolFiles>')
_p(1,'</ToolFiles>') _p(1,'<Configurations>')
end
-- Visual Studio requires each configuration to be paired up with each -- Visual Studio requires each configuration to be paired up with each
-- architecture, even if the pairing doesn't make any sense (i.e. Win32 -- architecture, even if the pairing doesn't make any sense (i.e. Win32
-- DLL DCRT|PS3). I already have a list of all the unique architectures; -- DLL DCRT|PS3). Start by finding the names of all of the configurations
-- make a list of configuration-architecture pairs used by the project. -- that actually are in the project; I'll use this to help identify the
-- configurations that *aren't* in the project below.
local prjcfgs = {} local prjcfgs = {}
for cfg in project.eachconfig(prj) do for cfg in project.eachconfig(prj) do
local cfgname = vstudio.projectConfig(cfg) local cfgname = vstudio.projectConfig(cfg)
prjcfgs[cfgname] = cfgname prjcfgs[cfgname] = true
end end
_p(1,'<Configurations>') -- Now enumerate all of the configurations in the project and write
-- out their <Configuration> blocks.
for cfg in project.eachconfig(prj) do for cfg in project.eachconfig(prj) do
local prjcfg = vstudio.projectConfig(cfg) local prjcfg = vstudio.projectConfig(cfg)
-- Visual Studio wants the architectures listed in a specific
-- order, so enumerate them that way.
for _, arch in ipairs(architectures) do for _, arch in ipairs(architectures) do
local tstcfg = vstudio.projectConfig(cfg, arch) local tstcfg = vstudio.projectConfig(cfg, arch)
-- Does this architecture match the one in the project config
-- that I'm trying to write? If so, go ahead and output the
-- full <Configuration> block.
if prjcfg == tstcfg then if prjcfg == tstcfg then
-- this is a real project configuration -- this is a real project configuration
vc200x.configuration(cfg) vc200x.configuration(cfg)
vc200x.tools(cfg) vc200x.tools(cfg)
_p(2,'</Configuration>') _p(2,'</Configuration>')
-- Otherwise, check the list of valid configurations I built
-- earlier. If this configuration is in the list, then I will
-- get to it on another pass of this loop. If it is not in
-- the list, then it isn't really part of the project, and I
-- need to output a dummy configuration in its place.
elseif not prjcfgs[tstcfg] then elseif not prjcfgs[tstcfg] then
-- this is a fake config to make VS happy -- this is a fake config to make VS happy
vc200x.emptyConfiguration(cfg, arch) vc200x.emptyConfiguration(cfg, arch)
end end
end end
end end
_p(1,'</Configurations>') _p(1,'</Configurations>')
_p(1,'<References>') _p(1,'<References>')
@ -103,7 +126,12 @@
end end
if isWin then if isWin then
if _ACTION > "vs2003" and not isMakefile then
-- Technically, this should be skipped for pure makefile projects that
-- do not contain any empty configurations. But I need to figure out a
-- a good way to check the empty configuration bit first.
if _ACTION > "vs2003" then
_x(1,'RootNamespace="%s"', prj.name) _x(1,'RootNamespace="%s"', prj.name)
end end
@ -192,7 +220,7 @@
_p(3,'ConfigurationType="1"') _p(3,'ConfigurationType="1"')
_p(3,'>') _p(3,'>')
local tools = vc200x.toolsForConfig(cfg) local tools = vc200x.toolsForConfig(cfg, true)
for _, tool in ipairs(tools) do for _, tool in ipairs(tools) do
vc200x.tool(tool) vc200x.tool(tool)
end end
@ -207,13 +235,19 @@
-- --
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- ---
-- Return the list of tools required to build a specific configuration. -- Return the list of tools required to build a specific configuration.
-- Each tool gets represented by an XML element in the project file. -- Each tool gets represented by an XML element in the project file.
--
-- @param cfg
-- The configuration being written.
-- @param isEmptyCfg
-- If true, the list is for the generation of an empty or dummy
-- configuration block; in this case different rules apply.
-- --
function vc200x.toolsForConfig(cfg) function vc200x.toolsForConfig(cfg, isEmptyCfg)
if cfg.kind == premake.MAKEFILE then if cfg.kind == premake.MAKEFILE and not isEmptyCfg then
return { return {
"VCNMakeTool" "VCNMakeTool"
} }
@ -329,6 +363,13 @@
end end
function vc200x.VCAppVerifierTool(cfg)
if cfg.kind ~= premake.STATICLIB then
vc200x.tool("VCAppVerifierTool")
end
end
function vc200x.VCCLCompilerTool(cfg) function vc200x.VCCLCompilerTool(cfg)
_p(3,'<Tool') _p(3,'<Tool')
vc200x.compilerToolName(cfg) vc200x.compilerToolName(cfg)
@ -581,6 +622,10 @@
function vc200x.VCManifestTool(cfg) function vc200x.VCManifestTool(cfg)
if cfg.kind == premake.STATICLIB then
return
end
local manifests = {} local manifests = {}
for _, fname in ipairs(cfg.files) do for _, fname in ipairs(cfg.files) do
if path.getextension(fname) == ".manifest" then if path.getextension(fname) == ".manifest" then
@ -695,6 +740,7 @@
vc200x.toolmap = { vc200x.toolmap = {
DebuggerTool = vc200x.DebuggerTool, DebuggerTool = vc200x.DebuggerTool,
VCAppVerifierTool = vc200x.VCAppVerifierTool,
VCCLCompilerTool = vc200x.VCCLCompilerTool, VCCLCompilerTool = vc200x.VCCLCompilerTool,
VCLinkerTool = vc200x.VCLinkerTool, VCLinkerTool = vc200x.VCLinkerTool,
VCManifestTool = vc200x.VCManifestTool, VCManifestTool = vc200x.VCManifestTool,
@ -716,7 +762,16 @@
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
function vc200x.files(prj) function vc200x.files(prj)
local tr = project.getsourcetree(prj) local tr = project.getsourcetree(prj, function(a,b)
local aSortName = a.name
local bSortName = b.name
-- Only file nodes have a relpath field; folder nodes do not
if a.relpath then aSortName = a.relpath:gsub("%.%.%/", "") end
if b.relpath then bSortName = b.relpath:gsub("%.%.%/", "") end
return aSortName < bSortName
end)
premake.tree.traverse(tr, { premake.tree.traverse(tr, {
@ -1054,6 +1109,14 @@
end end
function vc200x.toolFiles(prj)
if _ACTION > "vs2003" then
_p(1,'<ToolFiles>')
_p(1,'</ToolFiles>')
end
end
function vc200x.usePrecompiledHeader(filecfg, depth) function vc200x.usePrecompiledHeader(filecfg, depth)
local cfg = filecfg.config local cfg = filecfg.config
if cfg.pchsource == filecfg.abspath and if cfg.pchsource == filecfg.abspath and

View File

@ -169,14 +169,17 @@
-- --
-- @param tr -- @param tr
-- The tree to sort. -- The tree to sort.
-- @param fn
-- An optional comparator function.
-- --
function tree.sort(tr) function tree.sort(tr, fn)
if not fn then
fn = function(a,b) return a.name < b.name end
end
tree.traverse(tr, { tree.traverse(tr, {
onnode = function(node) onnode = function(node)
table.sort(node.children, function(a,b) table.sort(node.children, fn)
return a.name < b.name
end)
end end
}, true) }, true)
end end

View File

@ -609,6 +609,8 @@
-- --
-- @param prj -- @param prj
-- The project to query. -- The project to query.
-- @param sorter
-- An optional comparator function for the sorting pass.
-- @return -- @return
-- A tree object containing the source file hierarchy. Leaf nodes -- A tree object containing the source file hierarchy. Leaf nodes
-- representing the individual files contain the fields: -- representing the individual files contain the fields:
@ -621,7 +623,7 @@
-- name - the directory or file name represented by the node -- name - the directory or file name represented by the node
-- --
function project.getsourcetree(prj) function project.getsourcetree(prj, sorter)
-- make sure I have the project, and not it's root configuration -- make sure I have the project, and not it's root configuration
prj = prj.project or prj prj = prj.project or prj
@ -650,24 +652,24 @@
-- The tree represents the logical source code tree to be displayed -- The tree represents the logical source code tree to be displayed
-- in the IDE, not the physical organization of the file system. So -- in the IDE, not the physical organization of the file system. So
-- virtual paths are used when adding nodes. -- virtual paths are used when adding nodes.
local node = premake.tree.add(tr, fcfg.vpath, function(node) local node = premake.tree.add(tr, fcfg.vpath)
-- ...but when a real file system path is used, store it so that
-- an association can be made in the IDE
if fcfg.vpath == fcfg.relpath then
node.realpath = node.path
end
end)
-- Store full file configuration in file (leaf) nodes -- Store full file configuration in file (leaf) nodes
for key, value in pairs(fcfg) do for key, value in pairs(fcfg) do
node[key] = value node[key] = value
end end
-- ...but when a real file system path is used, store it so that
-- an association can be made in the IDE
if fcfg.vpath == fcfg.relpath then
node.realpath = node.path
end
prj.fileconfigs[node.abspath] = node prj.fileconfigs[node.abspath] = node
end end
premake.tree.trimroot(tr) premake.tree.trimroot(tr)
premake.tree.sort(tr) premake.tree.sort(tr, sorter)
-- cache result and return -- cache result and return
prj.sourcetree = tr prj.sourcetree = tr

View File

@ -134,10 +134,34 @@
-- --
-- Makefile projects set new keyword and drop the root namespace. -- Makefile projects set new keyword and drop the root namespace. But I
-- can't get this working yet; need to figure out a better way to test
-- for empty configurations in the project first.
-- --
function suite.keywordIsCorrect_onMakefile() -- function suite.keywordIsCorrect_onMakefile()
-- kind "Makefile"
-- prepare()
-- test.capture [[
--<VisualStudioProject
-- ProjectType="Visual C++"
-- Version="9.00"
-- Name="MyProject"
-- ProjectGUID="{AE61726D-187C-E440-BD07-2556188A6565}"
-- Keyword="MakeFileProj"
-- TargetFrameworkVersion="196613"
-- >
-- ]]
-- end
---
-- Makefile projects which do not support all of the solution configurations
-- add back the RootNamespace element.
---
function suite.keywordIsCorrect_onMakefileWithMixedConfigs()
removeconfigurations { "Release" }
kind "Makefile" kind "Makefile"
prepare() prepare()
test.capture [[ test.capture [[
@ -146,8 +170,10 @@
Version="9.00" Version="9.00"
Name="MyProject" Name="MyProject"
ProjectGUID="{AE61726D-187C-E440-BD07-2556188A6565}" ProjectGUID="{AE61726D-187C-E440-BD07-2556188A6565}"
RootNamespace="MyProject"
Keyword="MakeFileProj" Keyword="MakeFileProj"
TargetFrameworkVersion="196613" TargetFrameworkVersion="196613"
> >
]] ]]
end end

View File

@ -14,7 +14,7 @@
-- --
local tr local tr
function suite.setup() function suite.setup()
tr = tree.new() tr = tree.new()
end end
@ -99,7 +99,7 @@
test.isequal("13", r) test.isequal("13", r)
end end
function suite.Remove_WorksInTraversal() function suite.Remove_WorksInTraversal()
tree.add(tr, "Root/1") tree.add(tr, "Root/1")
tree.add(tr, "Root/2") tree.add(tr, "Root/2")
@ -158,6 +158,7 @@
]] ]]
end end
-- --
-- Should trim to first level with multiple items. -- Should trim to first level with multiple items.
-- --