2012-08-01 19:28:21 +00:00
--
-- vs2010_vcxproj.lua
-- Generate a Visual Studio 201x C/C++ project.
2015-07-15 20:50:59 +00:00
-- Copyright (c) 2009-2015 Jason Perkins and the Premake project
2012-08-01 19:28:21 +00:00
--
2012-11-27 15:18:06 +00:00
premake.vstudio . vc2010 = { }
2013-07-12 15:07:26 +00:00
2014-02-08 15:44:57 +00:00
local p = premake
local vstudio = p.vstudio
local project = p.project
local config = p.config
local fileconfig = p.fileconfig
local tree = p.tree
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
local m = p.vstudio . vc2010
2012-08-01 19:28:21 +00:00
2013-04-25 15:45:44 +00:00
---
2014-05-22 13:55:28 +00:00
-- Add namespace for element definition lists for premake.callArray()
2013-04-25 15:45:44 +00:00
---
2014-05-22 13:55:28 +00:00
m.elements = { }
2013-04-25 15:45:44 +00:00
2012-08-01 19:28:21 +00:00
--
-- Generate a Visual Studio 201x C++ project, with support for the new platforms API.
--
2014-05-22 13:55:28 +00:00
m.elements . project = function ( prj )
return {
2015-07-27 17:30:51 +00:00
m.xmlDeclaration ,
2015-07-06 22:08:32 +00:00
m.project ,
2014-05-22 13:55:28 +00:00
m.projectConfigurations ,
m.globals ,
m.importDefaultProps ,
m.configurationPropertiesGroup ,
2015-08-31 19:22:46 +00:00
m.importLanguageSettings ,
2014-05-22 13:55:28 +00:00
m.importExtensionSettings ,
m.propertySheetGroup ,
m.userMacros ,
m.outputPropertiesGroup ,
m.itemDefinitionGroups ,
m.assemblyReferences ,
m.files ,
m.projectReferences ,
2015-08-31 18:58:23 +00:00
m.importLanguageTargets ,
2014-06-12 23:05:44 +00:00
m.importExtensionTargets ,
2016-03-19 16:23:28 +00:00
m.ensureNuGetPackageBuildImports ,
2014-05-22 13:55:28 +00:00
}
end
2013-01-17 18:19:49 +00:00
2014-05-22 13:55:28 +00:00
function m . generate ( prj )
2015-07-26 22:25:31 +00:00
p.utf8 ( )
2014-05-22 13:55:28 +00:00
p.callArray ( m.elements . project , prj )
2014-02-08 15:44:57 +00:00
p.out ( ' </Project> ' )
2012-08-01 19:28:21 +00:00
end
--
-- Output the XML declaration and opening <Project> tag.
--
2015-07-06 22:08:32 +00:00
function m . project ( prj )
2015-07-14 19:52:01 +00:00
local action = p.action . current ( )
2015-01-12 22:17:56 +00:00
p.push ( ' <Project DefaultTargets="Build" ToolsVersion="%s" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> ' ,
action.vstudio . toolsVersion )
2012-08-01 19:28:21 +00:00
end
--
-- Write out the list of project configurations, which pairs build
-- configurations with architectures.
--
2014-05-22 13:55:28 +00:00
function m . projectConfigurations ( prj )
2013-04-03 15:53:00 +00:00
2012-08-01 19:28:21 +00:00
-- build a list of all architectures used in this project
local platforms = { }
for cfg in project.eachconfig ( prj ) do
2012-11-17 20:49:06 +00:00
local arch = vstudio.archFromConfig ( cfg , true )
2012-08-01 19:28:21 +00:00
if not table.contains ( platforms , arch ) then
table.insert ( platforms , arch )
end
end
2013-01-12 16:52:59 +00:00
2012-11-17 20:49:06 +00:00
local configs = { }
2015-07-09 19:13:11 +00:00
p.push ( ' <ItemGroup Label="ProjectConfigurations"> ' )
2012-08-01 19:28:21 +00:00
for cfg in project.eachconfig ( prj ) do
for _ , arch in ipairs ( platforms ) do
2012-11-17 20:49:06 +00:00
local prjcfg = vstudio.projectConfig ( cfg , arch )
if not configs [ prjcfg ] then
configs [ prjcfg ] = prjcfg
2015-07-09 19:13:11 +00:00
p.push ( ' <ProjectConfiguration Include="%s"> ' , vstudio.projectConfig ( cfg , arch ) )
p.x ( ' <Configuration>%s</Configuration> ' , vstudio.projectPlatform ( cfg ) )
p.w ( ' <Platform>%s</Platform> ' , arch )
p.pop ( ' </ProjectConfiguration> ' )
2012-11-17 20:49:06 +00:00
end
2012-08-01 19:28:21 +00:00
end
end
2015-07-09 19:13:11 +00:00
p.pop ( ' </ItemGroup> ' )
2012-08-01 19:28:21 +00:00
end
2013-09-30 14:53:16 +00:00
--
-- Write out the TargetFrameworkVersion property.
--
2014-05-22 13:55:28 +00:00
function m . targetFramework ( prj )
2015-07-14 19:52:01 +00:00
local action = p.action . current ( )
2014-12-29 20:18:07 +00:00
local tools = string.format ( ' ToolsVersion="%s" ' , action.vstudio . toolsVersion )
2015-09-10 01:58:52 +00:00
local framework = prj.dotnetframework or action.vstudio . targetFramework or " 4.0 "
2015-07-09 19:13:11 +00:00
p.w ( ' <TargetFrameworkVersion>v%s</TargetFrameworkVersion> ' , framework )
2013-09-30 14:53:16 +00:00
end
2014-05-22 14:26:16 +00:00
2012-08-01 19:28:21 +00:00
--
-- Write out the Globals property group.
--
2014-05-22 14:26:16 +00:00
m.elements . globals = function ( prj )
return {
m.projectGuid ,
2014-12-08 22:42:00 +00:00
m.ignoreWarnDuplicateFilename ,
2014-05-22 14:26:16 +00:00
m.keyword ,
m.projectName ,
2016-03-17 12:56:23 +00:00
m.targetPlatformVersion ,
2014-05-22 14:26:16 +00:00
}
end
2014-05-22 13:55:28 +00:00
function m . globals ( prj )
m.propertyGroup ( nil , " Globals " )
2014-05-22 14:26:16 +00:00
p.callArray ( m.elements . globals , prj )
2015-07-09 19:13:11 +00:00
p.pop ( ' </PropertyGroup> ' )
2012-08-01 19:28:21 +00:00
end
--
2013-01-12 16:52:59 +00:00
-- Write out the configuration property group: what kind of binary it
2012-08-01 19:28:21 +00:00
-- produces, and some global settings.
--
2014-05-22 13:55:28 +00:00
m.elements . configurationProperties = function ( cfg )
2014-07-14 20:48:03 +00:00
if cfg.kind == p.UTILITY then
return {
m.configurationType ,
2015-08-24 10:56:44 +00:00
m.platformToolset ,
2014-07-14 20:48:03 +00:00
}
else
return {
m.configurationType ,
m.useDebugLibraries ,
m.useOfMfc ,
m.useOfAtl ,
m.clrSupport ,
m.characterSet ,
2014-12-08 22:42:00 +00:00
m.platformToolset ,
2014-07-14 20:48:03 +00:00
m.wholeProgramOptimization ,
m.nmakeOutDirs ,
}
end
2012-08-01 19:28:21 +00:00
end
2014-05-22 13:55:28 +00:00
function m . configurationProperties ( cfg )
m.propertyGroup ( cfg , " Configuration " )
p.callArray ( m.elements . configurationProperties , cfg )
2015-07-09 19:13:11 +00:00
p.pop ( ' </PropertyGroup> ' )
2014-05-22 13:55:28 +00:00
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . configurationPropertiesGroup ( prj )
for cfg in project.eachconfig ( prj ) do
m.configurationProperties ( cfg )
end
2012-08-01 19:28:21 +00:00
end
2014-05-22 13:55:28 +00:00
2012-08-01 19:28:21 +00:00
--
2013-04-03 15:53:00 +00:00
-- Write the output property group, which includes the output and intermediate
2012-08-01 19:28:21 +00:00
-- directories, manifest, etc.
--
2014-05-22 13:55:28 +00:00
m.elements . outputProperties = function ( cfg )
2014-07-14 20:48:03 +00:00
if cfg.kind == p.UTILITY then
return {
m.outDir ,
m.intDir ,
2014-07-16 19:32:08 +00:00
m.extensionsToDeleteOnClean ,
2014-07-14 20:48:03 +00:00
}
else
return {
m.linkIncremental ,
m.ignoreImportLibrary ,
m.outDir ,
m.outputFile ,
m.intDir ,
m.targetName ,
m.targetExt ,
2015-05-13 19:41:29 +00:00
m.includePath ,
2015-05-17 21:53:55 +00:00
m.libraryPath ,
2014-07-14 20:48:03 +00:00
m.imageXexOutput ,
m.generateManifest ,
2014-07-16 19:32:08 +00:00
m.extensionsToDeleteOnClean ,
2015-03-25 16:47:05 +00:00
m.executablePath ,
2014-07-14 20:48:03 +00:00
}
end
2014-05-22 13:55:28 +00:00
end
function m . outputProperties ( cfg )
2013-06-26 11:28:57 +00:00
if not vstudio.isMakefile ( cfg ) then
2014-07-22 20:34:40 +00:00
m.propertyGroup ( cfg )
2014-05-22 13:55:28 +00:00
p.callArray ( m.elements . outputProperties , cfg )
2015-07-09 19:13:11 +00:00
p.pop ( ' </PropertyGroup> ' )
2013-04-03 15:53:00 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . outputPropertiesGroup ( prj )
for cfg in project.eachconfig ( prj ) do
m.outputProperties ( cfg )
m.nmakeProperties ( cfg )
end
end
2013-04-03 15:53:00 +00:00
--
-- Write the NMake property group for Makefile projects, which includes the custom
-- build commands, output file location, etc.
--
2014-05-22 13:55:28 +00:00
function m . nmakeProperties ( cfg )
2013-06-26 11:28:57 +00:00
if vstudio.isMakefile ( cfg ) then
2014-05-22 13:55:28 +00:00
m.propertyGroup ( cfg )
m.nmakeOutput ( cfg )
m.nmakeCommandLine ( cfg , cfg.buildcommands , " Build " )
m.nmakeCommandLine ( cfg , cfg.rebuildcommands , " ReBuild " )
m.nmakeCommandLine ( cfg , cfg.cleancommands , " Clean " )
2015-07-09 19:13:11 +00:00
p.pop ( ' </PropertyGroup> ' )
2013-04-03 15:53:00 +00:00
end
end
--
-- Write a configuration's item definition group, which contains all
-- of the per-configuration compile and link settings.
--
2014-05-22 13:55:28 +00:00
m.elements . itemDefinitionGroup = function ( cfg )
2014-07-14 20:48:03 +00:00
if cfg.kind == p.UTILITY then
return {
2014-10-20 19:41:00 +00:00
m.ruleVars ,
2014-10-14 09:39:54 +00:00
m.buildEvents ,
2014-07-14 20:48:03 +00:00
}
else
return {
m.clCompile ,
m.resourceCompile ,
2014-08-07 22:07:32 +00:00
m.linker ,
2014-07-14 20:48:03 +00:00
m.manifest ,
m.buildEvents ,
m.imageXex ,
m.deploy ,
2014-10-20 19:41:00 +00:00
m.ruleVars ,
2015-04-28 20:30:23 +00:00
m.buildLog ,
2014-07-14 20:48:03 +00:00
}
end
2014-05-22 13:55:28 +00:00
end
function m . itemDefinitionGroup ( cfg )
2013-06-26 11:28:57 +00:00
if not vstudio.isMakefile ( cfg ) then
2014-06-12 22:39:39 +00:00
p.push ( ' <ItemDefinitionGroup %s> ' , m.condition ( cfg ) )
2014-05-22 13:55:28 +00:00
p.callArray ( m.elements . itemDefinitionGroup , cfg )
2014-06-12 22:39:39 +00:00
p.pop ( ' </ItemDefinitionGroup> ' )
2013-04-03 15:53:00 +00:00
else
if cfg == project.getfirstconfig ( cfg.project ) then
2014-06-12 22:39:39 +00:00
p.w ( ' <ItemDefinitionGroup> ' )
p.w ( ' </ItemDefinitionGroup> ' )
2013-04-03 15:53:00 +00:00
end
end
2012-08-01 19:28:21 +00:00
end
2014-05-22 13:55:28 +00:00
function m . itemDefinitionGroups ( prj )
for cfg in project.eachconfig ( prj ) do
m.itemDefinitionGroup ( cfg )
end
end
2012-08-01 19:28:21 +00:00
--
-- Write the the <ClCompile> compiler settings block.
--
2014-05-22 13:55:28 +00:00
m.elements . clCompile = function ( cfg )
return {
m.precompiledHeader ,
m.warningLevel ,
m.treatWarningAsError ,
2015-03-09 23:53:46 +00:00
m.disableSpecificWarnings ,
m.treatSpecificWarningsAsErrors ,
2014-05-22 13:55:28 +00:00
m.basicRuntimeChecks ,
m.clCompilePreprocessorDefinitions ,
2015-03-09 22:49:19 +00:00
m.clCompileUndefinePreprocessorDefinitions ,
2014-05-22 13:55:28 +00:00
m.clCompileAdditionalIncludeDirectories ,
m.clCompileAdditionalUsingDirectories ,
m.forceIncludes ,
m.debugInformationFormat ,
m.programDataBaseFileName ,
m.optimization ,
m.functionLevelLinking ,
m.intrinsicFunctions ,
m.minimalRebuild ,
m.omitFramePointers ,
m.stringPooling ,
m.runtimeLibrary ,
m.omitDefaultLib ,
m.exceptionHandling ,
m.runtimeTypeInfo ,
m.bufferSecurityCheck ,
m.treatWChar_tAsBuiltInType ,
m.floatingPointModel ,
2015-06-08 18:06:18 +00:00
m.inlineFunctionExpansion ,
2014-05-22 13:55:28 +00:00
m.enableEnhancedInstructionSet ,
m.multiProcessorCompilation ,
m.additionalCompileOptions ,
m.compileAs ,
2015-06-03 02:16:53 +00:00
m.callingConvention ,
2014-05-22 13:55:28 +00:00
}
end
function m . clCompile ( cfg )
2014-06-12 22:39:39 +00:00
p.push ( ' <ClCompile> ' )
2014-05-22 13:55:28 +00:00
p.callArray ( m.elements . clCompile , cfg )
2014-06-12 22:39:39 +00:00
p.pop ( ' </ClCompile> ' )
2012-08-01 19:28:21 +00:00
end
--
-- Write out the resource compiler block.
--
2014-05-22 13:55:28 +00:00
m.elements . resourceCompile = function ( cfg )
return {
m.resourcePreprocessorDefinitions ,
m.resourceAdditionalIncludeDirectories ,
m.culture ,
}
end
2013-04-30 16:38:11 +00:00
2014-05-22 13:55:28 +00:00
function m . resourceCompile ( cfg )
2015-09-16 12:31:40 +00:00
if cfg.system ~= p.XBOX360 and p.config . hasFile ( cfg , path.isresourcefile ) then
2014-12-24 01:05:40 +00:00
local contents = p.capture ( function ( )
p.push ( )
p.callArray ( m.elements . resourceCompile , cfg )
p.pop ( )
end )
if # contents > 0 then
p.push ( ' <ResourceCompile> ' )
p.outln ( contents )
p.pop ( ' </ResourceCompile> ' )
end
2013-03-07 17:14:03 +00:00
end
2012-08-01 19:28:21 +00:00
end
--
-- Write out the linker tool block.
--
2014-08-07 22:07:32 +00:00
m.elements . linker = function ( cfg , explicit )
2016-03-15 18:48:33 +00:00
return {
m.link ,
m.lib ,
m.linkLibraryDependencies ,
}
2014-05-22 13:55:28 +00:00
end
2014-08-07 22:07:32 +00:00
function m . linker ( cfg )
local explicit = vstudio.needsExplicitLink ( cfg )
p.callArray ( m.elements . linker , cfg , explicit )
2014-05-22 13:55:28 +00:00
end
2012-08-01 19:28:21 +00:00
2014-08-07 22:07:32 +00:00
m.elements . link = function ( cfg , explicit )
2016-03-15 18:48:33 +00:00
if cfg.kind == p.STATICLIB then
return {
m.subSystem ,
m.generateDebugInformation ,
m.optimizeReferences ,
}
else
return {
m.subSystem ,
m.generateDebugInformation ,
m.optimizeReferences ,
m.additionalDependencies ,
m.additionalLibraryDirectories ,
m.importLibrary ,
m.entryPointSymbol ,
m.generateMapFile ,
m.moduleDefinitionFile ,
m.treatLinkerWarningAsErrors ,
m.ignoreDefaultLibraries ,
m.largeAddressAware ,
m.targetMachine ,
m.additionalLinkOptions ,
}
end
2014-08-07 22:07:32 +00:00
end
2013-04-25 20:05:08 +00:00
2014-08-07 22:07:32 +00:00
function m . link ( cfg , explicit )
local contents = p.capture ( function ( )
p.push ( )
p.callArray ( m.elements . link , cfg , explicit )
p.pop ( )
end )
if # contents > 0 then
p.push ( ' <Link> ' )
p.outln ( contents )
p.pop ( ' </Link> ' )
end
2012-08-01 19:28:21 +00:00
end
2014-08-07 22:07:32 +00:00
m.elements . lib = function ( cfg , explicit )
2016-03-15 18:48:33 +00:00
if cfg.kind == p.STATICLIB then
return {
m.treatLinkerWarningAsErrors ,
m.targetMachine ,
m.additionalLinkOptions ,
}
else
return { }
end
2012-08-01 19:28:21 +00:00
end
2014-08-07 22:07:32 +00:00
function m . lib ( cfg , explicit )
2014-02-08 15:44:57 +00:00
local contents = p.capture ( function ( )
2014-08-07 22:07:32 +00:00
p.push ( )
p.callArray ( m.elements . lib , cfg , explicit )
p.pop ( )
2013-12-11 22:33:44 +00:00
end )
if # contents > 0 then
2014-08-07 22:07:32 +00:00
p.push ( ' <Lib> ' )
p.outln ( contents )
p.pop ( ' </Lib> ' )
2013-06-12 21:03:09 +00:00
end
2012-08-01 19:28:21 +00:00
end
2014-08-07 22:07:32 +00:00
2013-09-06 15:32:06 +00:00
--
-- Write the manifest section.
--
2014-05-22 13:55:28 +00:00
function m . manifest ( cfg )
2015-07-09 19:13:11 +00:00
if cfg.kind ~= p.STATICLIB then
2013-09-18 08:35:02 +00:00
-- get the manifests files
2013-09-06 15:32:06 +00:00
local manifests = { }
for _ , fname in ipairs ( cfg.files ) do
if path.getextension ( fname ) == " .manifest " then
table.insert ( manifests , project.getrelative ( cfg.project , fname ) )
end
end
2015-07-09 19:13:11 +00:00
if # manifests > 0 then
2014-06-11 20:05:25 +00:00
p.push ( ' <Manifest> ' )
m.element ( " AdditionalManifestFiles " , nil , " %s %%(AdditionalManifestFiles) " , table.concat ( manifests , " " ) )
p.pop ( ' </Manifest> ' )
2013-09-06 15:32:06 +00:00
end
end
end
2014-01-15 21:12:29 +00:00
---
2012-08-01 19:28:21 +00:00
-- Write out the pre- and post-build event settings.
2014-01-15 21:12:29 +00:00
---
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . buildEvents ( cfg )
2014-01-15 21:12:29 +00:00
local write = function ( event )
local name = event .. " Event "
local field = event : lower ( )
local steps = cfg [ field .. " commands " ]
local msg = cfg [ field .. " message " ]
if # steps > 0 then
2014-11-29 19:51:49 +00:00
steps = os.translateCommands ( steps , p.WINDOWS )
2015-07-09 19:13:11 +00:00
p.push ( ' <%s> ' , name )
p.x ( ' <Command>%s</Command> ' , table.implode ( steps , " " , " " , " \r \n " ) )
2014-01-15 21:12:29 +00:00
if msg then
2015-07-09 19:13:11 +00:00
p.x ( ' <Message>%s</Message> ' , msg )
2014-01-15 21:12:29 +00:00
end
2015-07-09 19:13:11 +00:00
p.pop ( ' </%s> ' , name )
2012-08-01 19:28:21 +00:00
end
end
2014-01-15 21:12:29 +00:00
write ( " PreBuild " )
write ( " PreLink " )
write ( " PostBuild " )
2012-08-01 19:28:21 +00:00
end
2014-07-15 15:16:59 +00:00
---
-- Write out project-level custom rule variables.
---
2014-10-20 19:41:00 +00:00
function m . ruleVars ( cfg )
2014-10-24 19:35:30 +00:00
for i = 1 , # cfg.rules do
local rule = p.global . getRule ( cfg.rules [ i ] )
2014-07-15 15:16:59 +00:00
local contents = p.capture ( function ( )
p.push ( )
2014-10-20 22:45:05 +00:00
for prop in p.rule . eachProperty ( rule ) do
local fld = p.rule . getPropertyField ( rule , prop )
local value = cfg [ fld.name ]
2014-10-24 19:35:30 +00:00
if value ~= nil then
2016-08-01 21:40:40 +00:00
if fld.kind == " list:path " then
value = table.concat ( vstudio.path ( cfg , value ) , ' ; ' )
elseif fld.kind == " path " then
2015-05-08 21:08:41 +00:00
value = vstudio.path ( cfg , value )
2015-05-08 20:30:47 +00:00
else
value = p.rule . getPropertyString ( rule , prop , value )
end
2016-08-01 21:40:40 +00:00
2014-10-24 19:35:30 +00:00
if value ~= nil and # value > 0 then
2014-10-20 22:45:05 +00:00
m.element ( prop.name , nil , ' %s ' , value )
2014-07-15 15:16:59 +00:00
end
end
end
p.pop ( )
end )
if # contents > 0 then
2014-10-20 19:41:00 +00:00
p.push ( ' <%s> ' , rule.name )
2014-07-15 15:16:59 +00:00
p.outln ( contents )
2014-10-20 19:41:00 +00:00
p.pop ( ' </%s> ' , rule.name )
2014-07-15 15:16:59 +00:00
end
2014-10-20 19:41:00 +00:00
end
2014-07-15 15:16:59 +00:00
end
2013-03-04 16:45:27 +00:00
--
-- Reference any managed assemblies listed in the links()
--
2014-05-22 13:55:28 +00:00
function m . assemblyReferences ( prj )
2013-03-05 16:00:32 +00:00
-- Visual Studio doesn't support per-config references; use
-- whatever is contained in the first configuration
2013-03-04 16:45:27 +00:00
local cfg = project.getfirstconfig ( prj )
2013-03-05 16:00:32 +00:00
2013-03-04 16:45:27 +00:00
local refs = config.getlinks ( cfg , " system " , " fullpath " , " managed " )
2015-07-27 17:30:51 +00:00
if # refs > 0 then
p.push ( ' <ItemGroup> ' )
for i = 1 , # refs do
local value = refs [ i ]
2013-03-05 16:00:32 +00:00
-- If the link contains a '/' then it is a relative path to
-- a local assembly. Otherwise treat it as a system assembly.
if value : find ( ' / ' , 1 , true ) then
2015-07-09 19:13:11 +00:00
p.push ( ' <Reference Include="%s"> ' , path.getbasename ( value ) )
p.x ( ' <HintPath>%s</HintPath> ' , path.translate ( value ) )
p.pop ( ' </Reference> ' )
2013-03-05 16:00:32 +00:00
else
2015-07-09 19:13:11 +00:00
p.x ( ' <Reference Include="%s" /> ' , path.getbasename ( value ) )
2013-03-05 16:00:32 +00:00
end
2015-07-27 17:30:51 +00:00
end
p.pop ( ' </ItemGroup> ' )
end
2013-03-04 16:45:27 +00:00
end
2014-06-11 20:05:25 +00:00
---
2012-08-01 19:28:21 +00:00
-- Write out the list of source code files, and any associated configuration.
2014-06-11 20:05:25 +00:00
---
2014-06-11 17:52:08 +00:00
2014-06-11 20:05:25 +00:00
function m . files ( prj )
local groups = m.categorizeSources ( prj )
2016-04-05 16:12:33 +00:00
for _ , group in ipairs ( groups ) do
group.category . emitFiles ( prj , group )
2012-08-01 19:28:21 +00:00
end
end
2013-03-12 23:26:25 +00:00
2016-04-05 16:12:33 +00:00
m.categories = { }
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
---
-- ClInclude group
---
m.categories . ClInclude = {
name = " ClInclude " ,
extensions = { " .h " , " .hh " , " .hpp " , " .hxx " } ,
priority = 1 ,
2013-03-12 23:26:25 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
2016-07-14 02:46:20 +00:00
m.emitFiles ( prj , group , " ClInclude " )
2016-04-05 16:12:33 +00:00
end ,
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " ClInclude " )
end
}
2013-01-12 16:52:59 +00:00
2014-02-11 23:04:07 +00:00
2016-04-05 16:12:33 +00:00
---
-- ClCompile group
---
m.categories . ClCompile = {
name = " ClCompile " ,
extensions = { " .cc " , " .cpp " , " .cxx " , " .c " , " .s " , " .m " , " .mm " } ,
priority = 2 ,
emitFiles = function ( prj , group )
local fileCfgFunc = function ( fcfg , condition )
if fcfg then
return {
m.excludedFromBuild ,
m.objectFileName ,
m.clCompilePreprocessorDefinitions ,
m.clCompileUndefinePreprocessorDefinitions ,
m.optimization ,
m.forceIncludes ,
m.precompiledHeader ,
m.enableEnhancedInstructionSet ,
m.additionalCompileOptions ,
m.disableSpecificWarnings ,
m.treatSpecificWarningsAsErrors
}
else
return {
m.excludedFromBuild
}
end
end
2013-01-12 16:52:59 +00:00
2016-07-14 02:46:20 +00:00
m.emitFiles ( prj , group , " ClCompile " , nil , fileCfgFunc )
2016-04-05 16:12:33 +00:00
end ,
2013-09-03 11:16:08 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " ClCompile " )
end
}
2014-09-25 08:41:27 +00:00
2013-01-12 16:52:59 +00:00
2016-04-05 16:12:33 +00:00
---
-- None group
---
m.categories . None = {
name = " None " ,
priority = 3 ,
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
2016-07-14 02:46:20 +00:00
m.emitFiles ( prj , group , " None " )
2016-04-05 16:12:33 +00:00
end ,
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " None " )
end
}
2013-03-12 23:26:25 +00:00
2016-04-05 16:12:33 +00:00
---
-- ResourceCompile group
---
m.categories . ResourceCompile = {
name = " ResourceCompile " ,
extensions = " .rc " ,
priority = 4 ,
2014-10-20 22:45:05 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
local fileCfgFunc = {
m.excludedFromBuild
}
2014-02-26 23:43:06 +00:00
2016-04-05 16:12:33 +00:00
m.emitFiles ( prj , group , " ResourceCompile " , nil , fileCfgFunc , function ( cfg )
return cfg.system == p.WINDOWS
end )
end ,
2014-06-11 20:05:25 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " ResourceCompile " )
end
}
2014-06-11 20:05:25 +00:00
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
---
-- CustomBuild group
---
m.categories . CustomBuild = {
name = " CustomBuild " ,
priority = 5 ,
2015-07-27 17:30:51 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
local fileFunc = {
m.fileType
}
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
local fileCfgFunc = {
m.excludedFromBuild ,
m.buildCommands ,
m.buildOutputs ,
m.buildMessage ,
m.buildAdditionalInputs
}
2015-07-27 17:30:51 +00:00
2016-04-05 16:12:33 +00:00
m.emitFiles ( prj , group , " CustomBuild " , fileFunc , fileCfgFunc , function ( cfg , fcfg )
return fileconfig.hasCustomBuildRule ( fcfg )
end )
end ,
2014-06-11 20:05:25 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " CustomBuild " )
end
}
2014-06-11 20:05:25 +00:00
2016-04-05 16:12:33 +00:00
---
-- Midl group
---
m.categories . Midl = {
name = " Midl " ,
extensions = " .idl " ,
priority = 6 ,
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
local fileCfgFunc = {
m.excludedFromBuild
}
2015-06-29 11:56:15 +00:00
2016-04-05 16:12:33 +00:00
m.emitFiles ( prj , group , " Midl " , nil , fileCfgFunc , function ( cfg )
return cfg.system == p.WINDOWS
end )
end ,
2014-06-11 20:05:25 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " Midl " )
end
}
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
---
-- Masm group
---
m.categories . Masm = {
name = " Masm " ,
extensions = " .asm " ,
priority = 7 ,
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
emitFiles = function ( prj , group )
local fileCfgFunc = {
m.excludedFromBuild
}
2012-08-01 19:28:21 +00:00
2016-04-05 16:12:33 +00:00
m.emitFiles ( prj , group , " Masm " , nil , fileCfgFunc , function ( cfg )
return cfg.system == p.WINDOWS
end )
end ,
2015-07-27 17:30:51 +00:00
2016-04-05 16:12:33 +00:00
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , " Masm " )
end ,
2015-06-29 11:56:15 +00:00
2016-04-05 16:12:33 +00:00
emitExtensionSettings = function ( prj , group )
p.w ( ' <Import Project="$(VCTargetsPath) \\ BuildCustomizations \\ masm.props" /> ' )
end ,
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
emitExtensionTargets = function ( prj , group )
p.w ( ' <Import Project="$(VCTargetsPath) \\ BuildCustomizations \\ masm.targets" /> ' )
end
}
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
---
-- Categorize files into groups.
---
2015-07-09 18:43:25 +00:00
function m . categorizeSources ( prj )
2016-04-05 16:12:33 +00:00
-- if we already did this, return the cached result.
if prj._vc2010_sources then
return prj._vc2010_sources
2015-07-09 18:43:25 +00:00
end
2016-04-05 16:12:33 +00:00
-- build the new group table.
local result = { }
local groups = { }
prj._vc2010_sources = result
2015-07-09 18:43:25 +00:00
local tr = project.getsourcetree ( prj )
tree.traverse ( tr , {
onleaf = function ( node )
local cat = m.categorizeFile ( prj , node )
2016-04-05 16:12:33 +00:00
groups [ cat.name ] = groups [ cat.name ] or {
category = cat ,
files = { }
}
table.insert ( groups [ cat.name ] . files , node )
2015-06-29 11:56:15 +00:00
end
2015-07-09 18:43:25 +00:00
} )
-- sort by relative-to path; otherwise VS will reorder the files
2016-04-05 16:12:33 +00:00
for name , group in pairs ( groups ) do
table.sort ( group.files , function ( a , b )
2015-07-09 18:43:25 +00:00
return a.relpath < b.relpath
end )
2016-04-05 16:12:33 +00:00
table.insert ( result , group )
2015-06-29 11:56:15 +00:00
end
2015-07-09 18:43:25 +00:00
2016-04-05 16:12:33 +00:00
-- sort by category priority then name; so we get stable results.
table.sort ( result , function ( a , b )
if ( a.category . priority == b.category . priority ) then
return a.category . name < b.category . name
end
return a.category . priority < b.category . priority
end )
return result
2015-06-29 11:56:15 +00:00
end
2012-08-01 19:28:21 +00:00
2015-07-09 18:43:25 +00:00
function m . categorizeFile ( prj , file )
2014-10-20 19:41:00 +00:00
-- If any configuration for this file uses a custom build step,
-- that's the category to use
2014-06-10 20:38:16 +00:00
for cfg in project.eachconfig ( prj ) do
local fcfg = fileconfig.getconfig ( file , cfg )
if fileconfig.hasCustomBuildRule ( fcfg ) then
2016-04-05 16:12:33 +00:00
return m.categories . CustomBuild
2014-06-10 20:38:16 +00:00
end
end
2014-10-20 19:41:00 +00:00
-- If there is a custom rule associated with it, use that
2014-10-24 19:35:30 +00:00
local rule = p.global . getRuleForFile ( file.name , prj.rules )
2014-10-20 19:41:00 +00:00
if rule then
2016-04-05 16:12:33 +00:00
return {
name = rule.name ,
priority = 100 ,
rule = rule ,
emitFiles = function ( prj , group )
m.emitRuleFiles ( prj , group )
end ,
emitFilter = function ( prj , group )
m.filterGroup ( prj , group , group.category . name )
end
}
2014-10-20 19:41:00 +00:00
end
2014-06-10 20:38:16 +00:00
-- Otherwise use the file extension to deduce a category
2016-04-05 16:12:33 +00:00
for _ , cat in pairs ( m.categories ) do
if cat.extensions and path.hasextension ( file.name , cat.extensions ) then
return cat
end
2014-06-10 20:38:16 +00:00
end
2016-04-05 16:12:33 +00:00
return m.categories . None
2014-06-10 20:38:16 +00:00
end
2016-04-05 16:12:33 +00:00
function m . emitFiles ( prj , group , tag , fileFunc , fileCfgFunc , checkFunc )
local files = group.files
2015-07-09 18:43:25 +00:00
if files and # files > 0 then
p.push ( ' <ItemGroup> ' )
for _ , file in ipairs ( files ) do
2014-06-12 20:14:42 +00:00
2015-07-09 18:43:25 +00:00
local contents = p.capture ( function ( )
p.push ( )
2016-04-05 16:12:33 +00:00
p.callArray ( fileFunc , cfg , file )
2015-07-09 18:43:25 +00:00
for cfg in project.eachconfig ( prj ) do
local fcfg = fileconfig.getconfig ( file , cfg )
2016-04-05 16:12:33 +00:00
if not checkFunc or checkFunc ( cfg , fcfg ) then
p.callArray ( fileCfgFunc , fcfg , m.condition ( cfg ) )
2015-07-09 18:43:25 +00:00
end
end
p.pop ( )
end )
2014-06-10 20:38:16 +00:00
2015-07-09 18:43:25 +00:00
local rel = path.translate ( file.relpath )
if # contents > 0 then
2016-04-05 16:12:33 +00:00
p.push ( ' <%s Include="%s"> ' , tag , rel )
2015-07-09 18:43:25 +00:00
p.outln ( contents )
2016-04-05 16:12:33 +00:00
p.pop ( ' </%s> ' , tag )
2015-07-09 18:43:25 +00:00
else
2016-04-05 16:12:33 +00:00
p.x ( ' <%s Include="%s" /> ' , tag , rel )
2015-07-09 18:43:25 +00:00
end
2014-06-10 20:38:16 +00:00
2015-07-09 18:43:25 +00:00
end
p.pop ( ' </ItemGroup> ' )
2014-06-10 20:38:16 +00:00
end
end
2016-04-05 16:12:33 +00:00
function m . emitRuleFiles ( prj , group )
local files = group.files
local rule = group.category . rule
if files and # files > 0 then
p.push ( ' <ItemGroup> ' )
for _ , file in ipairs ( files ) do
local contents = p.capture ( function ( )
p.push ( )
for prop in p.rule . eachProperty ( rule ) do
local fld = p.rule . getPropertyField ( rule , prop )
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 )
end
end
end
end
p.pop ( )
end )
if # contents > 0 then
p.push ( ' <%s Include= \" %s \" > ' , rule.name , path.translate ( file.relpath ) )
p.outln ( contents )
p.pop ( ' </%s> ' , rule.name )
else
p.x ( ' <%s Include= \" %s \" /> ' , rule.name , path.translate ( file.relpath ) )
end
end
p.pop ( ' </ItemGroup> ' )
end
end
2014-06-10 20:38:16 +00:00
2012-08-01 19:28:21 +00:00
--
-- Generate the list of project dependencies.
--
2014-10-02 20:21:25 +00:00
m.elements . projectReferences = function ( prj , ref )
2014-11-12 00:29:28 +00:00
if prj.clr ~= p.OFF then
2014-10-02 20:40:28 +00:00
return {
m.referenceProject ,
m.referencePrivate ,
m.referenceOutputAssembly ,
m.referenceCopyLocalSatelliteAssemblies ,
m.referenceLinkLibraryDependencies ,
m.referenceUseLibraryDependences ,
}
else
return {
m.referenceProject ,
}
end
2014-10-02 20:21:25 +00:00
end
2014-05-22 13:55:28 +00:00
function m . projectReferences ( prj )
2015-07-14 01:22:44 +00:00
local refs = project.getdependencies ( prj , ' linkOnly ' )
2014-10-02 20:21:25 +00:00
if # refs > 0 then
p.push ( ' <ItemGroup> ' )
for _ , ref in ipairs ( refs ) do
2015-05-08 21:08:41 +00:00
local relpath = vstudio.path ( prj , vstudio.projectfile ( ref ) )
p.push ( ' <ProjectReference Include= \" %s \" > ' , relpath )
2014-10-02 20:21:25 +00:00
p.callArray ( m.elements . projectReferences , prj , ref )
p.pop ( ' </ProjectReference> ' )
2012-08-01 19:28:21 +00:00
end
2014-10-02 20:21:25 +00:00
p.pop ( ' </ItemGroup> ' )
2012-08-01 19:28:21 +00:00
end
end
2013-02-11 18:25:33 +00:00
2013-03-07 17:14:03 +00:00
---------------------------------------------------------------------------
2013-02-11 18:25:33 +00:00
--
2013-03-07 17:14:03 +00:00
-- Handlers for individual project elements
2012-08-01 19:28:21 +00:00
--
2013-03-07 17:14:03 +00:00
---------------------------------------------------------------------------
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . additionalDependencies ( cfg , explicit )
2012-08-01 19:28:21 +00:00
local links
2012-11-30 19:05:19 +00:00
2012-08-01 19:28:21 +00:00
-- check to see if this project uses an external toolset. If so, let the
-- toolset define the format of the links
2014-02-27 14:54:55 +00:00
local toolset = config.toolset ( cfg )
2012-08-01 19:28:21 +00:00
if toolset then
2012-11-30 19:05:19 +00:00
links = toolset.getlinks ( cfg , not explicit )
2012-08-01 19:28:21 +00:00
else
2015-02-14 19:56:02 +00:00
links = vstudio.getLinks ( cfg , explicit )
2012-08-01 19:28:21 +00:00
end
2013-01-12 16:52:59 +00:00
2012-08-01 19:28:21 +00:00
if # links > 0 then
links = path.translate ( table.concat ( links , " ; " ) )
2015-07-15 20:50:59 +00:00
m.element ( " AdditionalDependencies " , nil , " %s;%%(AdditionalDependencies) " , links )
2012-08-01 19:28:21 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . additionalIncludeDirectories ( cfg , includedirs )
2012-08-01 19:28:21 +00:00
if # includedirs > 0 then
2015-06-08 18:48:02 +00:00
local dirs = vstudio.path ( cfg , includedirs )
2015-03-25 16:47:05 +00:00
if # dirs > 0 then
2015-07-15 20:50:59 +00:00
m.element ( " AdditionalIncludeDirectories " , nil , " %s;%%(AdditionalIncludeDirectories) " , table.concat ( dirs , " ; " ) )
2015-03-25 16:47:05 +00:00
end
2012-08-01 19:28:21 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . additionalLibraryDirectories ( cfg )
2012-08-01 19:28:21 +00:00
if # cfg.libdirs > 0 then
2015-05-08 21:08:41 +00:00
local dirs = table.concat ( vstudio.path ( cfg , cfg.libdirs ) , " ; " )
2015-07-15 20:50:59 +00:00
m.element ( " AdditionalLibraryDirectories " , nil , " %s;%%(AdditionalLibraryDirectories) " , dirs )
2012-08-01 19:28:21 +00:00
end
end
2015-06-16 15:44:18 +00:00
2014-05-22 13:55:28 +00:00
function m . additionalUsingDirectories ( cfg )
2013-09-27 23:04:18 +00:00
if # cfg.usingdirs > 0 then
2015-10-05 16:21:26 +00:00
local dirs = vstudio.path ( cfg , cfg.usingdirs )
if # dirs > 0 then
m.element ( " AdditionalUsingDirectories " , nil , " %s;%%(AdditionalUsingDirectories) " , table.concat ( dirs , " ; " ) )
end
2013-09-27 23:04:18 +00:00
end
2013-11-15 22:17:41 +00:00
end
2013-09-27 23:04:18 +00:00
2012-08-01 19:28:21 +00:00
2015-11-03 18:11:56 +00:00
function m . largeAddressAware ( cfg )
if ( cfg.largeaddressaware == true ) then
m.element ( " LargeAddressAware " , nil , ' true ' )
end
end
2014-05-22 13:55:28 +00:00
function m . additionalCompileOptions ( cfg , condition )
2013-03-12 23:26:25 +00:00
if # cfg.buildoptions > 0 then
local opts = table.concat ( cfg.buildoptions , " " )
2014-06-11 20:05:25 +00:00
m.element ( " AdditionalOptions " , condition , ' %s %%(AdditionalOptions) ' , opts )
2013-03-12 23:26:25 +00:00
end
end
2013-04-03 15:53:00 +00:00
2014-05-22 13:55:28 +00:00
function m . additionalLinkOptions ( cfg )
2012-08-01 19:28:21 +00:00
if # cfg.linkoptions > 0 then
local opts = table.concat ( cfg.linkoptions , " " )
2015-07-15 20:50:59 +00:00
m.element ( " AdditionalOptions " , nil , " %s %%(AdditionalOptions) " , opts )
2012-08-01 19:28:21 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . basicRuntimeChecks ( cfg )
2015-06-10 23:26:51 +00:00
local runtime = config.getruntime ( cfg )
if cfg.flags . NoRuntimeChecks or ( config.isOptimizedBuild ( cfg ) and runtime : endswith ( " Debug " ) ) then
2015-07-15 20:50:59 +00:00
m.element ( " BasicRuntimeChecks " , nil , " Default " )
2013-02-11 18:25:33 +00:00
end
end
2012-08-01 19:28:21 +00:00
2013-02-11 18:25:33 +00:00
2015-07-08 20:53:30 +00:00
function m . buildAdditionalInputs ( fcfg , condition )
if fcfg.buildinputs and # fcfg.buildinputs > 0 then
local inputs = project.getrelative ( fcfg.project , fcfg.buildinputs )
m.element ( " AdditionalInputs " , condition , ' %s ' , table.concat ( inputs , " ; " ) )
2013-02-11 18:25:33 +00:00
end
end
2012-08-01 19:28:21 +00:00
2013-02-11 18:25:33 +00:00
2015-07-08 20:53:30 +00:00
function m . buildCommands ( fcfg , condition )
local commands = os.translateCommands ( fcfg.buildcommands , p.WINDOWS )
commands = table.concat ( commands , ' \r \n ' )
m.element ( " Command " , condition , ' %s ' , commands )
end
2015-04-28 20:30:23 +00:00
function m . buildLog ( cfg )
if cfg.buildlog and # cfg.buildlog > 0 then
p.push ( ' <BuildLog> ' )
2015-07-15 20:50:59 +00:00
m.element ( " Path " , nil , " %s " , vstudio.path ( cfg , cfg.buildlog ) )
2015-04-28 20:30:23 +00:00
p.pop ( ' </BuildLog> ' )
end
end
2015-07-08 20:53:30 +00:00
function m . buildMessage ( fcfg , condition )
if fcfg.buildmessage then
m.element ( " Message " , condition , ' %s ' , fcfg.buildmessage )
end
end
function m . buildOutputs ( fcfg , condition )
local outputs = project.getrelative ( fcfg.project , fcfg.buildoutputs )
m.element ( " Outputs " , condition , ' %s ' , table.concat ( outputs , " ; " ) )
end
2014-05-22 13:55:28 +00:00
function m . characterSet ( cfg )
2013-06-26 11:28:57 +00:00
if not vstudio.isMakefile ( cfg ) then
2015-12-18 21:59:13 +00:00
m.element ( " CharacterSet " , nil , iif ( cfg.characterset == p.MBCS , " MultiByte " , " Unicode " ) )
2013-04-03 15:53:00 +00:00
end
2012-08-01 19:28:21 +00:00
end
2015-07-08 20:53:30 +00:00
2014-05-22 13:55:28 +00:00
function m . wholeProgramOptimization ( cfg )
2013-08-21 09:58:08 +00:00
if cfg.flags . LinkTimeOptimization then
2015-07-15 20:50:59 +00:00
m.element ( " WholeProgramOptimization " , nil , " true " )
2013-08-21 09:58:08 +00:00
end
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . clCompileAdditionalIncludeDirectories ( cfg )
m.additionalIncludeDirectories ( cfg , cfg.includedirs )
2013-04-30 16:38:11 +00:00
end
2014-05-22 13:55:28 +00:00
function m . clCompileAdditionalUsingDirectories ( cfg )
m.additionalUsingDirectories ( cfg , cfg.usingdirs )
2013-11-15 22:17:41 +00:00
end
2013-09-27 23:04:18 +00:00
2013-04-30 16:38:11 +00:00
2014-05-22 13:55:28 +00:00
function m . clCompilePreprocessorDefinitions ( cfg , condition )
m.preprocessorDefinitions ( cfg , cfg.defines , false , condition )
2013-04-30 16:38:11 +00:00
end
2015-03-09 22:49:19 +00:00
function m . clCompileUndefinePreprocessorDefinitions ( cfg , condition )
m.undefinePreprocessorDefinitions ( cfg , cfg.undefines , false , condition )
end
2014-05-22 13:55:28 +00:00
function m . clrSupport ( cfg )
2014-11-12 00:44:44 +00:00
local value
if cfg.clr == " On " or cfg.clr == " Unsafe " then
value = " true "
elseif cfg.clr ~= p.OFF then
value = cfg.clr
end
if value then
2015-07-15 20:50:59 +00:00
m.element ( " CLRSupport " , nil , value )
2013-02-11 18:25:33 +00:00
end
2012-08-01 19:28:21 +00:00
end
2014-05-22 13:55:28 +00:00
function m . compileAs ( cfg )
2013-02-11 18:25:33 +00:00
if cfg.project . language == " C " then
2015-07-15 20:50:59 +00:00
m.element ( " CompileAs " , nil , " CompileAsC " )
2013-02-11 18:25:33 +00:00
end
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . configurationType ( cfg )
2013-04-03 15:53:00 +00:00
local types = {
SharedLib = " DynamicLibrary " ,
StaticLib = " StaticLibrary " ,
ConsoleApp = " Application " ,
WindowedApp = " Application " ,
Makefile = " Makefile " ,
2013-06-25 14:15:39 +00:00
None = " Makefile " ,
2014-03-01 17:20:06 +00:00
Utility = " Utility " ,
2013-04-03 15:53:00 +00:00
}
2015-07-15 20:50:59 +00:00
m.element ( " ConfigurationType " , nil , types [ cfg.kind ] )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . culture ( cfg )
2014-02-06 20:38:51 +00:00
local value = vstudio.cultureForLocale ( cfg.locale )
if value then
2015-07-15 20:50:59 +00:00
m.element ( " Culture " , nil , " 0x%04x " , tostring ( value ) )
2014-02-06 20:38:51 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . debugInformationFormat ( cfg )
2012-08-01 19:28:21 +00:00
local value
2015-07-26 01:08:44 +00:00
local tool , toolVersion = p.config . toolset ( cfg )
2016-06-22 15:36:42 +00:00
if cfg.symbols == p.ON then
2012-08-01 19:28:21 +00:00
if cfg.debugformat == " c7 " then
value = " OldStyle "
2015-04-10 13:02:19 +00:00
elseif cfg.architecture == " x86_64 " or
2014-11-12 00:29:28 +00:00
cfg.clr ~= p.OFF or
2013-09-13 15:15:36 +00:00
config.isOptimizedBuild ( cfg ) or
2015-07-26 01:08:44 +00:00
cfg.editandcontinue == p.OFF or
( toolVersion and toolVersion : startswith ( " LLVM-vs " ) )
2012-08-01 19:28:21 +00:00
then
value = " ProgramDatabase "
else
value = " EditAndContinue "
end
2016-06-22 15:36:42 +00:00
2016-07-19 06:29:26 +00:00
m.element ( " DebugInformationFormat " , nil , value )
elseif cfg.symbols == p.OFF then
m.element ( " DebugInformationFormat " , nil , " None " )
2012-08-01 19:28:21 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . deploy ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.system == p.XBOX360 then
2015-07-09 19:13:11 +00:00
p.push ( ' <Deploy> ' )
2015-07-15 20:50:59 +00:00
m.element ( " DeploymentType " , nil , " CopyToHardDrive " )
m.element ( " DvdEmulationType " , nil , " ZeroSeekTimes " )
m.element ( " DeploymentFiles " , nil , " $(RemoteRoot)=$(ImagePath); " )
2015-07-09 19:13:11 +00:00
p.pop ( ' </Deploy> ' )
2013-03-07 17:14:03 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . enableEnhancedInstructionSet ( cfg , condition )
2015-03-26 14:22:55 +00:00
local v
2014-03-18 20:26:21 +00:00
local x = cfg.vectorextensions
2015-03-26 14:22:55 +00:00
if x == " AVX " and _ACTION > " vs2010 " then
v = " AdvancedVectorExtensions "
elseif x == " AVX2 " and _ACTION > " vs2012 " then
v = " AdvancedVectorExtensions2 "
2015-05-19 00:54:02 +00:00
elseif cfg.architecture ~= " x86_64 " then
2015-07-25 05:11:57 +00:00
if x == " SSE2 " or x == " SSE3 " or x == " SSSE3 " or x == " SSE4.1 " then
2015-03-27 16:36:44 +00:00
v = " StreamingSIMDExtensions2 "
elseif x == " SSE " then
v = " StreamingSIMDExtensions "
2016-08-07 11:42:03 +00:00
elseif x == " IA32 " and _ACTION > " vs2010 " then
v = " NoExtensions "
2015-03-27 16:36:44 +00:00
end
2014-03-18 20:26:21 +00:00
end
2015-03-26 14:22:55 +00:00
if v then
m.element ( ' EnableEnhancedInstructionSet ' , condition , v )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . entryPointSymbol ( cfg )
2015-07-27 17:30:51 +00:00
if cfg.entrypoint then
m.element ( " EntryPointSymbol " , nil , cfg.entrypoint )
else
if ( cfg.kind == premake.CONSOLEAPP or cfg.kind == premake.WINDOWEDAPP ) and
not cfg.flags . WinMain and
cfg.clr == p.OFF and
cfg.system ~= p.XBOX360
then
m.element ( " EntryPointSymbol " , nil , " mainCRTStartup " )
end
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . exceptionHandling ( cfg )
2015-06-23 23:03:28 +00:00
local value
2015-06-16 15:44:18 +00:00
if cfg.exceptionhandling == p.OFF then
2015-07-15 20:50:59 +00:00
m.element ( " ExceptionHandling " , nil , " false " )
2015-06-23 23:03:28 +00:00
elseif cfg.exceptionhandling == " SEH " then
2015-07-15 20:50:59 +00:00
m.element ( " ExceptionHandling " , nil , " Async " )
2013-02-11 18:25:33 +00:00
end
end
2015-07-06 22:08:32 +00:00
function m . excludedFromBuild ( filecfg , condition )
2013-03-12 23:26:25 +00:00
if not filecfg or filecfg.flags . ExcludeFromBuild then
2015-07-06 22:08:32 +00:00
m.element ( " ExcludedFromBuild " , condition , " true " )
2013-03-12 23:26:25 +00:00
end
end
2014-07-16 19:32:08 +00:00
function m . extensionsToDeleteOnClean ( cfg )
2015-05-05 18:46:00 +00:00
if # cfg.cleanextensions > 0 then
local value = table.implode ( cfg.cleanextensions , " * " , " ; " , " " )
2014-07-16 19:32:08 +00:00
m.element ( " ExtensionsToDeleteOnClean " , nil , value .. " $(ExtensionsToDeleteOnClean) " )
end
end
2015-07-09 18:43:25 +00:00
function m . fileType ( cfg , file )
2015-07-15 20:50:59 +00:00
m.element ( " FileType " , nil , " Document " )
2015-07-09 18:43:25 +00:00
end
2014-05-22 13:55:28 +00:00
function m . floatingPointModel ( cfg )
2013-09-27 18:49:21 +00:00
if cfg.floatingpoint then
2015-07-15 20:50:59 +00:00
m.element ( " FloatingPointModel " , nil , cfg.floatingpoint )
2013-02-11 18:25:33 +00:00
end
end
2015-06-08 18:06:18 +00:00
function m . inlineFunctionExpansion ( cfg )
if cfg.inlining then
local types = {
Default = " Default " ,
Disabled = " Disabled " ,
Explicit = " OnlyExplicitInline " ,
2015-06-22 15:25:18 +00:00
Auto = " AnySuitable " ,
2015-06-08 18:06:18 +00:00
}
2015-07-15 20:50:59 +00:00
m.element ( " InlineFunctionExpansion " , nil , types [ cfg.inlining ] )
2015-06-08 18:06:18 +00:00
end
end
2013-02-11 18:25:33 +00:00
2014-05-22 13:55:28 +00:00
function m . forceIncludes ( cfg , condition )
2013-02-11 18:25:33 +00:00
if # cfg.forceincludes > 0 then
2015-05-08 21:08:41 +00:00
local includes = vstudio.path ( cfg , cfg.forceincludes )
2015-06-08 18:48:02 +00:00
if # includes > 0 then
m.element ( " ForcedIncludeFiles " , condition , table.concat ( includes , ' ; ' ) )
end
2013-02-11 18:25:33 +00:00
end
2013-02-20 14:57:37 +00:00
if # cfg.forceusings > 0 then
2015-05-08 21:08:41 +00:00
local usings = vstudio.path ( cfg , cfg.forceusings )
2015-06-08 18:48:02 +00:00
if # usings > 0 then
m.element ( " ForcedUsingFiles " , condition , table.concat ( usings , ' ; ' ) )
end
2013-02-20 14:57:37 +00:00
end
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . functionLevelLinking ( cfg )
2013-09-13 15:15:36 +00:00
if config.isOptimizedBuild ( cfg ) then
2015-07-15 20:50:59 +00:00
m.element ( " FunctionLevelLinking " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . generateDebugInformation ( cfg )
2016-06-22 15:36:42 +00:00
m.element ( " GenerateDebugInformation " , nil , tostring ( cfg.symbols == p.ON ) )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . generateManifest ( cfg )
2013-02-11 18:25:33 +00:00
if cfg.flags . NoManifest then
2015-07-15 20:50:59 +00:00
m.element ( " GenerateManifest " , nil , " false " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . generateMapFile ( cfg )
2014-05-01 19:32:50 +00:00
if cfg.flags . Maps then
2015-07-15 20:50:59 +00:00
m.element ( " GenerateMapFile " , nil , " true " )
2014-05-01 19:32:50 +00:00
end
end
2015-08-24 14:44:12 +00:00
function m . ignoreDefaultLibraries ( cfg )
if # cfg.ignoredefaultlibraries > 0 then
local ignored = cfg.ignoredefaultlibraries
for i = 1 , # ignored do
-- Add extension if required
if not p.tools . msc.getLibraryExtensions ( ) [ ignored [ i ] : match ( " [^.]+$ " ) ] then
ignored [ i ] = path.appendextension ( ignored [ i ] , " .lib " )
end
end
m.element ( " IgnoreSpecificDefaultLibraries " , condition , table.concat ( ignored , ' ; ' ) )
end
end
2014-12-08 22:42:00 +00:00
function m . ignoreWarnDuplicateFilename ( prj )
-- VS 2013 warns on duplicate file names, even those files which are
-- contained in different, mututally exclusive configurations. See:
-- http://connect.microsoft.com/VisualStudio/feedback/details/797460/incorrect-warning-msb8027-reported-for-files-excluded-from-build
-- Premake already adds unique object names to conflicting file names, so
-- just go ahead and disable that warning.
if _ACTION > " vs2012 " then
2015-07-15 20:50:59 +00:00
m.element ( " IgnoreWarnCompileDuplicatedFilename " , nil , " true " )
2014-12-08 22:42:00 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . ignoreImportLibrary ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.kind == p.SHAREDLIB and cfg.flags . NoImportLib then
2015-07-15 20:50:59 +00:00
m.element ( " IgnoreImportLibrary " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . imageXex ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.system == p.XBOX360 then
2015-07-09 19:13:11 +00:00
p.push ( ' <ImageXex> ' )
2015-05-05 18:46:00 +00:00
if cfg.configfile then
2015-07-15 20:50:59 +00:00
m.element ( " ConfigurationFile " , nil , " %s " , cfg.configfile )
2014-09-20 22:32:18 +00:00
else
2015-07-09 19:13:11 +00:00
p.w ( ' <ConfigurationFile> ' )
p.w ( ' </ConfigurationFile> ' )
2014-09-20 22:32:18 +00:00
end
2015-07-09 19:13:11 +00:00
p.w ( ' <AdditionalSections> ' )
p.w ( ' </AdditionalSections> ' )
p.pop ( ' </ImageXex> ' )
2013-03-07 17:14:03 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . imageXexOutput ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.system == p.XBOX360 then
2015-07-15 20:50:59 +00:00
m.element ( " ImageXexOutput " , nil , " %s " , " $(OutDir)$(TargetName).xex " )
2013-03-07 17:14:03 +00:00
end
end
2015-08-31 18:58:23 +00:00
function m . importLanguageTargets ( prj )
2014-06-12 23:05:44 +00:00
p.w ( ' <Import Project="$(VCTargetsPath) \\ Microsoft.Cpp.targets" /> ' )
2015-08-31 18:58:23 +00:00
end
m.elements . importExtensionTargets = function ( prj )
return {
2016-04-05 16:12:33 +00:00
m.importGroupTargets ,
2015-08-31 18:58:23 +00:00
m.importRuleTargets ,
2016-03-19 16:23:28 +00:00
m.importNuGetTargets ,
2016-02-23 03:54:20 +00:00
m.importBuildCustomizationsTargets
2015-08-31 18:58:23 +00:00
}
end
function m . importExtensionTargets ( prj )
2014-06-12 23:05:44 +00:00
p.push ( ' <ImportGroup Label="ExtensionTargets"> ' )
2015-08-31 18:58:23 +00:00
p.callArray ( m.elements . importExtensionTargets , prj )
p.pop ( ' </ImportGroup> ' )
end
2014-10-20 19:41:00 +00:00
2016-04-05 16:12:33 +00:00
function m . importGroupTargets ( prj )
local groups = m.categorizeSources ( prj )
for _ , group in ipairs ( groups ) do
if group.category . emitExtensionTargets then
group.category . emitExtensionTargets ( prj , group )
end
end
end
2015-08-31 18:58:23 +00:00
function m . importRuleTargets ( prj )
2014-10-20 19:41:00 +00:00
for i = 1 , # prj.rules do
local rule = p.global . getRule ( prj.rules [ i ] )
2015-05-08 21:08:41 +00:00
local loc = vstudio.path ( prj , p.filename ( rule , " .targets " ) )
p.x ( ' <Import Project="%s" /> ' , loc )
2014-10-20 19:41:00 +00:00
end
2013-02-11 18:25:33 +00:00
end
2016-03-19 16:23:28 +00:00
local function nuGetTargetsFile ( prj , package )
return p.vstudio . path ( prj , p.filename ( prj.solution , string.format ( " packages \\ %s \\ build \\ native \\ %s.targets " , vstudio.nuget2010 . packageName ( package ) , vstudio.nuget2010 . packageId ( package ) ) ) )
end
function m . importNuGetTargets ( prj )
2016-03-21 18:10:28 +00:00
for i = 1 , # prj.nuget do
local targetsFile = nuGetTargetsFile ( prj , prj.nuget [ i ] )
p.x ( ' <Import Project="%s" Condition="Exists( \' %s \' )" /> ' , targetsFile , targetsFile )
2016-03-19 16:23:28 +00:00
end
end
2016-02-23 03:54:20 +00:00
function m . importBuildCustomizationsTargets ( prj )
for i , build in ipairs ( prj.buildcustomizations ) do
2016-04-05 16:12:33 +00:00
p.w ( ' <Import Project="$(VCTargetsPath) \\ %s.targets" /> ' , path.translate ( build ) )
end
2016-02-23 03:54:20 +00:00
end
2013-02-11 18:25:33 +00:00
2014-05-22 13:55:28 +00:00
2016-03-19 16:23:28 +00:00
function m . ensureNuGetPackageBuildImports ( prj )
2016-04-13 22:55:44 +00:00
if # prj.nuget > 0 then
p.push ( ' <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> ' )
p.push ( ' <PropertyGroup> ' )
p.x ( ' <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> ' )
p.pop ( ' </PropertyGroup> ' )
2016-03-19 16:23:28 +00:00
2016-04-13 22:55:44 +00:00
for i = 1 , # prj.nuget do
local targetsFile = nuGetTargetsFile ( prj , prj.nuget [ i ] )
p.x ( ' <Error Condition="!Exists( \' %s \' )" Text="$([System.String]::Format( \' $(ErrorText) \' , \' %s \' ))" /> ' , targetsFile , targetsFile )
end
p.pop ( ' </Target> ' )
2016-03-19 16:23:28 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . importDefaultProps ( prj )
2015-07-09 19:13:11 +00:00
p.w ( ' <Import Project="$(VCTargetsPath) \\ Microsoft.Cpp.Default.props" /> ' )
2014-05-22 13:55:28 +00:00
end
2015-08-31 19:22:46 +00:00
function m . importLanguageSettings ( prj )
2014-06-10 20:38:16 +00:00
p.w ( ' <Import Project="$(VCTargetsPath) \\ Microsoft.Cpp.props" /> ' )
2015-08-31 19:22:46 +00:00
end
m.elements . importExtensionSettings = function ( prj )
return {
2016-04-05 16:12:33 +00:00
m.importGroupSettings ,
2015-08-31 19:22:46 +00:00
m.importRuleSettings ,
2016-02-23 03:54:20 +00:00
m.importBuildCustomizationsProps
2015-08-31 19:22:46 +00:00
}
end
function m . importExtensionSettings ( prj )
2014-06-10 20:38:16 +00:00
p.push ( ' <ImportGroup Label="ExtensionSettings"> ' )
2015-08-31 19:22:46 +00:00
p.callArray ( m.elements . importExtensionSettings , prj )
p.pop ( ' </ImportGroup> ' )
end
2014-10-20 19:41:00 +00:00
2016-04-05 16:12:33 +00:00
function m . importGroupSettings ( prj )
local groups = m.categorizeSources ( prj )
for _ , group in ipairs ( groups ) do
if group.category . emitExtensionSettings then
group.category . emitExtensionSettings ( prj , group )
end
end
end
2015-08-31 19:22:46 +00:00
function m . importRuleSettings ( prj )
2014-10-20 19:41:00 +00:00
for i = 1 , # prj.rules do
local rule = p.global . getRule ( prj.rules [ i ] )
2015-05-08 21:08:41 +00:00
local loc = vstudio.path ( prj , p.filename ( rule , " .props " ) )
p.x ( ' <Import Project="%s" /> ' , loc )
2014-10-20 19:41:00 +00:00
end
2014-05-22 13:55:28 +00:00
end
2016-04-05 16:12:33 +00:00
2016-02-23 03:54:20 +00:00
function m . importBuildCustomizationsProps ( prj )
for i , build in ipairs ( prj.buildcustomizations ) do
2016-04-05 16:12:33 +00:00
p.w ( ' <Import Project="$(VCTargetsPath) \\ %s.props" /> ' , path.translate ( build ) )
end
2016-02-23 03:54:20 +00:00
end
2014-05-22 13:55:28 +00:00
function m . importLibrary ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.kind == p.SHAREDLIB then
2015-07-15 20:50:59 +00:00
m.element ( " ImportLibrary " , nil , " %s " , path.translate ( cfg.linktarget . relpath ) )
2013-02-11 18:25:33 +00:00
end
end
2015-05-13 19:41:29 +00:00
function m . includePath ( cfg )
local dirs = vstudio.path ( cfg , cfg.sysincludedirs )
if # dirs > 0 then
2015-07-15 20:50:59 +00:00
m.element ( " IncludePath " , nil , " %s;$(IncludePath) " , table.concat ( dirs , " ; " ) )
2015-05-13 19:41:29 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . intDir ( cfg )
2015-05-08 21:08:41 +00:00
local objdir = vstudio.path ( cfg , cfg.objdir )
2015-07-15 20:50:59 +00:00
m.element ( " IntDir " , nil , " %s \\ " , objdir )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . intrinsicFunctions ( cfg )
2013-09-13 15:15:36 +00:00
if config.isOptimizedBuild ( cfg ) then
2015-07-15 20:50:59 +00:00
m.element ( " IntrinsicFunctions " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 14:26:16 +00:00
function m . keyword ( prj )
-- try to determine what kind of targets we're building here
local isWin , isManaged , isMakefile
for cfg in project.eachconfig ( prj ) do
2015-07-14 19:52:01 +00:00
if cfg.system == p.WINDOWS then
2014-05-22 14:26:16 +00:00
isWin = true
end
2014-11-12 00:29:28 +00:00
if cfg.clr ~= p.OFF then
2014-05-22 14:26:16 +00:00
isManaged = true
end
if vstudio.isMakefile ( cfg ) then
isMakefile = true
end
end
if isWin then
if isMakefile then
2015-07-15 20:50:59 +00:00
m.element ( " Keyword " , nil , " MakeFileProj " )
2014-05-22 14:26:16 +00:00
else
if isManaged then
m.targetFramework ( prj )
2015-07-15 20:50:59 +00:00
m.element ( " Keyword " , nil , " ManagedCProj " )
2014-05-22 14:26:16 +00:00
else
2015-07-15 20:50:59 +00:00
m.element ( " Keyword " , nil , " Win32Proj " )
2014-05-22 14:26:16 +00:00
end
2015-07-15 20:50:59 +00:00
m.element ( " RootNamespace " , nil , " %s " , prj.name )
2014-05-22 14:26:16 +00:00
end
end
end
2015-05-17 21:53:55 +00:00
function m . libraryPath ( cfg )
local dirs = vstudio.path ( cfg , cfg.syslibdirs )
if # dirs > 0 then
2015-07-15 20:50:59 +00:00
m.element ( " LibraryPath " , nil , " %s;$(LibraryPath) " , table.concat ( dirs , " ; " ) )
2015-05-17 21:53:55 +00:00
end
end
2014-05-22 14:26:16 +00:00
2014-05-22 13:55:28 +00:00
function m . linkIncremental ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.kind ~= p.STATICLIB then
2015-07-15 20:50:59 +00:00
m.element ( " LinkIncremental " , nil , " %s " , tostring ( config.canLinkIncremental ( cfg ) ) )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . linkLibraryDependencies ( cfg , explicit )
2013-02-11 18:25:33 +00:00
-- Left to its own devices, VS will happily link against a project dependency
-- that has been excluded from the build. As a workaround, disable dependency
-- linking and list all siblings explicitly
if explicit then
2015-07-09 19:13:11 +00:00
p.push ( ' <ProjectReference> ' )
2015-07-15 20:50:59 +00:00
m.element ( " LinkLibraryDependencies " , nil , " false " )
2015-07-09 19:13:11 +00:00
p.pop ( ' </ProjectReference> ' )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . minimalRebuild ( cfg )
2013-09-13 15:15:36 +00:00
if config.isOptimizedBuild ( cfg ) or
2013-02-11 18:25:33 +00:00
cfg.flags . NoMinimalRebuild or
cfg.flags . MultiProcessorCompile or
2015-07-14 19:52:01 +00:00
cfg.debugformat == p.C7
2013-02-11 18:25:33 +00:00
then
2015-07-15 20:50:59 +00:00
m.element ( " MinimalRebuild " , nil , " false " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . moduleDefinitionFile ( cfg )
2013-02-21 15:28:41 +00:00
local df = config.findfile ( cfg , " .def " )
if df then
2015-07-15 20:50:59 +00:00
m.element ( " ModuleDefinitionFile " , nil , " %s " , df )
2013-02-21 15:28:41 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . multiProcessorCompilation ( cfg )
2013-02-11 18:25:33 +00:00
if cfg.flags . MultiProcessorCompile then
2015-07-15 20:50:59 +00:00
m.element ( " MultiProcessorCompilation " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . nmakeCommandLine ( cfg , commands , phase )
2013-04-07 18:30:58 +00:00
if # commands > 0 then
2014-11-29 19:51:49 +00:00
commands = os.translateCommands ( commands , p.WINDOWS )
2015-07-14 19:52:01 +00:00
commands = table.concat ( p.esc ( commands ) , p.eol ( ) )
2015-07-09 19:13:11 +00:00
p.w ( ' <NMake%sCommandLine>%s</NMake%sCommandLine> ' , phase , commands , phase )
2013-04-07 18:30:58 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . nmakeOutDirs ( cfg )
2013-06-26 11:28:57 +00:00
if vstudio.isMakefile ( cfg ) then
2014-05-22 13:55:28 +00:00
m.outDir ( cfg )
m.intDir ( cfg )
2013-04-25 15:45:44 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . nmakeOutput ( cfg )
2015-07-15 20:50:59 +00:00
m.element ( " NMakeOutput " , nil , " $(OutDir)%s " , cfg.buildtarget . name )
2013-04-03 15:53:00 +00:00
end
2014-06-11 20:05:25 +00:00
function m . objectFileName ( fcfg )
if fcfg.objname ~= fcfg.basename then
2015-07-15 20:50:59 +00:00
m.element ( " ObjectFileName " , m.condition ( fcfg.config ) , " $(IntDir) \\ %s.obj " , fcfg.objname )
2013-03-12 23:26:25 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . omitDefaultLib ( cfg )
if cfg.flags . OmitDefaultLibrary then
2015-07-15 20:50:59 +00:00
m.element ( " OmitDefaultLibName " , nil , " true " )
2014-05-22 13:55:28 +00:00
end
end
function m . omitFramePointers ( cfg )
2013-02-11 18:25:33 +00:00
if cfg.flags . NoFramePointer then
2015-07-15 20:50:59 +00:00
m.element ( " OmitFramePointers " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . optimizeReferences ( cfg )
2013-09-13 15:15:36 +00:00
if config.isOptimizedBuild ( cfg ) then
2015-07-15 20:50:59 +00:00
m.element ( " EnableCOMDATFolding " , nil , " true " )
m.element ( " OptimizeReferences " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . optimization ( cfg , condition )
2013-10-16 18:29:49 +00:00
local map = { Off = " Disabled " , On = " Full " , Debug = " Disabled " , Full = " Full " , Size = " MinSpace " , Speed = " MaxSpeed " }
local value = map [ cfg.optimize ]
if value or not condition then
2014-06-11 20:05:25 +00:00
m.element ( ' Optimization ' , condition , value or " Disabled " )
2013-10-16 18:29:49 +00:00
end
2012-08-01 19:28:21 +00:00
end
2014-05-22 13:55:28 +00:00
function m . outDir ( cfg )
2015-05-08 21:08:41 +00:00
local outdir = vstudio.path ( cfg , cfg.buildtarget . directory )
2015-07-15 20:50:59 +00:00
m.element ( " OutDir " , nil , " %s \\ " , outdir )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . outputFile ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.system == p.XBOX360 then
2015-07-15 20:50:59 +00:00
m.element ( " OutputFile " , nil , " $(OutDir)%s " , cfg.buildtarget . name )
2013-02-11 18:25:33 +00:00
end
end
2015-03-25 16:47:05 +00:00
function m . executablePath ( cfg )
2015-06-08 18:48:02 +00:00
local dirs = vstudio.path ( cfg , cfg.bindirs )
2015-03-25 16:47:05 +00:00
if # dirs > 0 then
2015-07-15 20:50:59 +00:00
m.element ( " ExecutablePath " , nil , " %s;$(ExecutablePath) " , table.concat ( dirs , " ; " ) )
2015-03-25 16:47:05 +00:00
end
end
2014-12-08 22:42:00 +00:00
function m . platformToolset ( cfg )
2015-04-28 22:50:56 +00:00
local tool , version = p.config . toolset ( cfg )
2015-09-01 12:36:17 +00:00
if not version then
2015-07-14 19:52:01 +00:00
local action = p.action . current ( )
2015-04-28 22:50:56 +00:00
version = action.vstudio . platformToolset
end
if version then
2015-08-24 10:56:44 +00:00
if cfg.kind == p.NONE or cfg.kind == p.MAKEFILE then
2015-09-16 12:31:40 +00:00
if p.config . hasFile ( cfg , path.iscppfile ) then
2015-07-15 20:50:59 +00:00
m.element ( " PlatformToolset " , nil , version )
2014-12-08 22:42:00 +00:00
end
2015-08-24 10:56:44 +00:00
else
m.element ( " PlatformToolset " , nil , version )
2014-12-08 22:42:00 +00:00
end
end
end
2015-07-06 22:08:32 +00:00
function m . precompiledHeader ( cfg , condition )
prjcfg , filecfg = p.config . normalize ( cfg )
2013-03-12 23:26:25 +00:00
if filecfg then
2015-07-06 22:08:32 +00:00
if prjcfg.pchsource == filecfg.abspath and not prjcfg.flags . NoPCH then
2014-06-11 20:05:25 +00:00
m.element ( ' PrecompiledHeader ' , condition , ' Create ' )
2013-10-16 20:11:39 +00:00
elseif filecfg.flags . NoPCH then
2014-06-11 20:05:25 +00:00
m.element ( ' PrecompiledHeader ' , condition , ' NotUsing ' )
2013-03-12 23:26:25 +00:00
end
2013-02-11 18:25:33 +00:00
else
2015-07-06 22:08:32 +00:00
if not prjcfg.flags . NoPCH and prjcfg.pchheader then
2015-07-15 20:50:59 +00:00
m.element ( " PrecompiledHeader " , nil , " Use " )
m.element ( " PrecompiledHeaderFile " , nil , " %s " , prjcfg.pchheader )
2013-03-12 23:26:25 +00:00
else
2015-07-15 20:50:59 +00:00
m.element ( " PrecompiledHeader " , nil , " NotUsing " )
2013-03-12 23:26:25 +00:00
end
2013-02-11 18:25:33 +00:00
end
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . preprocessorDefinitions ( cfg , defines , escapeQuotes , condition )
2012-08-01 19:28:21 +00:00
if # defines > 0 then
defines = table.concat ( defines , " ; " )
2013-04-30 16:25:25 +00:00
if escapeQuotes then
defines = defines : gsub ( ' " ' , ' \\ " ' )
end
2015-07-14 19:52:01 +00:00
defines = p.esc ( defines ) .. " ;%%(PreprocessorDefinitions) "
2014-06-11 20:05:25 +00:00
m.element ( ' PreprocessorDefinitions ' , condition , defines )
2012-08-01 19:28:21 +00:00
end
end
2015-03-09 22:49:19 +00:00
function m . undefinePreprocessorDefinitions ( cfg , undefines , escapeQuotes , condition )
if # undefines > 0 then
undefines = table.concat ( undefines , " ; " )
if escapeQuotes then
undefines = undefines : gsub ( ' " ' , ' \\ " ' )
end
2015-07-14 19:52:01 +00:00
undefines = p.esc ( undefines ) .. " ;%%(UndefinePreprocessorDefinitions) "
2015-03-09 22:49:19 +00:00
m.element ( ' UndefinePreprocessorDefinitions ' , condition , undefines )
end
end
2014-05-22 13:55:28 +00:00
function m . programDataBaseFileName ( cfg )
2016-06-22 16:18:03 +00:00
if cfg.symbolspath and cfg.symbols == p.ON and cfg.debugformat ~= " c7 " then
m.element ( " ProgramDataBaseFileName " , nil , p.project . getrelative ( cfg.project , cfg.symbolspath ) )
end
2013-02-11 18:25:33 +00:00
end
2012-08-01 19:28:21 +00:00
2013-02-11 18:25:33 +00:00
2014-05-22 13:55:28 +00:00
function m . projectGuid ( prj )
2015-07-15 20:50:59 +00:00
m.element ( " ProjectGuid " , nil , " {%s} " , prj.uuid )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . projectName ( prj )
2013-05-01 16:08:41 +00:00
if prj.name ~= prj.filename then
2015-07-15 20:50:59 +00:00
m.element ( " ProjectName " , nil , " %s " , prj.name )
2013-05-01 16:08:41 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . propertyGroup ( cfg , label )
2013-02-11 18:25:33 +00:00
local cond
if cfg then
2014-05-22 13:55:28 +00:00
cond = string.format ( ' %s ' , m.condition ( cfg ) )
2012-08-01 19:28:21 +00:00
end
2013-02-11 18:25:33 +00:00
if label then
label = string.format ( ' Label="%s" ' , label )
end
2015-07-09 19:13:11 +00:00
p.push ( ' <PropertyGroup%s%s> ' , cond or " " , label or " " )
2012-12-11 16:17:43 +00:00
end
2012-08-01 19:28:21 +00:00
2014-05-22 13:55:28 +00:00
function m . propertySheets ( cfg )
2015-07-09 19:13:11 +00:00
p.push ( ' <ImportGroup Label="PropertySheets" %s> ' , m.condition ( cfg ) )
p.w ( ' <Import Project="$(UserRootDir) \\ Microsoft.Cpp.$(Platform).user.props" Condition="exists( \' $(UserRootDir) \\ Microsoft.Cpp.$(Platform).user.props \' )" Label="LocalAppDataPlatform" /> ' )
p.pop ( ' </ImportGroup> ' )
2014-05-22 13:55:28 +00:00
end
function m . propertySheetGroup ( prj )
for cfg in project.eachconfig ( prj ) do
m.propertySheets ( cfg )
end
end
2014-10-02 20:40:28 +00:00
function m . referenceCopyLocalSatelliteAssemblies ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " CopyLocalSatelliteAssemblies " , nil , " false " )
2014-10-02 20:40:28 +00:00
end
function m . referenceLinkLibraryDependencies ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " LinkLibraryDependencies " , nil , " true " )
2014-10-02 20:40:28 +00:00
end
function m . referenceOutputAssembly ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " ReferenceOutputAssembly " , nil , " true " )
2014-10-02 20:40:28 +00:00
end
function m . referencePrivate ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " Private " , nil , " true " )
2014-10-02 20:40:28 +00:00
end
function m . referenceProject ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " Project " , nil , " {%s} " , ref.uuid )
2014-10-02 20:40:28 +00:00
end
function m . referenceUseLibraryDependences ( prj , ref )
2015-07-15 20:50:59 +00:00
m.element ( " UseLibraryDependencyInputs " , nil , " false " )
2014-10-02 20:40:28 +00:00
end
2014-05-22 13:55:28 +00:00
function m . resourceAdditionalIncludeDirectories ( cfg )
m.additionalIncludeDirectories ( cfg , table.join ( cfg.includedirs , cfg.resincludedirs ) )
2013-04-30 16:38:11 +00:00
end
2014-05-22 13:55:28 +00:00
function m . resourcePreprocessorDefinitions ( cfg )
m.preprocessorDefinitions ( cfg , table.join ( cfg.defines , cfg.resdefines ) , true )
2013-04-30 16:38:11 +00:00
end
2014-05-22 13:55:28 +00:00
function m . runtimeLibrary ( cfg )
2013-03-27 15:12:37 +00:00
local runtimes = {
2015-06-10 23:26:51 +00:00
StaticDebug = " MultiThreadedDebug " ,
2013-03-27 15:12:37 +00:00
StaticRelease = " MultiThreaded " ,
}
local runtime = runtimes [ config.getruntime ( cfg ) ]
if runtime then
2015-07-15 20:50:59 +00:00
m.element ( " RuntimeLibrary " , nil , runtime )
2013-02-08 15:35:14 +00:00
end
end
2015-06-03 02:16:53 +00:00
function m . callingConvention ( cfg )
if cfg.callingconvention then
2015-07-15 20:50:59 +00:00
m.element ( " CallingConvention " , nil , cfg.callingconvention )
2015-06-03 02:16:53 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . runtimeTypeInfo ( cfg )
2015-06-16 15:44:18 +00:00
if cfg.rtti == p.OFF and cfg.clr == p.OFF then
2015-07-15 20:50:59 +00:00
m.element ( " RuntimeTypeInfo " , nil , " false " )
2015-06-16 15:44:18 +00:00
elseif cfg.rtti == p.ON then
2015-07-15 20:50:59 +00:00
m.element ( " RuntimeTypeInfo " , nil , " true " )
2013-02-08 15:35:14 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . bufferSecurityCheck ( cfg )
2015-07-26 01:08:44 +00:00
local tool , toolVersion = p.config . toolset ( cfg )
if cfg.flags . NoBufferSecurityCheck or ( toolVersion and toolVersion : startswith ( " LLVM-vs " ) ) then
2015-07-15 20:50:59 +00:00
m.element ( " BufferSecurityCheck " , nil , " false " )
2013-08-15 22:22:23 +00:00
end
end
2013-02-08 15:35:14 +00:00
2014-05-22 13:55:28 +00:00
function m . stringPooling ( cfg )
2013-09-13 15:15:36 +00:00
if config.isOptimizedBuild ( cfg ) then
2015-07-15 20:50:59 +00:00
m.element ( " StringPooling " , nil , " true " )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . subSystem ( cfg )
2015-07-14 19:52:01 +00:00
if cfg.system ~= p.XBOX360 then
local subsystem = iif ( cfg.kind == p.CONSOLEAPP , " Console " , " Windows " )
2015-07-15 20:50:59 +00:00
m.element ( " SubSystem " , nil , subsystem )
2013-03-07 17:14:03 +00:00
end
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . targetExt ( cfg )
2013-05-22 13:06:33 +00:00
local ext = cfg.buildtarget . extension
if ext ~= " " then
2015-07-15 20:50:59 +00:00
m.element ( " TargetExt " , nil , " %s " , ext )
2013-05-22 13:06:33 +00:00
else
2015-07-09 19:13:11 +00:00
p.w ( ' <TargetExt> ' )
p.w ( ' </TargetExt> ' )
2013-05-22 13:06:33 +00:00
end
2013-02-11 18:25:33 +00:00
end
2015-12-16 21:25:37 +00:00
function m . targetMachine ( cfg )
-- If a static library project contains a resource file, VS will choke with
-- "LINK : warning LNK4068: /MACHINE not specified; defaulting to X86"
local targetmachine = {
x86 = " MachineX86 " ,
x86_64 = " MachineX64 " ,
}
2015-12-17 00:50:37 +00:00
if cfg.kind == p.STATICLIB and config.hasFile ( cfg , path.isresourcefile ) then
2015-12-16 21:25:37 +00:00
local value = targetmachine [ cfg.architecture ]
if value ~= nil then
m.element ( " TargetMachine " , nil , ' %s ' , value )
end
end
end
2014-05-22 13:55:28 +00:00
function m . targetName ( cfg )
2015-07-15 20:50:59 +00:00
m.element ( " TargetName " , nil , " %s%s " , cfg.buildtarget . prefix , cfg.buildtarget . basename )
2013-02-11 18:25:33 +00:00
end
2016-03-17 12:56:23 +00:00
function m . targetPlatformVersion ( prj )
local min = project.systemversion ( prj )
if min ~= nil and _ACTION >= " vs2015 " then
m.element ( " WindowsTargetPlatformVersion " , nil , min )
end
end
2014-05-22 13:55:28 +00:00
function m . treatLinkerWarningAsErrors ( cfg )
2014-02-14 17:23:12 +00:00
if cfg.flags . FatalLinkWarnings then
2015-07-14 19:52:01 +00:00
local el = iif ( cfg.kind == p.STATICLIB , " Lib " , " Linker " )
2015-07-15 20:50:59 +00:00
m.element ( " Treat " .. el .. " WarningAsErrors " , nil , " true " )
2013-12-24 19:01:57 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . treatWChar_tAsBuiltInType ( cfg )
2013-09-27 19:12:50 +00:00
local map = { On = " true " , Off = " false " }
local value = map [ cfg.nativewchar ]
if value then
2015-07-15 20:50:59 +00:00
m.element ( " TreatWChar_tAsBuiltInType " , nil , value )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . treatWarningAsError ( cfg )
2014-11-12 00:29:28 +00:00
if cfg.flags . FatalCompileWarnings and cfg.warnings ~= p.OFF then
2015-07-15 20:50:59 +00:00
m.element ( " TreatWarningAsError " , nil , " true " )
2013-01-12 16:52:59 +00:00
end
2012-12-11 16:17:43 +00:00
end
2015-03-09 23:53:46 +00:00
function m . disableSpecificWarnings ( cfg , condition )
if # cfg.disablewarnings > 0 then
local warnings = table.concat ( cfg.disablewarnings , " ; " )
2015-07-14 19:52:01 +00:00
warnings = p.esc ( warnings ) .. " ;%%(DisableSpecificWarnings) "
2015-03-09 23:53:46 +00:00
m.element ( ' DisableSpecificWarnings ' , condition , warnings )
end
end
2015-03-26 14:22:55 +00:00
2015-03-09 23:53:46 +00:00
function m . treatSpecificWarningsAsErrors ( cfg , condition )
if # cfg.fatalwarnings > 0 then
local fatal = table.concat ( cfg.fatalwarnings , " ; " )
2015-07-14 19:52:01 +00:00
fatal = p.esc ( fatal ) .. " ;%%(TreatSpecificWarningsAsErrors) "
2015-03-09 23:53:46 +00:00
m.element ( ' TreatSpecificWarningsAsErrors ' , condition , fatal )
end
end
2014-05-22 13:55:28 +00:00
function m . useDebugLibraries ( cfg )
2013-03-27 15:12:37 +00:00
local runtime = config.getruntime ( cfg )
2015-07-15 20:50:59 +00:00
m.element ( " UseDebugLibraries " , nil , tostring ( runtime : endswith ( " Debug " ) ) )
2013-02-11 18:25:33 +00:00
end
2014-05-22 13:55:28 +00:00
function m . useOfMfc ( cfg )
2013-02-11 18:25:33 +00:00
if cfg.flags . MFC then
2015-07-15 20:50:59 +00:00
m.element ( " UseOfMfc " , nil , iif ( cfg.flags . StaticRuntime , " Static " , " Dynamic " ) )
2013-02-11 18:25:33 +00:00
end
end
2014-05-22 13:55:28 +00:00
function m . useOfAtl ( cfg )
2014-02-27 15:47:43 +00:00
if cfg.atl then
2015-07-15 20:50:59 +00:00
m.element ( " UseOfATL " , nil , cfg.atl )
2014-02-27 12:47:51 +00:00
end
end
2013-02-11 18:25:33 +00:00
2014-05-22 13:55:28 +00:00
function m . userMacros ( cfg )
2015-07-09 19:13:11 +00:00
p.w ( ' <PropertyGroup Label="UserMacros" /> ' )
2014-05-22 13:55:28 +00:00
end
function m . warningLevel ( cfg )
2013-09-29 16:39:07 +00:00
local map = { Off = " TurnOffAllWarnings " , Extra = " Level4 " }
2014-06-11 20:05:25 +00:00
m.element ( " WarningLevel " , nil , " %s " , map [ cfg.warnings ] or " Level3 " )
2012-08-01 19:28:21 +00:00
end
2013-03-12 23:26:25 +00:00
2014-09-12 19:47:22 +00:00
function m . xmlDeclaration ( )
p.xmlUtf8 ( )
end
2013-03-12 23:26:25 +00:00
---------------------------------------------------------------------------
--
-- Support functions
--
---------------------------------------------------------------------------
--
-- Format and return a Visual Studio Condition attribute.
--
2014-05-22 13:55:28 +00:00
function m . condition ( cfg )
2015-07-14 19:52:01 +00:00
return string.format ( ' Condition=" \' $(Configuration)|$(Platform) \' == \' %s \' " ' , p.esc ( vstudio.projectConfig ( cfg ) ) )
2013-03-12 23:26:25 +00:00
end
--
-- Output an individual project XML element, with an optional configuration
-- condition.
--
-- @param depth
-- How much to indent the element.
-- @param name
-- The element name.
-- @param condition
-- An optional configuration condition, formatted with vc2010.condition().
-- @param value
-- The element value, which may contain printf formatting tokens.
-- @param ...
-- Optional additional arguments to satisfy any tokens in the value.
--
2014-06-11 20:05:25 +00:00
function m . element ( name , condition , value , ... )
2013-03-12 23:26:25 +00:00
if select ( ' # ' , ... ) == 0 then
2015-07-14 19:52:01 +00:00
value = p.esc ( value )
2013-03-12 23:26:25 +00:00
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 )
end
2014-06-11 20:05:25 +00:00
p.x ( format , ... )
2013-03-12 23:26:25 +00:00
end