1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621 |
- --
- -- vs200x_vcproj.lua
- -- Generate a Visual Studio 2005-2008 C/C++ project.
- -- Copyright (c) Jason Perkins and the Premake project
- --
- local p = premake
- p.vstudio.vc200x = {}
- local m = p.vstudio.vc200x
- local vstudio = p.vstudio
- local context = p.context
- local project = p.project
- local config = p.config
- local fileconfig = p.fileconfig
- m.elements = {}
- ---
- -- Generate a Visual Studio 200x C++ or Makefile project.
- ---
- m.elements.project = function(prj)
- return {
- m.xmlElement,
- m.visualStudioProject,
- m.platforms,
- m.toolFiles,
- m.configurations,
- m.references,
- m.files,
- m.globals
- }
- end
- function m.generate(prj)
- p.indent("\t")
- p.callArray(m.elements.project, prj)
- p.pop('</VisualStudioProject>')
- p.w()
- end
- ---
- -- Write the opening <VisualStudioProject> element of the project file.
- -- In this case, the call list is for XML attributes rather than elements.
- ---
- m.elements.visualStudioProject = function(prj)
- return {
- m.projectType,
- m.version,
- m.projectName,
- m.projectGUID,
- m.rootNamespace,
- m.keyword,
- m.targetFrameworkVersion
- }
- end
- function m.visualStudioProject(prj)
- p.push('<VisualStudioProject')
- p.callArray(m.elements.visualStudioProject, prj)
- p.w('>')
- end
- ---
- -- Write out the <Configurations> element group, enumerating each of the
- -- configuration-architecture pairings.
- ---
- function m.configurations(prj)
- p.push('<Configurations>')
- -- Visual Studio requires each configuration to be paired up with each
- -- architecture, even if the pairing doesn't make any sense (i.e. Win32
- -- DLL DCRT|PS3). Start by building a map between configurations and
- -- their Visual Studio names. I will use this to determine which
- -- pairings are "real", and which need to be synthesized.
- local mapping = {}
- for cfg in project.eachconfig(prj) do
- local name = vstudio.projectConfig(cfg)
- mapping[cfg] = name
- mapping[name] = cfg
- end
- -- Now enumerate each configuration and architecture pairing
- for cfg in project.eachconfig(prj) do
- for i, arch in ipairs(architectures) do
- local target
- -- Generate a Visual Studio name from this pairing and see if
- -- it matches. If so, I can go ahead and output the markup for
- -- this configuration.
- local testName = vstudio.projectConfig(cfg, arch)
- if testName == mapping[cfg] then
- target = cfg
- -- Okay, this pairing doesn't match this configuration. Check
- -- the mapping to see if it matches some *other* configuration.
- -- If it does, I can ignore it as it will getting written on
- -- another pass through the loop. If it does not, then this is
- -- one of those fake configurations that I have to synthesize.
- elseif not mapping[testName] then
- target = { fake = true }
- end
- -- If I'm not ignoring this pairing, output the result now
- if target then
- m.configuration(target, testName)
- m.tools(target)
- p.pop('</Configuration>')
- end
- end
- end
- p.pop('</Configurations>')
- end
- ---
- -- Write out the <Configuration> element, describing a specific Premake
- -- build configuration/platform pairing.
- ---
- m.elements.configuration = function(cfg)
- if cfg.fake then
- return {
- m.intermediateDirectory,
- m.configurationType
- }
- else
- return {
- m.outputDirectory,
- m.intermediateDirectory,
- m.configurationType,
- m.useOfMFC,
- m.characterSet,
- m.managedExtensions,
- }
- end
- end
- function m.configuration(cfg, name)
- p.push('<Configuration')
- p.w('Name="%s"', name)
- p.callArray(m.elements.configuration, cfg)
- p.w('>')
- end
- ---
- -- Return the list of tools required to build a specific configuration.
- -- Each tool gets represented by an XML element in the project file, all
- -- of which are implemented farther down in this file.
- --
- -- @param cfg
- -- The configuration being written.
- ---
- m.elements.tools = function(cfg)
- if vstudio.isMakefile(cfg) and not cfg.fake then
- return {
- m.VCNMakeTool
- }
- end
-
- return {
- m.VCPreBuildEventTool,
- m.VCCustomBuildTool,
- m.VCXMLDataGeneratorTool,
- m.VCWebServiceProxyGeneratorTool,
- m.VCMIDLTool,
- m.VCCLCompilerTool,
- m.VCManagedResourceCompilerTool,
- m.VCResourceCompilerTool,
- m.VCPreLinkEventTool,
- m.VCLinkerTool,
- m.VCALinkTool,
- m.VCManifestTool,
- m.VCXDCMakeTool,
- m.VCBscMakeTool,
- m.VCFxCopTool,
- m.VCAppVerifierTool,
- m.VCPostBuildEventTool,
- }
- end
- function m.tools(cfg)
- p.callArray(m.elements.tools, cfg, config.toolset(cfg))
- end
- ---
- -- Write out the <References> element group.
- ---
- m.elements.references = function(prj)
- return {
- m.assemblyReferences,
- m.projectReferences,
- }
- end
- function m.references(prj)
- p.push('<References>')
- p.callArray(m.elements.references, prj)
- p.pop('</References>')
- end
- ---
- -- Write out the <Files> element group.
- ---
- function m.files(prj)
- local tr = m.filesSorted(prj)
- p.push('<Files>')
- p.tree.traverse(tr, {
- onbranchenter = m.filesFilterStart,
- onbranchexit = m.filesFilterEnd,
- onleaf = m.filesFile,
- }, false)
- p.pop('</Files>')
- end
- function m.filesSorted(prj)
- -- Fetch the source tree, sorted how Visual Studio likes it: alpha
- -- sorted, with any leading ../ sequences ignored. At the top level
- -- of the tree, files go after folders, otherwise before.
- return project.getsourcetree(prj, function(a,b)
- local istop = (a.parent.parent == nil)
- local aSortName = a.name
- local bSortName = b.name
- -- Only file nodes have a relpath field; folder nodes do not
- if a.relpath then
- if not b.relpath then
- return not istop
- end
- aSortName = a.relpath:gsub("%.%.%/", "")
- end
- if b.relpath then
- if not a.relpath then
- return istop
- end
- bSortName = b.relpath:gsub("%.%.%/", "")
- end
- return aSortName < bSortName
- end)
- end
- function m.filesFilterStart(node)
- p.push('<Filter')
- p.w('Name="%s"', node.name)
- p.w('>')
- end
- function m.filesFilterEnd(node)
- p.pop('</Filter>')
- end
- function m.filesFile(node)
- p.push('<File')
- p.w('RelativePath="%s"', path.translate(node.relpath))
- p.w('>')
- local prj = node.project
- for cfg in project.eachconfig(prj) do
- m.fileConfiguration(cfg, node)
- end
- p.pop('</File>')
- end
- m.elements.fileConfigurationAttributes = function(filecfg)
- return {
- m.excludedFromBuild,
- }
- end
- function m.fileConfiguration(cfg, node)
- local filecfg = fileconfig.getconfig(node, cfg)
- -- Generate the individual sections of the file configuration
- -- element and capture the results to a buffer. I will only
- -- write the file configuration if the buffers are not empty.
- local configAttribs = p.capture(function ()
- p.push()
- p.callArray(m.elements.fileConfigurationAttributes, filecfg)
- p.pop()
- end)
- local compilerAttribs = p.capture(function ()
- p.push()
- m.VCCLCompilerTool(filecfg)
- p.pop()
- end)
- -- lines() > 3 skips empty <Tool Name="VCCLCompiler" /> elements
- if #configAttribs > 0 or compilerAttribs:lines() > 3 then
- p.push('<FileConfiguration')
- p.w('Name="%s"', vstudio.projectConfig(cfg))
- if #configAttribs > 0 then
- p.outln(configAttribs)
- end
- p.w('>')
- p.outln(compilerAttribs)
- p.pop('</FileConfiguration>')
- end
- end
- ---
- -- I don't do anything with globals yet, but here it is if you want to
- -- extend it.
- ---
- m.elements.globals = function(prj)
- return {}
- end
- function m.globals(prj)
- p.push('<Globals>')
- p.callArray(m.elements.globals, prj)
- p.pop('</Globals>')
- end
- ---------------------------------------------------------------------------
- --
- -- Handlers for the individual tool sections of the project.
- --
- -- There is a lot of repetition here; most of these tools are just
- -- placeholders for modules to override as needed.
- --
- ---------------------------------------------------------------------------
- ---
- -- The implementation of a "normal" tool. Writes the opening tool element
- -- and name attribute, calls the corresponding function list, and then
- -- closes the element.
- --
- -- @param name
- -- The name of the tool, e.g. "VCCustomBuildTool".
- -- @param ...
- -- Any additional arguments required by the call list.
- ---
- function m.VCTool(name, cfg, ...)
- p.push('<Tool')
- local nameFunc = m[name .. "Name"]
- local callFunc = m.elements[name]
- if nameFunc then
- name = nameFunc(cfg, ...)
- end
- p.w('Name="%s"', name)
- if cfg and not cfg.fake then
- p.callArray(callFunc, cfg, ...)
- end
- p.pop('/>')
- end
- ------------
- m.elements.DebuggerTool = function(cfg)
- return {}
- end
- function m.DebuggerTool(cfg)
- p.push('<DebuggerTool')
- p.pop('/>')
- end
- ------------
- m.elements.VCALinkTool = function(cfg)
- return {}
- end
- function m.VCALinkTool(cfg)
- m.VCTool("VCALinkTool", cfg)
- end
- ------------
- m.elements.VCAppVerifierTool = function(cfg)
- return {}
- end
- function m.VCAppVerifierTool(cfg)
- if cfg.kind ~= p.STATICLIB then
- m.VCTool("VCAppVerifierTool", cfg)
- end
- end
- ------------
- m.elements.VCBscMakeTool = function(cfg)
- return {}
- end
- function m.VCBscMakeTool(cfg)
- m.VCTool("VCBscMakeTool", cfg)
- end
- ------------
- m.elements.VCCLCompilerTool = function(cfg, toolset)
- if not toolset then
- -- not a custom tool, use the standard set of attributes
- return {
- m.customBuildTool,
- m.objectFile,
- m.additionalCompilerOptions,
- m.optimization,
- m.additionalIncludeDirectories,
- m.wholeProgramOptimization,
- m.preprocessorDefinitions,
- m.undefinePreprocessorDefinitions,
- m.minimalRebuild,
- m.basicRuntimeChecks,
- m.bufferSecurityCheck,
- m.stringPooling,
- m.exceptionHandling,
- m.runtimeLibrary,
- m.enableFunctionLevelLinking,
- m.enableEnhancedInstructionSet,
- m.floatingPointModel,
- m.runtimeTypeInfo,
- m.treatWChar_tAsBuiltInType,
- m.usePrecompiledHeader,
- m.programDataBaseFileName,
- m.warningLevel,
- m.warnAsError,
- m.detect64BitPortabilityProblems,
- m.debugInformationFormat,
- m.compileAs,
- m.disableSpecificWarnings,
- m.forcedIncludeFiles,
- m.omitDefaultLib,
- }
- else
- -- custom tool, use subset of attributes
- return {
- m.additionalExternalCompilerOptions,
- m.additionalIncludeDirectories,
- m.preprocessorDefinitions,
- m.undefinePreprocessorDefinitions,
- m.usePrecompiledHeader,
- m.programDataBaseFileName,
- m.debugInformationFormat,
- m.compileAs,
- m.forcedIncludeFiles,
- }
- end
- end
- function m.VCCLCompilerToolName(cfg)
- local prjcfg, filecfg = config.normalize(cfg)
- if filecfg and fileconfig.hasCustomBuildRule(filecfg) then
- return "VCCustomBuildTool"
- else
- return "VCCLCompilerTool"
- end
- end
- function m.VCCLCompilerTool(cfg, toolset)
- m.VCTool("VCCLCompilerTool", cfg, toolset)
- end
- ------------
- m.elements.VCCustomBuildTool = function(cfg)
- return {}
- end
- function m.VCCustomBuildTool(cfg)
- m.VCTool("VCCustomBuildTool", cfg)
- end
- ------------
- m.elements.VCFxCopTool = function(cfg)
- return {}
- end
- function m.VCFxCopTool(cfg)
- m.VCTool("VCFxCopTool", cfg)
- end
- ------------
- m.elements.VCLinkerTool = function(cfg, toolset)
- if cfg.kind ~= p.STATICLIB then
- return {
- m.linkLibraryDependencies,
- m.ignoreImportLibrary,
- m.additionalLinkerOptions,
- m.additionalDependencies,
- m.outputFile,
- m.linkIncremental,
- m.additionalLibraryDirectories,
- m.moduleDefinitionFile,
- m.generateManifest,
- m.generateDebugInformation,
- m.programDatabaseFile,
- m.subSystem,
- m.largeAddressAware,
- m.optimizeReferences,
- m.enableCOMDATFolding,
- m.entryPointSymbol,
- m.importLibrary,
- m.targetMachine,
- }
- else
- return {
- m.additionalLinkerOptions,
- m.additionalDependencies,
- m.outputFile,
- m.additionalLibraryDirectories,
- }
- end
- end
- function m.VCLinkerToolName(cfg)
- if cfg.kind == p.STATICLIB then
- return "VCLibrarianTool"
- else
- return "VCLinkerTool"
- end
- end
- function m.VCLinkerTool(cfg, toolset)
- m.VCTool("VCLinkerTool", cfg, toolset)
- end
- ------------
- m.elements.VCManagedResourceCompilerTool = function(cfg)
- return {}
- end
- function m.VCManagedResourceCompilerTool(cfg)
- m.VCTool("VCManagedResourceCompilerTool", cfg)
- end
- ------------
- m.elements.VCManifestTool = function(cfg)
- return {
- m.additionalManifestFiles,
- }
- end
- function m.VCManifestTool(cfg)
- if cfg.kind ~= p.STATICLIB then
- m.VCTool("VCManifestTool", cfg)
- end
- end
- ------------
- m.elements.VCMIDLTool = function(cfg)
- return {
- m.targetEnvironment
- }
- end
- function m.VCMIDLTool(cfg)
- m.VCTool("VCMIDLTool", cfg)
- end
- ------------
- m.elements.VCNMakeTool = function(cfg)
- return {
- m.buildCommandLine,
- m.reBuildCommandLine,
- m.cleanCommandLine,
- m.output,
- m.preprocessorDefinitions,
- m.undefinePreprocessorDefinitions,
- m.includeSearchPath,
- m.forcedIncludes,
- m.assemblySearchPath,
- m.forcedUsingAssemblies,
- m.compileAsManaged,
- }
- end
- function m.VCNMakeTool(cfg)
- m.VCTool("VCNMakeTool", cfg)
- end
- ------------
- m.elements.VCBuildTool = function(cfg, stage)
- return {
- m.commandLine,
- }
- end
- function m.VCBuildToolName(cfg, stage)
- return "VC" .. stage .. "EventTool"
- end
- function m.VCPreBuildEventTool(cfg)
- m.VCTool("VCBuildTool", cfg, "PreBuild")
- end
- function m.VCPreLinkEventTool(cfg)
- m.VCTool("VCBuildTool", cfg, "PreLink")
- end
- function m.VCPostBuildEventTool(cfg)
- m.VCTool("VCBuildTool", cfg, "PostBuild")
- end
- ------------
- m.elements.VCResourceCompilerTool = function(cfg)
- return {
- m.additionalResourceOptions,
- m.resourcePreprocessorDefinitions,
- m.additionalResourceIncludeDirectories,
- m.culture,
- }
- end
- function m.VCResourceCompilerTool(cfg)
- m.VCTool("VCResourceCompilerTool", cfg)
- end
- ------------
- m.elements.VCWebServiceProxyGeneratorTool = function(cfg)
- return {}
- end
- function m.VCWebServiceProxyGeneratorTool(cfg)
- m.VCTool("VCWebServiceProxyGeneratorTool", cfg)
- end
- ------------
- m.elements.VCXDCMakeTool = function(cfg)
- return {}
- end
- function m.VCXDCMakeTool(cfg)
- m.VCTool("VCXDCMakeTool", cfg)
- end
- ------------
- m.elements.VCXMLDataGeneratorTool = function(cfg)
- return {}
- end
- function m.VCXMLDataGeneratorTool(cfg)
- m.VCTool("VCXMLDataGeneratorTool", cfg)
- end
- ---------------------------------------------------------------------------
- --
- -- Support functions
- --
- ---------------------------------------------------------------------------
- --
- -- Return the debugging symbol level for a configuration.
- --
- function m.symbols(cfg)
- if not (cfg.symbols == p.ON) then
- return 0
- elseif cfg.debugformat == "c7" then
- return 1
- else
- -- Edit-and-continue doesn't work for some configurations
- if cfg.editandcontinue == p.OFF or
- config.isOptimizedBuild(cfg) or
- cfg.clr ~= p.OFF or
- cfg.architecture == p.X86_64
- then
- return 3
- else
- return 4
- end
- end
- end
- ---------------------------------------------------------------------------
- --
- -- Handlers for individual project elements
- --
- ---------------------------------------------------------------------------
- function m.additionalCompilerOptions(cfg)
- local opts = cfg.buildoptions
- if cfg.flags.MultiProcessorCompile then
- table.insert(opts, "/MP")
- end
- if #opts > 0 then
- p.x('AdditionalOptions="%s"', table.concat(opts, " "))
- end
- end
- function m.additionalDependencies(cfg, toolset)
- if #cfg.links == 0 then return end
- local ex = vstudio.needsExplicitLink(cfg)
- local links
- if not toolset then
- links = vstudio.getLinks(cfg, ex)
- for i, link in ipairs(links) do
- if link:find(" ", 1, true) then
- link = '"' .. link .. '"'
- end
- links[i] = path.translate(link)
- end
- else
- links = path.translate(toolset.getlinks(cfg, not ex))
- end
- if #links > 0 then
- p.x('AdditionalDependencies="%s"', table.concat(links, " "))
- end
- end
- function m.additionalExternalCompilerOptions(cfg, toolset)
- local buildoptions = table.join(toolset.getcxxflags(cfg), cfg.buildoptions)
- if not cfg.flags.NoPCH and cfg.pchheader then
- table.insert(buildoptions, '--use_pch="$(IntDir)/$(TargetName).pch"')
- end
- if #buildoptions > 0 then
- p.x('AdditionalOptions="%s"', table.concat(buildoptions, " "))
- end
- end
- function m.additionalImageOptions(cfg)
- if #cfg.imageoptions > 0 then
- p.x('AdditionalOptions="%s"', table.concat(cfg.imageoptions, " "))
- end
- end
- function m.additionalIncludeDirectories(cfg)
- if #cfg.includedirs > 0 then
- local dirs = vstudio.path(cfg, cfg.includedirs)
- p.x('AdditionalIncludeDirectories="%s"', table.concat(dirs, ";"))
- end
- end
- function m.additionalLibraryDirectories(cfg)
- if #cfg.libdirs > 0 then
- local dirs = vstudio.path(cfg, cfg.libdirs)
- p.x('AdditionalLibraryDirectories="%s"', table.concat(dirs, ";"))
- end
- end
- function m.additionalLinkerOptions(cfg, toolset)
- local flags
- if toolset then
- flags = table.join(toolset.getldflags(cfg), cfg.linkoptions)
- else
- flags = cfg.linkoptions
- end
- if #flags > 0 then
- p.x('AdditionalOptions="%s"', table.concat(flags, " "))
- end
- end
- function m.additionalManifestFiles(cfg)
- local manifests = {}
- for i, fname in ipairs(cfg.files) do
- if path.getextension(fname) == ".manifest" then
- table.insert(manifests, project.getrelative(cfg.project, fname))
- end
- end
- if #manifests > 0 then
- p.x('AdditionalManifestFiles="%s"', table.concat(manifests, ";"))
- end
- end
- function m.additionalResourceIncludeDirectories(cfg)
- local dirs = table.join(cfg.includedirs, cfg.resincludedirs)
- if #dirs > 0 then
- dirs = vstudio.path(cfg, dirs)
- p.x('AdditionalIncludeDirectories="%s"', table.concat(dirs, ";"))
- end
- end
- function m.additionalResourceOptions(cfg)
- if #cfg.resoptions > 0 then
- p.x('AdditionalOptions="%s"', table.concat(cfg.resoptions, " "))
- end
- end
- function m.assemblyReferences(prj)
- -- Visual Studio doesn't support per-config references
- local cfg = project.getfirstconfig(prj)
- local refs = config.getlinks(cfg, "system", "fullpath", "managed")
- table.foreachi(refs, function(value)
- p.push('<AssemblyReference')
- p.x('RelativePath="%s"', path.translate(value))
- p.pop('/>')
- end)
- end
- function m.assemblySearchPath(cfg)
- p.w('AssemblySearchPath=""')
- end
- function m.basicRuntimeChecks(cfg)
- local cfg, filecfg = config.normalize(cfg)
- if not filecfg
- and not config.isOptimizedBuild(cfg)
- and cfg.clr == p.OFF
- and not cfg.flags.NoRuntimeChecks
- then
- p.w('BasicRuntimeChecks="3"')
- end
- end
- function m.bufferSecurityCheck(cfg)
- if cfg.flags.NoBufferSecurityCheck then
- p.w('BufferSecurityCheck="false"')
- end
- end
- function m.buildCommandLine(cfg)
- local cmds = os.translateCommandsAndPaths(cfg.buildcommands, cfg.project.basedir, cfg.project.location)
- p.x('BuildCommandLine="%s"', table.concat(cmds, "\r\n"))
- end
- function m.characterSet(cfg)
- if not vstudio.isMakefile(cfg) then
- p.w('CharacterSet="%s"', iif(cfg.characterset == p.MBCS, 2, 1))
- end
- end
- function m.cleanCommandLine(cfg)
- local cmds = os.translateCommandsAndPaths(cfg.cleancommands, cfg.project.basedir, cfg.project.location)
- cmds = table.concat(cmds, "\r\n")
- p.x('CleanCommandLine="%s"', cmds)
- end
- function m.commandLine(cfg, stage)
- local field = stage:lower()
- local steps = cfg[field .. "commands"]
- local msg = cfg[field .. "message"]
- if #steps > 0 then
- if msg then
- p.x('Description="%s"', msg)
- end
- steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location)
- p.x('CommandLine="%s"', table.implode(steps, "", "", "\r\n"))
- end
- end
- function m.compileAs(cfg, toolset)
- local cfg, filecfg = config.normalize(cfg)
- local c = p.languages.isc(cfg.language)
- local compileAs
- if filecfg then
- if filecfg.compileas then
- compileAs = iif(p.languages.iscpp(filecfg.compileas), 2, 1)
- elseif path.iscfile(filecfg.name) ~= c then
- if path.iscppfile(filecfg.name) then
- compileAs = iif(c, 2, 1)
- end
- end
- else
- if toolset then
- compileAs = "0"
- elseif c then
- compileAs = "1"
- end
- end
- if compileAs then
- p.w('CompileAs="%s"', compileAs)
- end
- end
- function m.disableSpecificWarnings(cfg)
- if #cfg.disablewarnings > 0 then
- p.x('DisableSpecificWarnings="%s"', table.concat(cfg.disablewarnings, ";"))
- end
- end
- function m.compileAsManaged(cfg)
- p.w('CompileAsManaged=""')
- end
- function m.configurationType(cfg)
- local cfgtypes = {
- Makefile = 0,
- None = 0,
- SharedLib = 2,
- StaticLib = 4,
- }
- p.w('ConfigurationType="%s"', cfgtypes[cfg.kind] or 1)
- end
- function m.culture(cfg)
- local value = vstudio.cultureForLocale(cfg.locale)
- if value then
- p.w('Culture="%d"', value)
- end
- end
- function m.customBuildTool(cfg)
- local cfg, filecfg = config.normalize(cfg)
- if filecfg and fileconfig.hasCustomBuildRule(filecfg) then
- local cmds = os.translateCommandsAndPaths(filecfg.buildcommands, filecfg.project.basedir, filecfg.project.location)
- p.x('CommandLine="%s"', table.concat(cmds,'\r\n'))
- local outputs = project.getrelative(filecfg.project, filecfg.buildoutputs)
- p.x('Outputs="%s"', table.concat(outputs, ';'))
- if filecfg.buildinputs and #filecfg.buildinputs > 0 then
- local inputs = project.getrelative(filecfg.project, filecfg.buildinputs)
- p.x('AdditionalDependencies="%s"', table.concat(inputs, ';'))
- end
- end
- end
- function m.debugInformationFormat(cfg, toolset)
- local prjcfg, filecfg = config.normalize(cfg)
- if not filecfg then
- local fmt = iif(toolset, "0", m.symbols(cfg))
- p.w('DebugInformationFormat="%s"', fmt)
- end
- end
-
- function m.detect64BitPortabilityProblems(cfg)
- local prjcfg, filecfg = config.normalize(cfg)
- if _ACTION < "vs2008" and cfg.clr == p.OFF and cfg.warnings ~= p.OFF and not filecfg then
- p.w('Detect64BitPortabilityProblems="%s"', tostring(not cfg.flags.No64BitChecks))
- end
- end
- function m.enableCOMDATFolding(cfg, toolset)
- if config.isOptimizedBuild(cfg) and not toolset then
- p.w('EnableCOMDATFolding="2"')
- end
- end
- function m.largeAddressAware(cfg)
- if (cfg.largeaddressaware == true) then
- p.w('LargeAddressAware="2"')
- end
- end
- function m.enableEnhancedInstructionSet(cfg)
- local map = { SSE = "1", SSE2 = "2" }
- local value = map[cfg.vectorextensions]
- if value and cfg.architecture ~= "x86_64" then
- p.w('EnableEnhancedInstructionSet="%d"', value)
- end
- end
- function m.enableFunctionLevelLinking(cfg)
- local cfg, filecfg = config.normalize(cfg)
- if not filecfg then
- p.w('EnableFunctionLevelLinking="true"')
- end
- end
- function m.entryPointSymbol(cfg, toolset)
- if cfg.entrypoint then
- p.w('EntryPointSymbol="%s"', cfg.entrypoint)
- end
- end
- function m.exceptionHandling(cfg)
- if cfg.exceptionhandling == p.OFF then
- p.w('ExceptionHandling="%s"', iif(_ACTION < "vs2005", "FALSE", 0))
- elseif cfg.exceptionhandling == "SEH" and _ACTION > "vs2003" then
- p.w('ExceptionHandling="2"')
- end
- end
- function m.excludedFromBuild(filecfg)
- if not filecfg or filecfg.flags.ExcludeFromBuild then
- p.w('ExcludedFromBuild="true"')
- end
- end
- function m.floatingPointModel(cfg)
- local map = { Strict = "1", Fast = "2" }
- local value = map[cfg.floatingpoint]
- if value then
- p.w('FloatingPointModel="%d"', value)
- end
- end
- function m.forcedIncludeFiles(cfg)
- if #cfg.forceincludes > 0 then
- local includes = vstudio.path(cfg, cfg.forceincludes)
- p.w('ForcedIncludeFiles="%s"', table.concat(includes, ';'))
- end
- if #cfg.forceusings > 0 then
- local usings = vstudio.path(cfg, cfg.forceusings)
- p.w('ForcedUsingFiles="%s"', table.concat(usings, ';'))
- end
- end
- function m.forcedIncludes(cfg)
- p.w('ForcedIncludes=""')
- end
- function m.forcedUsingAssemblies(cfg)
- p.w('ForcedUsingAssemblies=""')
- end
- function m.keyword(prj)
- local windows, managed, makefile
- for cfg in project.eachconfig(prj) do
- if cfg.system == p.WINDOWS then windows = true end
- if cfg.clr ~= p.OFF then managed = true end
- if vstudio.isMakefile(cfg) then makefile = true end
- end
- if windows then
- local keyword = "Win32Proj"
- if managed then
- keyword = "ManagedCProj"
- end
- if makefile then
- keyword = "MakeFileProj"
- end
- p.w('Keyword="%s"', keyword)
- end
- end
- function m.generateDebugInformation(cfg, toolset)
- if not toolset then
- p.w('GenerateDebugInformation="%s"', tostring(m.symbols(cfg) ~= 0))
- end
- end
- function m.generateManifest(cfg, toolset)
- if cfg.flags.NoManifest or toolset then
- p.w('GenerateManifest="false"')
- end
- end
- function m.ignoreImportLibrary(cfg, toolset)
- if cfg.flags.NoImportLib and not toolset then
- p.w('IgnoreImportLibrary="true"')
- end
- end
- function m.importLibrary(cfg, toolset)
- if cfg.kind == p.SHAREDLIB and not toolset then
- local implibdir = cfg.linktarget.abspath
- -- I can't actually stop the import lib, but I can hide it in the objects directory
- if cfg.flags.NoImportLib then
- implibdir = path.join(cfg.objdir, path.getname(implibdir))
- end
- implibdir = vstudio.path(cfg, implibdir)
- p.x('ImportLibrary="%s"', implibdir)
- end
- end
- function m.includeSearchPath(cfg)
- p.w('IncludeSearchPath=""')
- end
- function m.intermediateDirectory(cfg)
- local objdir
- if not cfg.fake then
- objdir = vstudio.path(cfg, cfg.objdir)
- else
- objdir = "$(PlatformName)\\$(ConfigurationName)"
- end
- p.x('IntermediateDirectory="%s"', objdir)
- end
- function m.linkIncremental(cfg, toolset)
- local value
- if not toolset then
- value = iif(config.canLinkIncremental(cfg) , 2, 1)
- else
- value = 0
- end
- p.w('LinkIncremental="%s"', value)
- end
- function m.linkLibraryDependencies(cfg, toolset)
- if vstudio.needsExplicitLink(cfg) and not toolset then
- p.w('LinkLibraryDependencies="false"')
- end
- end
- function m.managedExtensions(cfg)
- if cfg.clr ~= p.OFF then
- p.w('ManagedExtensions="1"')
- end
- end
- function m.minimalRebuild(cfg)
- if config.isDebugBuild(cfg) and
- cfg.debugformat ~= "c7" and
- not cfg.flags.NoMinimalRebuild and
- cfg.clr == p.OFF and
- not cfg.flags.MultiProcessorCompile
- then
- p.w('MinimalRebuild="true"')
- end
- end
- function m.moduleDefinitionFile(cfg, toolset)
- if not toolset then
- local deffile = config.findfile(cfg, ".def")
- if deffile then
- p.w('ModuleDefinitionFile="%s"', deffile)
- end
- end
- end
- function m.objectFile(cfg)
- local cfg, filecfg = config.normalize(cfg)
- if filecfg and path.iscppfile(filecfg.name) then
- if filecfg.objname ~= path.getbasename(filecfg.abspath) then
- p.x('ObjectFile="$(IntDir)\\%s.obj"', filecfg.objname)
- end
- end
- end
- function m.omitDefaultLib(cfg)
- if cfg.flags.OmitDefaultLibrary then
- p.w('OmitDefaultLibName="true"')
- end
- end
- function m.omitFramePointers(cfg)
- if cfg.omitframepointer == "On" then
- p.w('OmitFramePointers="true"')
- end
- end
- function m.optimization(cfg)
- local map = { Off=0, On=3, Debug=0, Full=3, Size=1, Speed=2 }
- local value = map[cfg.optimize]
- if value or not cfg.abspath then
- p.w('Optimization="%s"', value or 0)
- end
- end
- function m.optimizeReferences(cfg, toolset)
- if config.isOptimizedBuild(cfg) and not toolset then
- p.w('OptimizeReferences="2"')
- end
- end
- function m.output(cfg)
- p.w('Output="$(OutDir)%s"', cfg.buildtarget.name)
- end
- function m.outputDirectory(cfg)
- local outdir = project.getrelative(cfg.project, cfg.buildtarget.directory)
- p.x('OutputDirectory="%s"', path.translate(outdir))
- end
- function m.outputFile(cfg)
- p.x('OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name)
- end
- function m.outputFileName(cfg)
- if cfg.imagepath ~= nil then
- p.x('OutputFileName="%s"', path.translate(cfg.imagepath))
- end
- end
- function m.platforms(prj)
- architectures = {}
- for cfg in project.eachconfig(prj) do
- local arch = vstudio.archFromConfig(cfg, true)
- if not table.contains(architectures, arch) then
- table.insert(architectures, arch)
- end
- end
- p.push('<Platforms>')
- table.foreachi(architectures, function(arch)
- p.push('<Platform')
- p.w('Name="%s"', arch)
- p.pop('/>')
- end)
- p.pop('</Platforms>')
- end
- function m.preprocessorDefinitions(cfg)
- if #cfg.defines > 0 or vstudio.isMakefile(cfg) then
- p.x('PreprocessorDefinitions="%s"', table.concat(cfg.defines, ";"))
- end
- end
- function m.undefinePreprocessorDefinitions(cfg)
- if #cfg.undefines > 0 then
- p.x('UndefinePreprocessorDefinitions="%s"', table.concat(cfg.undefines, ";"))
- end
- end
- function m.programDatabaseFile(cfg, toolset)
- if toolset then
- p.w('ProgramDatabaseFile=""')
- end
- end
- function m.programDataBaseFileName(cfg, toolset)
- if toolset then
- p.w('ProgramDataBaseFileName=""')
- end
- end
- function m.projectGUID(prj)
- p.w('ProjectGUID="{%s}"', prj.uuid)
- end
- function m.projectName(prj)
- p.x('Name="%s"', prj.name)
- end
- function m.projectReferences(prj)
- local deps = project.getdependencies(prj)
- if #deps > 0 then
- -- This is a little odd: Visual Studio wants the "relative path to project"
- -- to be relative to the *workspace*, rather than the project doing the
- -- referencing. Which, in theory, would break if the project is included
- -- in more than one workspace. But that's how they do it.
- for i, dep in ipairs(deps) do
- local relpath = vstudio.path(prj.workspace, vstudio.projectfile(dep))
- -- Visual Studio wants the path to start with ./ or ../
- if not relpath:startswith(".") then
- relpath = ".\\" .. relpath
- end
- p.push('<ProjectReference')
- p.w('ReferencedProjectIdentifier="{%s}"', dep.uuid)
- p.w('RelativePathToProject="%s"', relpath)
- p.pop('/>')
- end
- end
- end
- function m.projectType(prj)
- p.w('ProjectType="Visual C++"')
- end
- function m.reBuildCommandLine(cfg)
- commands = table.concat(cfg.rebuildcommands, "\r\n")
- p.x('ReBuildCommandLine="%s"', commands)
- end
- function m.resourcePreprocessorDefinitions(cfg)
- local defs = table.join(cfg.defines, cfg.resdefines)
- if #defs > 0 then
- p.x('PreprocessorDefinitions="%s"', table.concat(defs, ";"))
- end
- end
- function m.rootNamespace(prj)
- local hasWindows = project.hasConfig(prj, function(cfg)
- return cfg.system == p.WINDOWS
- end)
- -- 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 hasWindows and _ACTION > "vs2003" then
- p.x('RootNamespace="%s"', prj.name)
- end
- end
- function m.runtimeLibrary(cfg)
- local cfg, filecfg = config.normalize(cfg)
- if not filecfg then
- local runtimes = {
- StaticRelease = 0,
- StaticDebug = 1,
- SharedRelease = 2,
- SharedDebug = 3,
- }
- local runtime = config.getruntime(cfg)
- if runtime then
- p.w('RuntimeLibrary="%s"', runtimes[runtime])
- else
- -- TODO: this path should probably be omitted and left for default
- -- ...but I can't really test this, so I'm a leave it how I found it
- p.w('RuntimeLibrary="%s"', iif(config.isDebugBuild(cfg), 3, 2))
- end
- end
- end
- function m.runtimeTypeInfo(cfg)
- if cfg.rtti == p.OFF and cfg.clr == p.OFF then
- p.w('RuntimeTypeInfo="false"')
- elseif cfg.rtti == p.ON then
- p.w('RuntimeTypeInfo="true"')
- end
- end
- function m.stringPooling(cfg)
- if config.isOptimizedBuild(cfg) then
- p.w('StringPooling="true"')
- end
- end
- function m.subSystem(cfg, toolset)
- if not toolset then
- p.w('SubSystem="%s"', iif(cfg.kind == "ConsoleApp", 1, 2))
- end
- end
- function m.targetEnvironment(cfg)
- if cfg.architecture == "x86_64" then
- p.w('TargetEnvironment="3"')
- end
- end
- function m.targetFrameworkVersion(prj)
- local windows, makefile
- for cfg in project.eachconfig(prj) do
- if cfg.system == p.WINDOWS then windows = true end
- if vstudio.isMakefile(cfg) then makefile = true end
- end
- local version = 0
- if makefile or not windows then
- version = 196613
- end
- p.w('TargetFrameworkVersion="%d"', version)
- end
- function m.targetMachine(cfg, toolset)
- if not toolset then
- p.w('TargetMachine="%d"', iif(cfg.architecture == "x86_64", 17, 1))
- end
- end
- function m.toolFiles(prj)
- if _ACTION > "vs2003" then
- p.w('<ToolFiles>')
- p.w('</ToolFiles>')
- end
- end
- function m.treatWChar_tAsBuiltInType(cfg)
- local map = { On = "true", Off = "false" }
- local value = map[cfg.nativewchar]
- if value then
- p.w('TreatWChar_tAsBuiltInType="%s"', value)
- end
- end
- function m.useOfMFC(cfg)
- if (cfg.flags.MFC) then
- p.w('UseOfMFC="%d"', iif(cfg.staticruntime == "On", 1, 2))
- end
- end
- function m.usePrecompiledHeader(cfg)
- local prj, file = config.normalize(cfg)
- if file then
- if prj.pchsource == file.abspath and
- not prj.flags.NoPCH and
- prj.system == p.WINDOWS
- then
- p.w('UsePrecompiledHeader="1"')
- elseif file.flags.NoPCH then
- p.w('UsePrecompiledHeader="0"')
- end
- else
- if not prj.flags.NoPCH and prj.pchheader then
- p.w('UsePrecompiledHeader="%s"', iif(_ACTION < "vs2005", 3, 2))
- p.x('PrecompiledHeaderThrough="%s"', prj.pchheader)
- else
- p.w('UsePrecompiledHeader="%s"', iif(_ACTION > "vs2003" or prj.flags.NoPCH, 0, 2))
- end
- end
- end
- function m.version(prj)
- local map = {
- vs2002 = '7.0',
- vs2003 = '7.1',
- vs2005 = '8.0',
- vs2008 = '9.0'
- }
- p.w('Version="%s0"', map[_ACTION])
- end
- function m.warnAsError(cfg)
- if cfg.flags.FatalCompileWarnings and cfg.warnings ~= p.OFF then
- p.w('WarnAsError="true"')
- end
- end
- function m.warningLevel(cfg)
- local prjcfg, filecfg = config.normalize(cfg)
- local level
- if cfg.warnings == p.OFF then
- level = "0"
- elseif cfg.warnings == "High" then
- level = "4"
- elseif cfg.warnings == "Extra" then
- level = "4"
- elseif not filecfg then
- level = "3"
- end
- if level then
- p.w('WarningLevel="%s"', level)
- end
- end
- function m.wholeProgramOptimization(cfg)
- if cfg.flags.LinkTimeOptimization then
- p.x('WholeProgramOptimization="true"')
- end
- end
- function m.xmlElement()
- p.w('<?xml version="1.0" encoding="Windows-1252"?>')
- end
|