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', 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', 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', name, condition, value, name) else - format = string.format('<%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', name, value, name) + p.w(format, table.unpack(arg)) + end end