diff --git a/modules/vstudio/tests/vc2010/test_files.lua b/modules/vstudio/tests/vc2010/test_files.lua
index 69c9ff89..537b1e01 100644
--- a/modules/vstudio/tests/vc2010/test_files.lua
+++ b/modules/vstudio/tests/vc2010/test_files.lua
@@ -104,10 +104,8 @@
Document
- cgc $(InputFile)
- $(InputName).obj
- cgc $(InputFile)
- $(InputName).obj
+ cgc $(InputFile)
+ $(InputName).obj
]]
@@ -123,10 +121,8 @@
Document
- cgc $(InputFile)
- $(InputName).a;$(InputName).b
- cgc $(InputFile)
- $(InputName).a;$(InputName).b
+ cgc $(InputFile)
+ $(InputName).a;$(InputName).b
]]
@@ -143,12 +139,9 @@
Document
- cgc $(InputFile)
- $(InputName).obj
- Compiling shader $(InputFile)
- cgc $(InputFile)
- $(InputName).obj
- Compiling shader $(InputFile)
+ cgc $(InputFile)
+ $(InputName).obj
+ Compiling shader $(InputFile)
]]
@@ -165,12 +158,9 @@
Document
- cgc $(InputFile)
- $(InputName).obj
- common.cg.inc;common.cg.inc2
- cgc $(InputFile)
- $(InputName).obj
- common.cg.inc;common.cg.inc2
+ cgc $(InputFile)
+ $(InputName).obj
+ common.cg.inc;common.cg.inc2
]]
@@ -189,8 +179,7 @@
test.capture [[
- Create
- Create
+ Create
]]
@@ -223,8 +212,7 @@
test.capture [[
- true
- true
+ true
]]
@@ -252,8 +240,7 @@
test.capture [[
- true
- true
+ true
]]
@@ -302,12 +289,9 @@
Document
- true
- cgc $(InputFile)
- $(InputName).obj
- true
- cgc $(InputFile)
- $(InputName).obj
+ true
+ cgc $(InputFile)
+ $(InputName).obj
]]
@@ -349,10 +333,8 @@
Document
- echo $(InputFile)
- $(InputName).obj
- echo $(InputFile)
- $(InputName).obj
+ echo $(InputFile)
+ $(InputName).obj
]]
@@ -369,12 +351,9 @@
Document
- echo $(InputFile)
- $(InputName).obj
- false
- echo $(InputFile)
- $(InputName).obj
- false
+ echo $(InputFile)
+ $(InputName).obj
+ false
]]
@@ -391,12 +370,9 @@
Document
- echo $(InputFile)
- $(InputName).obj
- true
- echo $(InputFile)
- $(InputName).obj
- true
+ echo $(InputFile)
+ $(InputName).obj
+ true
]]
@@ -415,8 +391,7 @@
- $(IntDir)\hello1.obj
- $(IntDir)\hello1.obj
+ $(IntDir)\hello1.obj
]]
@@ -436,8 +411,7 @@
test.capture [[
- ..\include\force1.h;..\include\force2.h
- ..\include\force1.h;..\include\force2.h
+ ..\include\force1.h;..\include\force2.h
]]
@@ -457,8 +431,7 @@
test.capture [[
- /Xc %(AdditionalOptions)
- /Xc %(AdditionalOptions)
+ /Xc %(AdditionalOptions)
]]
@@ -477,7 +450,7 @@
test.capture [[
- Full
+ Full
]]
end
@@ -490,7 +463,7 @@
test.capture [[
- MinSpace
+ MinSpace
]]
end
@@ -502,7 +475,7 @@
test.capture [[
- MaxSpeed
+ MaxSpeed
]]
end
@@ -514,7 +487,7 @@
test.capture [[
- Full
+ Full
]]
end
@@ -526,7 +499,7 @@
test.capture [[
- Disabled
+ Disabled
]]
end
@@ -538,7 +511,7 @@
test.capture [[
- Disabled
+ Disabled
]]
end
@@ -556,7 +529,9 @@
test.capture [[
- true
+ true
+
+
]]
end
@@ -568,7 +543,9 @@
test.capture [[
- false
+ false
+
+
]]
end
@@ -584,8 +561,7 @@
test.capture [[
- NotUsing
- NotUsing
+ NotUsing
]]
@@ -605,8 +581,7 @@
test.capture [[
- IS_CPP;%(PreprocessorDefinitions)
- IS_CPP;%(PreprocessorDefinitions)
+ IS_CPP;%(PreprocessorDefinitions)
]]
@@ -630,8 +605,7 @@
- true
- true
+ true
]]
@@ -671,8 +645,7 @@
test.capture [[
- StreamingSIMDExtensions2
- StreamingSIMDExtensions2
+ StreamingSIMDExtensions2
]]
diff --git a/modules/vstudio/vs2010_vcxproj.lua b/modules/vstudio/vs2010_vcxproj.lua
index b7579c9c..b4257fa8 100644
--- a/modules/vstudio/vs2010_vcxproj.lua
+++ b/modules/vstudio/vs2010_vcxproj.lua
@@ -21,7 +21,7 @@
---
m.elements = {}
-
+ m.conditionalElements = {}
--
-- Generate a Visual Studio 201x C++ project, with support for the new platforms API.
@@ -901,6 +901,95 @@
end
+ function m.configPair(cfg)
+ return vstudio.projectPlatform(cfg) .. "|" .. vstudio.archFromConfig(cfg, true)
+ end
+
+
+ function m.getTotalCfgCount(prj)
+ if prj._totalCfgCount then
+ return prj._totalCfgCount
+ else
+ local result = 0
+ for _ in p.project.eachconfig(prj) do
+ result = result + 1
+ end
+ -- cache result
+ prj._totalCfgCount = result
+ return result
+ end
+ end
+
+
+ function m.indexConditionalElements()
+ local nameMap, nameList, settingList
+ nameMap = {}
+ nameList = {} -- to preserve ordering
+ settingList = {} -- to preserve ordering
+ for _, element in ipairs(m.conditionalElements) do
+ local settingMap = nameMap[element.name]
+ if not settingMap then
+ settingMap = {}
+ nameMap[element.name] = settingMap
+ if not table.contains(nameList, element.name) then
+ table.insert(nameList, element.name)
+ end
+ end
+ --setting will either be value or args
+ local elementSet = settingMap[element.setting]
+ if elementSet then
+ table.insert(elementSet, element)
+ else
+ elementSet = {element}
+ settingMap[element.setting] = elementSet
+ if not table.contains(settingList, element.setting) then
+ table.insert(settingList, element.setting)
+ end
+ end
+ end
+ return nameMap, nameList, settingList
+ end
+
+
+ function m.emitConditionalElements(prj)
+ local keyCount = function(tbl)
+ local count = 0
+ for _ in pairs(tbl) do count = count + 1 end
+ return count
+ end
+
+ local nameMap, nameList, settingList
+ nameMap, nameList, settingList = m.indexConditionalElements()
+
+ local totalCfgCount = m.getTotalCfgCount(prj)
+ for _, name in ipairs(nameList) do
+ local settingMap = nameMap[name]
+ local done = false
+ if keyCount(settingMap)==1 then
+ for _, setting in ipairs(settingList) do
+ local elements = settingMap[setting]
+ if elements~=nil and #elements==totalCfgCount then
+ local element = elements[1]
+ local format = string.format('<%s>%s%s>', name, element.value, name)
+ p.w(format, table.unpack(element.args))
+ done = true
+ end
+ end
+ end
+ if not done then
+ for _, setting in ipairs(settingList) do
+ local elements = settingMap[setting]
+ if elements then
+ for _, element in ipairs(elements) do
+ local format = string.format('<%s %s>%s%s>', name, m.conditionFromConfigText(element.condition), element.value, name)
+ p.w(format, table.unpack(element.args))
+ end
+ end
+ end
+ end
+ end
+ end
+
function m.emitFiles(prj, group, tag, fileFunc, fileCfgFunc, checkFunc)
local files = group.files
if files and #files > 0 then
@@ -910,11 +999,15 @@
local contents = p.capture(function ()
p.push()
p.callArray(fileFunc, cfg, file)
+ m.conditionalElements = {}
for cfg in project.eachconfig(prj) do
local fcfg = fileconfig.getconfig(file, cfg)
if not checkFunc or checkFunc(cfg, fcfg) then
- p.callArray(fileCfgFunc, fcfg, m.condition(cfg))
+ p.callArray(fileCfgFunc, fcfg, m.configPair(cfg))
end
+ end
+ if #m.conditionalElements > 0 then
+ m.emitConditionalElements(prj)
end
p.pop()
end)
@@ -945,17 +1038,19 @@
p.push()
for prop in p.rule.eachProperty(rule) do
local fld = p.rule.getPropertyField(rule, prop)
-
+ m.conditionalElements = {}
for cfg in project.eachconfig(prj) do
local fcfg = fileconfig.getconfig(file, cfg)
if fcfg and fcfg[fld.name] then
local value = p.rule.getPropertyString(rule, prop, fcfg[fld.name])
if value and #value > 0 then
- m.element(prop.name, m.condition(cfg), '%s', value)
+ m.element(prop.name, m.configPair(cfg), '%s', value)
+ end
end
end
+ if #m.conditionalElements > 0 then
+ m.emitConditionalElements(prj)
end
-
end
p.pop()
end)
@@ -1862,12 +1957,11 @@
function m.objectFileName(fcfg)
if fcfg.objname ~= fcfg.basename then
- m.element("ObjectFileName", m.condition(fcfg.config), "$(IntDir)\\%s.obj", fcfg.objname)
+ m.element("ObjectFileName", m.configPair(fcfg.config), "$(IntDir)\\%s.obj", fcfg.objname)
end
end
-
function m.omitDefaultLib(cfg)
if cfg.flags.OmitDefaultLibrary then
m.element("OmitDefaultLibName", nil, "true")
@@ -1875,7 +1969,6 @@
end
-
function m.omitFramePointers(cfg)
if cfg.flags.NoFramePointer then
m.element("OmitFramePointers", nil, "true")
@@ -2279,10 +2372,15 @@
-- Format and return a Visual Studio Condition attribute.
--
- function m.condition(cfg)
- return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', p.esc(vstudio.projectConfig(cfg)))
+ function m.conditionFromConfigText(cfgText)
+ return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', p.esc(cfgText))
end
+ function m.condition(cfg)
+ return m.conditionFromConfigText(vstudio.projectConfig(cfg))
+ end
+
+
--
-- Output an individual project XML element, with an optional configuration
@@ -2301,16 +2399,34 @@
--
function m.element(name, condition, value, ...)
+ local arg = {...}
if select('#',...) == 0 then
value = p.esc(value)
- end
-
- local format
- if condition then
- format = string.format('<%s %s>%s%s>', name, condition, value, name)
else
- format = string.format('<%s>%s%s>', name, value, name)
+ for i = 1, #arg do
+ arg[i] = p.esc(arg[i])
+ end
end
- p.x(format, ...)
+ if condition then
+ --defer output
+ local element = {}
+ element.name = name
+ element.condition = condition
+ element.value = value
+ element.args = arg
+ if ... then
+ if value == '%s' then
+ element.setting = table.concat(arg)
+ else
+ element.setting = value .. table.concat(arg)
+ end
+ else
+ element.setting = element.value
+ end
+ table.insert(m.conditionalElements, element)
+ else
+ local format = string.format('<%s>%s%s>', name, value, name)
+ p.w(format, table.unpack(arg))
+ end
end