Plaform-specific settings and Xbox 360 support now working in Visual Studio 2005/2008

This commit is contained in:
starkos 2009-04-09 20:02:49 +00:00
parent ec90b60d94
commit 69fc269f4e
19 changed files with 580 additions and 343 deletions

View File

@ -3,6 +3,7 @@
----- -----
- Added support for multiple target platforms - Added support for multiple target platforms
- Added Xbox 360 support to Visual Studio 2005/2008
- Bug 2564404: FatalWarnings has no effect with gmake target - Bug 2564404: FatalWarnings has no effect with gmake target
- Bug 2550759: pchheader option has wrong type - Bug 2550759: pchheader option has wrong type
- Support links and libdirs for Visual Studio static libraries - Support links and libdirs for Visual Studio static libraries

View File

@ -1,6 +1,8 @@
solution "PremakeTestbox" solution "PremakeTestbox"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms { "x32", "x64" } platforms { "x32", "xbox360" }
objdir "obj"
-- solution level configuration -- solution level configuration
@ -14,6 +16,9 @@ solution "PremakeTestbox"
flags { "Optimize" } flags { "Optimize" }
defines { "NDEBUG" } defines { "NDEBUG" }
configuration "x64"
defines { "IS_64BIT" }
-- include all the projects -- include all the projects

View File

@ -8,60 +8,81 @@
-- --
-- Configuration blocks used by each version. -- Map Premake platform identifiers to the Visual Studio versions. Adds the Visual
-- Studio specific "any" and "mixed" to make solution generation easier.
-- --
_VS.vs2002 = { premake.vstudio_platforms = {
"VCCLCompilerTool", any = "Any CPU",
"VCCustomBuildTool", mixed = "Mixed Platforms",
"VCLinkerTool", x32 = "Win32",
"VCMIDLTool", x64 = "x64",
"VCPostBuildEventTool", xbox360 = "Xbox 360",
"VCPreBuildEventTool",
"VCPreLinkEventTool",
"VCResourceCompilerTool",
"VCWebServiceProxyGeneratorTool",
"VCWebDeploymentTool"
} }
_VS.vs2003 = {
"VCCLCompilerTool",
"VCCustomBuildTool",
"VCLinkerTool",
"VCMIDLTool",
"VCPostBuildEventTool",
"VCPreBuildEventTool",
"VCPreLinkEventTool",
"VCResourceCompilerTool",
"VCWebServiceProxyGeneratorTool",
"VCXMLDataGeneratorTool",
"VCWebDeploymentTool",
"VCManagedWrapperGeneratorTool",
"VCAuxiliaryManagedWrapperGeneratorTool"
}
_VS.vs2005 = {
"VCPreBuildEventTool",
"VCCustomBuildTool",
"VCXMLDataGeneratorTool",
"VCWebServiceProxyGeneratorTool",
"VCMIDLTool",
"VCCLCompilerTool",
"VCManagedResourceCompilerTool",
"VCResourceCompilerTool",
"VCPreLinkEventTool",
"VCLinkerTool",
"VCALinkTool",
"VCManifestTool",
"VCXDCMakeTool",
"VCBscMakeTool",
"VCFxCopTool",
"VCAppVerifierTool",
"VCWebDeploymentTool",
"VCPostBuildEventTool"
}
_VS.vs2008 = _VS.vs2005 --
-- Returns the architecture identifier for a project.
--
function _VS.arch(prj)
if (prj.language == "C#") then
if (_ACTION < "vs2005") then
return ".NET"
else
return "Any CPU"
end
else
return "Win32"
end
end
--
-- Return the version-specific text for a boolean value.
-- (this should probably go in vs200x_vcproj.lua)
--
function _VS.bool(value)
if (_ACTION < "vs2005") then
return iif(value, "TRUE", "FALSE")
else
return iif(value, "true", "false")
end
end
--
-- Return a configuration type index.
-- (this should probably go in vs200x_vcproj.lua)
--
function _VS.cfgtype(cfg)
if (cfg.kind == "SharedLib") then
return 2
elseif (cfg.kind == "StaticLib") then
return 4
else
return 1
end
end
--
-- Extend the filterplatforms() function to handle the different sets of
-- supported platforms for various Visual Studio versions. See filterplatforms()
-- for more details.
--
function premake.vstudio_filterplatforms(sln)
local supported = iif(_ACTION < "vs2005", {}, premake.vstudio_platforms)
return premake.filterplatforms(sln, supported, "x32")
end
-- --
@ -94,82 +115,10 @@
end end
--
-- Returns the architecture identifier for a project.
--
function _VS.arch(prj)
if (prj.language == "C#") then
if (_ACTION < "vs2005") then
return ".NET"
else
return "Any CPU"
end
else
return "Win32"
end
end
--
-- Return the action specific text for a boolean value.
--
function _VS.bool(value)
if (_ACTION < "vs2005") then
return iif(value, "TRUE", "FALSE")
else
return iif(value, "true", "false")
end
end
--
-- Return a configuration type index.
--
function _VS.cfgtype(cfg)
if (cfg.kind == "SharedLib") then
return 2
elseif (cfg.kind == "StaticLib") then
return 4
else
return 1
end
end
--
-- Map a list of platforms to their Visual Studio equivalents, taking the
-- Visual Studio version into account. Note that multiple target platforms
-- is only supported for Visual Studio 2005 or later right now.
--
function premake.vstudio_get_platforms(platforms, version)
local result = { }
if version > "vs2003" and platforms then
for _, platform in ipairs(platforms) do
if platform == "x32" then
table.insert(result, "Win32")
elseif platform == "x64" then
table.insert(result, "x64")
end
end
end
-- make sure I've got at least one
if #result == 0 then
result = { "Win32" }
end
return result
end
-- --
-- Write out entries for the files element; called from premake.walksources(). -- Write out entries for the files element; called from premake.walksources().
-- (this should probably go in vs200x_vcproj.lua)
-- --
local function output(indent, value) local function output(indent, value)
@ -216,6 +165,7 @@
-- --
-- Return the optimization code. -- Return the optimization code.
-- (this should probably go in vs200x_vcproj.lua)
-- --
function _VS.optimization(cfg) function _VS.optimization(cfg)
@ -254,6 +204,7 @@
-- --
-- Returns the runtime code for a configuration. -- Returns the runtime code for a configuration.
-- (this should probably go in vs200x_vcproj.lua)
-- --
function _VS.runtime(cfg) function _VS.runtime(cfg)
@ -269,6 +220,7 @@
-- --
-- Return the debugging symbols level for a configuration. -- Return the debugging symbols level for a configuration.
-- (this should probably go in vs200x_vcproj.lua)
-- --
function _VS.symbols(cfg) function _VS.symbols(cfg)

View File

@ -8,24 +8,6 @@
function premake.vs2005_solution(sln) function premake.vs2005_solution(sln)
io.eol = '\r\n' io.eol = '\r\n'
-- Build the list of target platforms
local hascpp = premake.hascppproject(sln)
local hasdotnet = premake.hasdotnetproject(sln)
local platforms = { }
if hasdotnet then
table.insert(platforms, "Any CPU")
end
if hasdotnet and hascpp then
table.insert(platforms, "Mixed Platforms")
end
if hascpp then
platforms.cppdefault = #platforms + 1
for _, p in ipairs(premake.vstudio_get_platforms(sln.platforms, _ACTION)) do
table.insert(platforms, p)
end
end
-- Mark the file as Unicode -- Mark the file as Unicode
io.printf('\239\187\191') io.printf('\239\187\191')
@ -55,6 +37,8 @@
io.printf('EndProject') io.printf('EndProject')
end end
local platforms = premake.vs2005_solution_platforms(sln)
io.printf('Global') io.printf('Global')
premake.vs2005_solution_configurations(sln, platforms) premake.vs2005_solution_configurations(sln, platforms)
premake.vs2005_solution_project_configurations(sln, platforms) premake.vs2005_solution_project_configurations(sln, platforms)
@ -72,7 +56,8 @@
function premake.vs2005_solution_configurations(sln, platforms) function premake.vs2005_solution_configurations(sln, platforms)
io.printf('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution') io.printf('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution')
for _, cfgname in ipairs(sln.configurations) do for _, cfgname in ipairs(sln.configurations) do
for _, platname in ipairs(platforms) do for _, platform in ipairs(platforms) do
local platname = premake.vstudio_platforms[platform]
io.printf('\t\t%s|%s = %s|%s', cfgname, platname, cfgname, platname) io.printf('\t\t%s|%s = %s|%s', cfgname, platname, cfgname, platname)
end end
end end
@ -90,8 +75,19 @@
io.printf('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution') io.printf('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution')
for prj in premake.eachproject(sln) do for prj in premake.eachproject(sln) do
for _, cfgname in ipairs(sln.configurations) do for _, cfgname in ipairs(sln.configurations) do
for i, platname in ipairs(platforms) do for i, platform in ipairs(platforms) do
local mappedname = premake.vs2005_map_platform(prj, platforms, i) local platname = premake.vstudio_platforms[platform]
-- .NET projects always use "Any CPU" platform (for now, at least)
-- C++ projects use the current platform, or the first C++ platform
-- if the current one is for .NET
local mappedname
if premake.isdotnetproject(prj) then
mappedname = "Any CPU"
else
mappedname = premake.vstudio_platforms[platforms[math.max(i, platforms._offset)]]
end
io.printf('\t\t{%s}.%s|%s.ActiveCfg = %s|%s', prj.uuid, cfgname, platname, cfgname, mappedname) io.printf('\t\t{%s}.%s|%s.ActiveCfg = %s|%s', prj.uuid, cfgname, platname, cfgname, mappedname)
if (platname == mappedname or platname == "Mixed Platforms") then if (platname == mappedname or platname == "Mixed Platforms") then
io.printf('\t\t{%s}.%s|%s.Build.0 = %s|%s', prj.uuid, cfgname, platname, cfgname, mappedname) io.printf('\t\t{%s}.%s|%s.Build.0 = %s|%s', prj.uuid, cfgname, platname, cfgname, mappedname)
@ -99,13 +95,14 @@
end end
end end
end end
io.printf('\tEndGlobalSection') io.printf('\tEndGlobalSection')
end end
-- --
-- Write out contents of the SolutionProperties section; current unused. -- Write out contents of the SolutionProperties section; currently unused.
-- --
function premake.vs2005_solution_properties(sln) function premake.vs2005_solution_properties(sln)
@ -117,17 +114,24 @@
-- --
-- Map a solution-level platform to one compatible with the provided project. -- Create a list of platforms used by this solution. A special member _offset
-- C++ platforms are mapped to "Any CPU" for .NET projects, and vice versa. -- points to the first C/C++ platform (skipping over .NET-related platforms).
-- --
function premake.vs2005_map_platform(prj, platforms, i) function premake.vs2005_solution_platforms(sln)
-- .NET projects always use "Any CPU" platform (for now, at least) local platforms = premake.filterplatforms(sln, premake.vstudio_platforms, "x32")
if premake.isdotnetproject(prj) then platforms._offset = 1
return "Any CPU"
local hascpp = premake.hascppproject(sln)
local hasdotnet = premake.hasdotnetproject(sln)
if hasdotnet then
table.insert(platforms, 1, "any")
platforms._offset = 2
end
if hasdotnet and hascpp then
table.insert(platforms, 2, "mixed")
platforms._offset = 3
end end
-- C++ projects use the current platform, or the first C++ platform return platforms
-- if the current one is for .NET
return platforms[math.max(i, platforms.cppdefault)]
end end

View File

@ -5,7 +5,10 @@
-- --
-- Write out a custom build steps block --
-- Write out a custom build steps block.
--
local function buildstepsblock(name, steps) local function buildstepsblock(name, steps)
io.printf('\t\t\t<Tool') io.printf('\t\t\t<Tool')
io.printf('\t\t\t\tName="%s"', name) io.printf('\t\t\t\tName="%s"', name)
@ -16,6 +19,89 @@
end end
--
-- Return a list of sections for a particular Visual Studio version and target platform.
--
local function getsections(version, platform)
if version == "vs2002" then
return {
"VCCLCompilerTool",
"VCCustomBuildTool",
"VCLinkerTool",
"VCMIDLTool",
"VCPostBuildEventTool",
"VCPreBuildEventTool",
"VCPreLinkEventTool",
"VCResourceCompilerTool",
"VCWebServiceProxyGeneratorTool",
"VCWebDeploymentTool"
}
end
if version == "vs2003" then
return {
"VCCLCompilerTool",
"VCCustomBuildTool",
"VCLinkerTool",
"VCMIDLTool",
"VCPostBuildEventTool",
"VCPreBuildEventTool",
"VCPreLinkEventTool",
"VCResourceCompilerTool",
"VCWebServiceProxyGeneratorTool",
"VCXMLDataGeneratorTool",
"VCWebDeploymentTool",
"VCManagedWrapperGeneratorTool",
"VCAuxiliaryManagedWrapperGeneratorTool"
}
end
if platform == "xbox360" then
return {
"VCPreBuildEventTool",
"VCCustomBuildTool",
"VCXMLDataGeneratorTool",
"VCWebServiceProxyGeneratorTool",
"VCMIDLTool",
"VCCLX360CompilerTool",
"VCManagedResourceCompilerTool",
"VCResourceCompilerTool",
"VCPreLinkEventTool",
"VCX360LinkerTool",
"VCALinkTool",
"VCX360ImageTool",
"VCBscMakeTool",
"VCX360DeploymentTool",
"VCPostBuildEventTool",
"DebuggerTool",
}
else
return {
"VCPreBuildEventTool",
"VCCustomBuildTool",
"VCXMLDataGeneratorTool",
"VCWebServiceProxyGeneratorTool",
"VCMIDLTool",
"VCCLCompilerTool",
"VCManagedResourceCompilerTool",
"VCResourceCompilerTool",
"VCPreLinkEventTool",
"VCLinkerTool",
"VCALinkTool",
"VCManifestTool",
"VCXDCMakeTool",
"VCBscMakeTool",
"VCFxCopTool",
"VCAppVerifierTool",
"VCWebDeploymentTool",
"VCPostBuildEventTool"
}
end
end
--
-- The main function: write the project file.
--
function premake.vs200x_vcproj(prj) function premake.vs200x_vcproj(prj)
io.eol = "\r\n" io.eol = "\r\n"
@ -41,12 +127,12 @@
io.printf('\tKeyword="%s"', iif(prj.flags.Managed, "ManagedCProj", "Win32Proj")) io.printf('\tKeyword="%s"', iif(prj.flags.Managed, "ManagedCProj", "Win32Proj"))
io.printf('\t>') io.printf('\t>')
-- list target platforms -- list the target platforms
local platforms = premake.vstudio_get_platforms(prj.solution.platforms, _ACTION) local platforms = premake.vstudio_filterplatforms(prj.solution)
io.printf('\t<Platforms>') io.printf('\t<Platforms>')
for _, platform in ipairs(platforms) do for _, platform in ipairs(platforms) do
io.printf('\t\t<Platform') io.printf('\t\t<Platform')
io.printf('\t\t\tName="%s"', platform) io.printf('\t\t\tName="%s"', premake.vstudio_platforms[platform])
io.printf('\t\t/>') io.printf('\t\t/>')
end end
io.printf('\t</Platforms>') io.printf('\t</Platforms>')
@ -57,12 +143,12 @@
end end
io.printf('\t<Configurations>') io.printf('\t<Configurations>')
for _, platform in ipairs(platforms) do for _, platform in ipairs(platforms) do
for cfg in premake.eachconfig(prj) do for cfg in premake.eachconfig(prj, platform) do
-- Start a configuration -- Start a configuration
io.printf('\t\t<Configuration') io.printf('\t\t<Configuration')
io.printf('\t\t\tName="%s|%s"', premake.esc(cfg.name), platform) io.printf('\t\t\tName="%s|%s"', premake.esc(cfg.name), premake.vstudio_platforms[platform])
io.printf('\t\t\tOutputDirectory="%s"', premake.esc(cfg.buildtarget.directory)) io.printf('\t\t\tOutputDirectory="%s"', premake.esc(cfg.buildtarget.directory))
io.printf('\t\t\tIntermediateDirectory="%s"', premake.esc(cfg.objectsdir)) io.printf('\t\t\tIntermediateDirectory="%s"', premake.esc(cfg.objectsdir))
io.printf('\t\t\tConfigurationType="%s"', _VS.cfgtype(cfg)) io.printf('\t\t\tConfigurationType="%s"', _VS.cfgtype(cfg))
@ -72,12 +158,12 @@
end end
io.printf('\t\t\t>') io.printf('\t\t\t>')
for _, block in ipairs(_VS[_ACTION]) do for _, block in ipairs(getsections(_ACTION, platform)) do
-- Compiler block -- -- Compiler block --
if block == "VCCLCompilerTool" then if block == "VCCLCompilerTool" or block == "VCCLX360CompilerTool" then
io.printf('\t\t\t<Tool') io.printf('\t\t\t<Tool')
io.printf('\t\t\t\tName="VCCLCompilerTool"') io.printf('\t\t\t\tName="%s"', block)
if #cfg.buildoptions > 0 then if #cfg.buildoptions > 0 then
io.printf('\t\t\t\tAdditionalOptions="%s"', table.concat(premake.esc(cfg.buildoptions), " ")) io.printf('\t\t\t\tAdditionalOptions="%s"', table.concat(premake.esc(cfg.buildoptions), " "))
end end
@ -136,10 +222,10 @@
-- End compiler block -- -- End compiler block --
-- Linker block -- -- Linker block --
elseif block == "VCLinkerTool" then elseif block == "VCLinkerTool" or block == "VCX360LinkerTool" then
io.printf('\t\t\t<Tool') io.printf('\t\t\t<Tool')
if cfg.kind ~= "StaticLib" then if cfg.kind ~= "StaticLib" then
io.printf('\t\t\t\tName="VCLinkerTool"') io.printf('\t\t\t\tName="%s"', block)
if cfg.flags.NoImportLib then if cfg.flags.NoImportLib then
io.printf('\t\t\t\tIgnoreImportLibrary="%s"', _VS.bool(true)) io.printf('\t\t\t\tIgnoreImportLibrary="%s"', _VS.bool(true))
end end
@ -212,11 +298,24 @@
buildstepsblock("VCPostBuildEventTool", cfg.postbuildcommands) buildstepsblock("VCPostBuildEventTool", cfg.postbuildcommands)
-- End build event blocks -- -- End build event blocks --
-- Xbox 360 custom sections --
elseif block == "VCX360DeploymentTool" then
io.printf('\t\t\t<Tool')
io.printf('\t\t\t\tName="VCX360DeploymentTool"')
io.printf('\t\t\t\tDeploymentType="0"')
io.printf('\t\t\t/>')
elseif block == "DebuggerTool" then
io.printf('\t\t\t<DebuggerTool')
io.printf('\t\t\t/>')
-- End Xbox 360 custom sections --
else else
io.printf('\t\t\t<Tool') io.printf('\t\t\t<Tool')
io.printf('\t\t\t\tName="%s"', block) io.printf('\t\t\t\tName="%s"', block)
io.printf('\t\t\t/>') io.printf('\t\t\t/>')
end end
end end
io.printf('\t\t</Configuration>') io.printf('\t\t</Configuration>')
end end
@ -236,29 +335,3 @@
end end
--
-- Write out the platforms block, listing all of the platforms targeted in the project.
--
function premake.vs200x_vcproj_platforms(prj)
io.printf('\t<Platforms>')
-- I haven't implement platforms for VS2002/2003 yet
if _ACTION < "vs2005" then
io.printf('\t\t<Platform')
io.printf('\t\t\tName="Win32"')
io.printf('\t\t/>')
else
-- only list C/C++ platforms; skip the generic .NET ones
local platforms = premake.vs2005_solution_platforms(prj.solution)
for i = platforms._firstCppPlatform, #platforms do
io.printf('\t\t<Platform')
io.printf('\t\t\tName="%s"', platforms[i])
io.printf('\t\t/>')
end
end
io.printf('\t</Platforms>')
end

View File

@ -5,7 +5,7 @@
-- data down into simpler objects, keeping only the settings that apply to -- data down into simpler objects, keeping only the settings that apply to
-- the current runtime environment. -- the current runtime environment.
-- --
-- Copyright (c) 2008 Jason Perkins and the Premake project -- Copyright (c) 2008, 2009 Jason Perkins and the Premake project
-- --
@ -28,6 +28,7 @@
-- --
-- Returns a list of all of the active terms from the current environment. -- Returns a list of all of the active terms from the current environment.
-- See the docs for configuration() for more information about the terms.
-- --
function premake.getactiveterms() function premake.getactiveterms()
@ -66,6 +67,9 @@
-- --
-- Test a single configuration block keyword against a list of terms. -- Test a single configuration block keyword against a list of terms.
-- The terms are a mix of key/value pairs. The keyword is tested against
-- the values; on a match, the corresponding key is returned. This
-- enables testing for required values in iskeywordsmatch(), below.
-- --
function premake.iskeywordmatch(keyword, terms) function premake.iskeywordmatch(keyword, terms)
@ -88,6 +92,8 @@
-- --
-- Checks a set of configuration block keywords against a list of terms. -- Checks a set of configuration block keywords against a list of terms.
-- I've already forgotten the purpose of the required terms (d'oh!) but
-- I'll see if I can figure it out on a future refactoring.
-- --
function premake.iskeywordsmatch(keywords, terms) function premake.iskeywordsmatch(keywords, terms)
@ -112,8 +118,9 @@
-- --
-- Copies all of the fields from an object into a configuration object. List -- Copies all of the fields from one settings object into another. List fields are
-- fields are appended, string fields are overwritten. -- appended, string fields are overwritten. In this way, multiple settings blocks
-- are merged together to create a full configuration set.
-- --
local function copyfields(cfg, this) local function copyfields(cfg, this)
@ -167,16 +174,30 @@
-- --
-- Builds a configuration object for a particular project/configuration pair. Flattens -- Builds a configuration object for a particular project/configuration pair. Flattens
-- the object hierarchy, and discards any settings that do not apply to this environment. -- the object hierarchy, and discards any settings that do not apply to this environment.
--
-- @param prj
-- The project being queried.
-- @param cfgname
-- The target build configuration; only settings applicable to this configuration
-- will be returned. May be nil to query project-wide settings.
-- @param pltname
-- The target platform; only settings applicable to this platform will be returned.
-- Maybe be nil to query platform-independent settings.
-- @returns
-- A configuration object, aggregating all of the blocks whose keywords matched the
-- platform and configuration provided, as well as the active environment.
-- --
local function buildprojectconfig(prj, cfgname) local function buildprojectconfig(prj, cfgname, pltname)
-- create the base configuration, flattening the list of objects and -- create the base configuration, flattening the list of objects and
-- filtering out settings which do not match the current environment -- filtering out settings which do not match the current environment
local terms = premake.getactiveterms() local terms = premake.getactiveterms()
terms.platform = (pltname or ""):lower()
terms.config = (cfgname or ""):lower() terms.config = (cfgname or ""):lower()
local cfg = buildconfig(prj, terms) local cfg = buildconfig(prj, terms)
cfg.name = cfgname cfg.name = cfgname
cfg.platform = pltname
cfg.project = prj cfg.project = prj
-- set the project location, if not already set -- set the project location, if not already set
@ -253,31 +274,39 @@
end end
-- build a unique objects directory -- build a unique objects directory
local function getbasedir(cfg) local function buildpath(cfg, variant)
return path.join(cfg.location, cfg.objdir or cfg.project.objdir or "obj") local dir = path.getabsolute(path.join(cfg.location, cfg.objdir or cfg.project.objdir or "obj"))
if variant > 1 then
dir = path.join(dir, cfg.platform)
end
if variant > 2 then
dir = path.join(dir, cfg.name)
end
if variant > 3 then
dir = path.join(dir, cfg.project.name)
end
return dir
end end
local function getuniquedir(cfg) local function getuniquedir(thiscfg)
local thisbase = getbasedir(cfg) local variant = 1
local thislocal = path.join(thisbase, cfg.name) local thispath = buildpath(thiscfg, variant)
local isbasematched = false
for _, sln in ipairs(_SOLUTIONS) do for _, sln in ipairs(_SOLUTIONS) do
for _, prj in ipairs(sln.projects) do for _, prj in ipairs(sln.projects) do
for _, thatcfg in pairs(prj.__configs) do for _, thatcfg in pairs(prj.__configs) do
if thatcfg ~= cfg then if thiscfg ~= thatcfg then
local thatbase = getbasedir(thatcfg) local thatpath = buildpath(thatcfg, variant)
if thisbase == thatbase then while thispath == thatpath and variant < 4 do
isbasematched = true variant = variant + 1
if thislocal == path.join(thatbase, thatcfg.name) then thispath = buildpath(thiscfg, variant)
return path.join(thislocal, cfg.project.name) thatpath = buildpath(thatcfg, variant)
end
end end
end end
end end
end end
end end
return iif(isbasematched, thislocal, thisbase) return thispath
end end
cfg.objectsdir = path.getrelative(cfg.location, getuniquedir(cfg)) cfg.objectsdir = path.getrelative(cfg.location, getuniquedir(cfg))
@ -311,9 +340,21 @@
for _, sln in ipairs(_SOLUTIONS) do for _, sln in ipairs(_SOLUTIONS) do
for _, prj in ipairs(sln.projects) do for _, prj in ipairs(sln.projects) do
prj.__configs = { } prj.__configs = { }
-- create a "root" config for project-wide settings
prj.__configs[""] = buildprojectconfig(prj) prj.__configs[""] = buildprojectconfig(prj)
for _, name in ipairs(sln.configurations) do
prj.__configs[name] = buildprojectconfig(prj, name) -- then one per build configuration
for _, cfgname in ipairs(sln.configurations) do
prj.__configs[cfgname] = buildprojectconfig(prj, cfgname)
-- then one per build configuration/platform pair
if sln.platforms then
for _, pltname in ipairs(sln.platforms) do
prj.__configs[cfgname..":"..pltname] = buildprojectconfig(prj, cfgname, pltname)
end
end
end end
end end
end end

View File

@ -1,24 +1,27 @@
-- --
-- project.lua -- project.lua
-- Functions for working with the project data. -- Functions for working with the project data.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project -- Copyright (c) 2002-2009 Jason Perkins and the Premake project
-- --
-- --
-- Iterator for a project's configuration objects. -- Returns an iterator for a set of build configuration settings. If a platform is
-- specified, settings specific to that platform and build configuration pair are
-- returned.
-- --
function premake.eachconfig(prj) function premake.eachconfig(prj, platform)
-- I probably have the project root config, rather than the actual project -- I probably have the project root config, rather than the actual project
if prj.project then prj = prj.project end if prj.project then prj = prj.project end
local cfgs = prj.solution.configurations
local i = 0 local i = 0
local t = prj.solution.configurations
return function () return function ()
i = i + 1 i = i + 1
if (i <= #t) then if i <= #cfgs then
return prj.__configs[t[i]] return premake.getconfig(prj, cfgs[i], platform)
end end
end end
end end
@ -91,6 +94,36 @@
--
-- Given a map of supported platform identifiers, filters the solution's list
-- of platforms to match. A map takes the form of a table like:
--
-- { x32 = "Win32", x64 = "x64" }
--
-- Only platforms that are listed in both the solution and the map will be
-- included in the results. An option default platform may also be specified;
-- if the result set would otherwise be empty this platform will be used.
--
function premake.filterplatforms(sln, map, default)
local result = { }
if sln.platforms then
for _, p in ipairs(sln.platforms) do
if map[p] then
table.insert(result, p)
end
end
end
if #result == 0 and default then
table.insert(result, default)
end
return result
end
-- --
-- Locate a project by name; case insensitive. -- Locate a project by name; case insensitive.
-- --
@ -122,14 +155,34 @@
-- --
-- Retrieve a configuration for a given project/configuration pairing. If -- Retrieve a configuration for a given project/configuration pairing.
-- `cfgname` is nil, the project's root configuration will be returned. -- @param prj
-- The project to query.
-- @param cfgname
-- The target build configuration; only settings applicable to this configuration
-- will be returned. May be nil to retrieve project-wide settings.
-- @param pltname
-- The target platform; only settings applicable to this platform will be returned.
-- May be nil to retrieve platform-independent settings.
-- @returns
-- A configuration object containing all the settings for the given platform/build
-- configuration pair.
-- --
function premake.getconfig(prj, cfgname) function premake.getconfig(prj, cfgname, pltname)
-- might have the root configuration, rather than the actual project -- might have the root configuration, rather than the actual project
if prj.project then prj = prj.project end if prj.project then prj = prj.project end
return prj.__configs[cfgname or ""]
-- if platform is not included in the solution, use general settings instead
if not table.contains(prj.solution.platforms or {}, pltname) then
pltname = nil
end
-- build a cache key
local key = cfgname or ""
if pltname then key = key .. ":" .. pltname end
return prj.__configs[key]
end end

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
-- --
-- tests/premake4.lua -- tests/premake4.lua
-- Automated test suite for Premake 4.x -- Automated test suite for Premake 4.x
-- Copyright (c) 2008 Jason Perkins and the Premake project -- Copyright (c) 2008, 2009 Jason Perkins and the Premake project
-- --
dofile("testfx.lua") dofile("testfx.lua")
@ -13,10 +13,11 @@
dofile("test_template.lua") dofile("test_template.lua")
dofile("test_premake.lua") dofile("test_premake.lua")
dofile("test_project.lua") dofile("test_project.lua")
dofile("test_configs.lua")
dofile("test_platforms.lua")
dofile("test_api.lua") dofile("test_api.lua")
dofile("test_targets.lua") dofile("test_targets.lua")
dofile("test_keywords.lua") dofile("test_keywords.lua")
dofile("test_vstudio.lua")
dofile("test_vs2002_sln.lua") dofile("test_vs2002_sln.lua")
dofile("test_vs2003_sln.lua") dofile("test_vs2003_sln.lua")
dofile("test_vs2005_sln.lua") dofile("test_vs2005_sln.lua")

60
tests/test_configs.lua Normal file
View File

@ -0,0 +1,60 @@
--
-- tests/test_configs.lua
-- Automated test suite for the configuration building functions.
-- Copyright (c) 2009 Jason Perkins and the Premake project
--
T.configs = { }
local prj
function T.configs.setup()
solution "MySolution"
configurations { "Debug", "Release" }
platforms { "x32", "x64" }
prj = project "MyProject"
language "C"
kind "ConsoleApp"
defines "GLOBAL"
configuration "Debug"
defines "DEBUG"
configuration "Release"
defines "RELEASE"
configuration "x32"
defines "X86_32"
configuration "x64"
defines "X86_64"
premake.buildconfigs()
end
--
-- Make sure that values only get applied to the right configurations.
--
function T.configs.RootValues()
local cfg = premake.getconfig(prj).defines
test.istrue(#cfg == 1 and cfg[1] == "GLOBAL") -- maybe table.compare instead?
end
function T.configs.ConfigValues()
local cfg = premake.getconfig(prj, "Debug").defines
test.istrue(#cfg == 2 and cfg[1] == "GLOBAL" and cfg[2] == "DEBUG")
end
function T.configs.PlatformValues()
local cfg = premake.getconfig(prj, "Debug", "x32").defines
test.istrue(#cfg == 3 and cfg[1] == "GLOBAL" and cfg[2] == "DEBUG" and cfg[3] == "X86_32")
end
function T.configs.DefaultPlaformNotInSolution()
local cfg = premake.getconfig(prj, "Debug", "xbox360").defines
test.isequal("GLOBAL:DEBUG", table.concat(cfg, ":"))
end

50
tests/test_platforms.lua Normal file
View File

@ -0,0 +1,50 @@
--
-- tests/test_platforms.lua
-- Automated test suite for platform handling functions.
-- Copyright (c) 2009 Jason Perkins and the Premake project
--
T.platforms = { }
local testmap = { x32="Win32", x64="x64" }
local sln, r
function T.platforms.setup()
sln = solution "MySolution"
configurations { "Debug", "Release" }
end
function T.platforms.filter_OnNoSolutionPlatforms()
premake.buildconfigs()
r = premake.filterplatforms(sln, testmap)
test.isequal("", table.concat(r, ":"))
end
function T.platforms.filter_OnNoSolutionPlatformsAndDefault()
premake.buildconfigs()
r = premake.filterplatforms(sln, testmap, "x32")
test.isequal("x32", table.concat(r, ":"))
end
function T.platforms.filter_OnIntersection()
platforms { "x32", "x64", "xbox360" }
premake.buildconfigs()
r = premake.filterplatforms(sln, testmap, "x32")
test.isequal("x32:x64", table.concat(r, ":"))
end
function T.platforms.filter_OnNoIntersection()
platforms { "ppc", "xbox360" }
premake.buildconfigs()
r = premake.filterplatforms(sln, testmap)
test.isequal("", table.concat(r, ":"))
end
function T.platforms.filter_OnNoIntersectionAndDefault()
platforms { "ppc", "xbox360" }
premake.buildconfigs()
r = premake.filterplatforms(sln, testmap, "x32")
test.isequal("x32", table.concat(r, ":"))
end

View File

@ -14,6 +14,7 @@
end end
-- --
-- premake.walksources() tests -- premake.walksources() tests
-- --

View File

@ -14,6 +14,7 @@
function T.vs2002_sln.setup() function T.vs2002_sln.setup()
sln = solution "MySolution" sln = solution "MySolution"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms {}
prj = project "MyProject" prj = project "MyProject"
language "C++" language "C++"

View File

@ -14,6 +14,7 @@
function T.vs2003_sln.setup() function T.vs2003_sln.setup()
sln = solution "MySolution" sln = solution "MySolution"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms {}
prj = project "MyProject" prj = project "MyProject"
language "C++" language "C++"

View File

@ -14,6 +14,7 @@
function T.vs2005_sln.setup() function T.vs2005_sln.setup()
sln = solution "MySolution" sln = solution "MySolution"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms {}
prj = project "MyProject" prj = project "MyProject"
language "C++" language "C++"
@ -63,15 +64,12 @@ EndGlobal
-- Test a mixed runtime (C++/.NET) solution. -- Test a mixed runtime (C++/.NET) solution.
-- --
function T.vs2005_sln.MixedPlatformsAndRuntime() function T.vs2005_sln.MixedRuntime()
project "MyNetProject" project "MyNetProject"
language "C#" language "C#"
kind "ConsoleApp" kind "ConsoleApp"
uuid "C9135098-6047-8142-B10E-D27E7F73FCB3" uuid "C9135098-6047-8142-B10E-D27E7F73FCB3"
solution()
platforms { "x32", "x64" }
io.capture() io.capture()
premake.buildconfigs() premake.buildconfigs()
premake.vs2005_solution(sln) premake.vs2005_solution(sln)
@ -88,12 +86,97 @@ Global
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Win32.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Win32.Build.0 = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Any CPU.ActiveCfg = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Mixed Platforms.Build.0 = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Win32.ActiveCfg = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Win32.Build.0 = Release|Win32
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Debug|Win32.ActiveCfg = Debug|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Any CPU.Build.0 = Release|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Win32.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
]])
end
--
-- Test combinations of C++ and .NET platforms
--
function T.vs2005_sln.SolutionConfigs_OnMultipleCppPlatforms()
solution()
platforms { "x32", "x64" }
io.capture()
premake.buildconfigs()
premake.vs2005_solution_configurations(sln, premake.vs2005_solution_platforms(sln))
test.capture [[
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
]]
end
function T.vs2005_sln.ProjectConfigs_OnMultipleCppPlatforms()
solution()
platforms { "x32", "x64" }
io.capture()
premake.buildconfigs()
premake.vs2005_solution_project_configurations(sln, premake.vs2005_solution_platforms(sln))
test.capture [[
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Win32.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Win32.Build.0 = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|x64.ActiveCfg = Debug|x64
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|x64.Build.0 = Debug|x64
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Win32.ActiveCfg = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|Win32.Build.0 = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release|x64.ActiveCfg = Release|x64
{AE61726D-187C-E440-BD07-2556188A6565}.Release|x64.Build.0 = Release|x64
EndGlobalSection
]]
end
function T.vs2005_sln.ProjectConfigs_OnMultipleCppPlatformsAndMixedRuntimes()
project "MyNetProject"
language "C#"
kind "ConsoleApp"
uuid "C9135098-6047-8142-B10E-D27E7F73FCB3"
solution()
platforms { "x32", "x64" }
io.capture()
premake.buildconfigs()
premake.vs2005_solution_project_configurations(sln, premake.vs2005_solution_platforms(sln))
test.capture [[
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Any CPU.ActiveCfg = Debug|Win32 {AE61726D-187C-E440-BD07-2556188A6565}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {AE61726D-187C-E440-BD07-2556188A6565}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
@ -122,9 +205,5 @@ Global
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Win32.ActiveCfg = Release|Any CPU {C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|Win32.ActiveCfg = Release|Any CPU
{C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|x64.ActiveCfg = Release|Any CPU {C9135098-6047-8142-B10E-D27E7F73FCB3}.Release|x64.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution ]]
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
]])
end end

View File

@ -14,6 +14,7 @@
function T.vs2008_sln.setup() function T.vs2008_sln.setup()
sln = solution "MySolution" sln = solution "MySolution"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms {}
prj = project "MyProject" prj = project "MyProject"
language "C++" language "C++"

View File

@ -14,6 +14,7 @@
function T.vs200x_vcproj.setup() function T.vs200x_vcproj.setup()
sln = solution "MySolution" sln = solution "MySolution"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
platforms {}
prj = project "MyProject" prj = project "MyProject"
language "C++" language "C++"
@ -231,59 +232,15 @@
-- Test multiple platforms -- Test multiple platforms
-- --
function T.vs200x_vcproj.PlatformsBlock_OnMultiplePlatforms() function T.vs200x_vcproj.Platforms_OnMultiplePlatforms()
platforms { "x32", "x64" } platforms { "x32", "x64" }
prepare()
premake.vs200x_vcproj(prj)
test.capturecontains [[
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
]]
end
function T.vs200x_vcproj.PlatformConfigs_OnMultiplePlatforms()
platforms { "x32", "x64" }
prepare() prepare()
premake.vs200x_vcproj(prj) premake.vs200x_vcproj(prj)
local result = io.endcapture() local result = io.endcapture()
test.istrue(result:find '<Configuration\r\n\t\t\tName="Debug|Win32"\r\n') test.istrue(result:find '<Configuration\r\n\t\t\tName="Debug|Win32"\r\n')
test.istrue(result:find '<Configuration\r\n\t\t\tName="Release|Win32"\r\n') test.istrue(result:find '<Configuration\r\n\t\t\tName="Release|Win32"\r\n')
test.istrue(result:find '<Configuration\r\n\t\t\tName="Debug|x64"\r\n') test.istrue(result:find '<Configuration\r\n\t\t\tName="Debug|x64"\r\n')
test.istrue(result:find '<Configuration\r\n\t\t\tName="Release|x64"\r\n') test.istrue(result:find '<Configuration\r\n\t\t\tName="Release|x64"\r\n')
end end
function T.vs200x_vcproj.PlatformsBlock_Ignored_OnVs2003()
platforms { "x32", "x64" }
_ACTION = "vs2003"
prepare()
premake.vs200x_vcproj(prj)
test.capturecontains [[
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
]]
end
function T.vs200x_vcproj.PlatformConfigs_Ignored_OnMultiplePlatforms()
platforms { "x32", "x64" }
_ACTION = "vs2003"
prepare()
premake.vs200x_vcproj(prj)
local result = io.endcapture()
test.istrue(result:find '<Configuration\r\n\t\t\tName="Debug|Win32"\r\n')
test.istrue(result:find '<Configuration\r\n\t\t\tName="Release|Win32"\r\n')
test.isfalse(result:find '<Configuration\r\n\t\t\tName="Debug|x64"\r\n')
test.isfalse(result:find '<Configuration\r\n\t\t\tName="Release|x64"\r\n')
end

View File

@ -1,34 +0,0 @@
--
-- tests/test_vstudio.lua
-- Automated test suite for Visual Studio 200* general functions.
-- Copyright (c) 2009 Jason Perkins and the Premake project
--
T.vstudio = { }
--
-- Test platform mapping
--
function T.vstudio.Platforms_OnVs2002()
local result = premake.vstudio_get_platforms(premake.fields.platforms.allowed, "vs2002")
test.isequal("Win32", table.concat(result, "|"))
end
function T.vstudio.Platforms_OnVs2003()
local result = premake.vstudio_get_platforms(premake.fields.platforms.allowed, "vs2003")
test.isequal("Win32", table.concat(result, "|"))
end
function T.vstudio.Platforms_OnVs2005()
local result = premake.vstudio_get_platforms(premake.fields.platforms.allowed, "vs2005")
test.isequal("Win32|x64", table.concat(result, "|"))
end
function T.vstudio.Platforms_OnVs2008()
local result = premake.vstudio_get_platforms(premake.fields.platforms.allowed, "vs2008")
test.isequal("Win32|x64", table.concat(result, "|"))
end

View File

@ -39,15 +39,6 @@
end end
function test.capturecontains(expected)
local actual = io.endcapture()
expected = expected:gsub("\n", io.eol)
if (not actual:find(expected)) then
test.fail("result did not contain the expected text")
end
end
function test.fail(format, ...) function test.fail(format, ...)
-- convert nils into something more usefuls -- convert nils into something more usefuls
for i = 1, arg.n do for i = 1, arg.n do