Commits

Jason Perkins committed b34965f

Made build and link targets available for token expansion

  • Participants
  • Parent commits 7041949

Comments (0)

Files changed (9)

src/actions/make/make_cpp.lua

 --
 
 	function cpp.targetconfig(cfg)		
-		local targetinfo = config.gettargetinfo(cfg)
 		_p('  OBJDIR     = %s', make.esc(project.getrelative(cfg.project, cfg.objdir)))
-		_p('  TARGETDIR  = %s', make.esc(targetinfo.directory))
-		_p('  TARGET     = $(TARGETDIR)/%s', make.esc(targetinfo.name))
+		_p('  TARGETDIR  = %s', make.esc(cfg.buildtarget.directory))
+		_p('  TARGET     = $(TARGETDIR)/%s', make.esc(cfg.buildtarget.name))
 	end
 
 

src/actions/vstudio/vs2005_csproj.lua

---
--- vs2005_csproj.lua
--- Generate a Visual Studio 2005/2008 C# project.
--- Copyright (c) 2009-2012 Jason Perkins and the Premake project
---
-
-	premake.vstudio.cs2005 = { }
-	local vstudio = premake.vstudio
-	local cs2005  = premake.vstudio.cs2005
-	local project = premake5.project
-	local config = premake5.config
-	local dotnet = premake.dotnet
-
-
 --
-
+-- vs2005_csproj.lua
+-- Generate a Visual Studio 2005/2008 C# project.
+-- Copyright (c) 2009-2012 Jason Perkins and the Premake project
+--
+
+	premake.vstudio.cs2005 = { }
+	local vstudio = premake.vstudio
+	local cs2005  = premake.vstudio.cs2005
+	local project = premake5.project
+	local config = premake5.config
+	local dotnet = premake.dotnet
+
+
+--
+
 -- Generate a Visual Studio 200x C# project, with support for the new platforms API.
-
+
 --
-
-
-	function cs2005.generate_ng(prj)
-		io.eol = "\r\n"
-		io.indent = "  "
-		
-		cs2005.projectelement(prj)
-		cs2005.projectsettings(prj)
-
-		for cfg in project.eachconfig(prj) do
-			cs2005.propertygroup(cfg)
-			cs2005.flags(cfg)		
-		end
-
-		cs2005.projectReferences(prj)
-
-
-	--[[
-		_p('  <ItemGroup>')
-		cs2005.files(prj)
-		_p('  </ItemGroup>')
-
-		_p('  <Import Project="$(MSBuildBinPath)\\Microsoft.CSharp.targets" />')
-		_p('  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')
-		_p('       Other similar extension points exist, see Microsoft.Common.targets.')
-		_p('  <Target Name="BeforeBuild">')
-		_p('  </Target>')
-		_p('  <Target Name="AfterBuild">')
-		_p('  </Target>')
-		_p('  -->')
-	--]]
-
-		_p('</Project>')
-
-		print("** Warning: C# projects have not been ported yet")
-	end
-
-
---
--- Write the opening <Project> element.
---
-
-	function cs2005.projectelement(prj)
-		local toolversion = {
-			vs2005 = '',
-			vs2008 = ' ToolsVersion="3.5"',
-			vs2010 = ' ToolsVersion="4.0"',
-			vs2012 = ' ToolsVersion="4.0"',
-		}
-
-		if _ACTION > "vs2008" then
-			_p('<?xml version="1.0" encoding="utf-8"?>')
-		end
-		_p('<Project%s DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">', toolversion[_ACTION])
-	end
-
-
---
--- Write the opening PropertyGroup, which contains the project-level settings.
---
-
-	function cs2005.projectsettings(prj)
-		local version = {
-			vs2005 = '8.0.50727',
-			vs2008 = '9.0.21022',
-			vs2010 = '8.0.30703',
-			vs2012 = '8.0.30703',
-		}
-		
-		local frameworks = {
-			vs2010 = "4.0",
-			vs2012 = "4.5",
-		}
-
-		_p(1,'<PropertyGroup>')
-		
-		-- find the first configuration in the project, use as the default
-		local cfg = project.getfirstconfig(prj)
-		
-		_p(2,'<Configuration Condition=" \'$(Configuration)\' == \'\' ">%s</Configuration>', premake.esc(cfg.buildcfg))
-		_p(2,'<Platform Condition=" \'$(Platform)\' == \'\' ">%s</Platform>', cs2005.arch(prj))
-		
-		_p(2,'<ProductVersion>%s</ProductVersion>', version[_ACTION])
-		_p(2,'<SchemaVersion>2.0</SchemaVersion>')
-		_p(2,'<ProjectGuid>{%s}</ProjectGuid>', prj.uuid)
-		
-		_p(2,'<OutputType>%s</OutputType>', dotnet.getkind(cfg))
-		_p(2,'<AppDesignerFolder>Properties</AppDesignerFolder>')
-
-		local target = config.gettargetinfo(cfg)
-		_p(2,'<RootNamespace>%s</RootNamespace>', target.basename)
-		_p(2,'<AssemblyName>%s</AssemblyName>', target.basename)
-
-		local framework = prj.framework or frameworks[_ACTION]
-		if framework then
-			_p(2,'<TargetFrameworkVersion>v%s</TargetFrameworkVersion>', framework)
-		end
-
-		if _ACTION >= "vs2010" then
-			_p(2,'<TargetFrameworkProfile>Client</TargetFrameworkProfile>')
-			_p(2,'<FileAlignment>512</FileAlignment>')
-		end
-		
-		_p(1,'</PropertyGroup>')
-	end
-
-
---
--- Write the flags for a particular configuration.
---
-
-	function cs2005.flags(cfg)
-		if cfg.flags.Symbols then
-			_p(2,'<DebugSymbols>true</DebugSymbols>')
-			_p(2,'<DebugType>full</DebugType>')
-		else
-			_p(2,'<DebugType>pdbonly</DebugType>')
-		end
-
-		_p(2,'<Optimize>%s</Optimize>', iif(premake.config.isoptimizedbuild(cfg), "true", "false"))
-
-		local target = config.gettargetinfo(cfg)
-		_p(2,'<OutputPath>%s</OutputPath>', target.directory)
-
-		_p(2,'<DefineConstants>%s</DefineConstants>', table.concat(premake.esc(cfg.defines), ";"))
-
-		_p(2,'<ErrorReport>prompt</ErrorReport>')
-		_p(2,'<WarningLevel>4</WarningLevel>')
-
-		if cfg.flags.Unsafe then
-			_p(2,'<AllowUnsafeBlocks>true</AllowUnsafeBlocks>')
-		end
-		
-		if cfg.flags.FatalWarnings then
-			_p(2,'<TreatWarningsAsErrors>true</TreatWarningsAsErrors>')
-		end
-
-		_p(1,'</PropertyGroup>')			
-	end
-
-
---
--- Write the list of project dependencies.
---
-	function cs2005.projectReferences(prj)
-		_p(1,'<ItemGroup>')
-
-	--[[
-		for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do
-			_p('    <ProjectReference Include="%s">', path.translate(path.getrelative(prj.location, vstudio.projectfile(ref)), "\\"))
-			_p('      <Project>{%s}</Project>', ref.uuid)
-			_p('      <Name>%s</Name>', premake.esc(ref.name))
-			_p('    </ProjectReference>')
-		end
-		for _, linkname in ipairs(premake.getlinks(prj, "system", "basename")) do
-			_p('    <Reference Include="%s" />', premake.esc(linkname))
-		end
-	--]]
-	
-		_p(1,'</ItemGroup>')
-	end
-
-
---
--- Return the Visual Studio architecture identification string. The logic
--- to select this is getting more complicated in VS2010, but I haven't 
--- tackled all the permutations yet.
---
-
-	function cs2005.arch(prj)
-		return "AnyCPU"
-	end
-
-
---
--- Write the PropertyGroup element for a specific configuration block.
---
-
-	function cs2005.propertygroup(cfg)
-		_p(1,'<PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' ">', premake.esc(cfg.buildcfg), cs2005.arch(cfg))
-		if _ACTION > "vs2008" then
-			_p(2,'<PlatformTarget>%s</PlatformTarget>', cs2005.arch(cfg))
-		end
-	end
-
-
-
------------------------------------------------------------------------------
--- Everything below this point is a candidate for deprecation
------------------------------------------------------------------------------
-
---
--- Figure out what elements a particular source code file need in its item
--- block, based on its build action and any related files in the project.
--- 
-	
-	local function getelements(prj, action, fname)
-	
-		if action == "Compile" and fname:endswith(".cs") then
-			if fname:endswith(".Designer.cs") then
-				-- is there a matching *.cs file?
-				local basename = fname:sub(1, -13)
-				local testname = basename .. ".cs"
-				if premake.findfile(prj, testname) then
-					return "Dependency", testname
-				end
-				-- is there a matching *.resx file?
-				testname = basename .. ".resx"
-				if premake.findfile(prj, testname) then
-					return "AutoGen", testname
-				end
-			else
-				-- is there a *.Designer.cs file?
-				local basename = fname:sub(1, -4)
-				local testname = basename .. ".Designer.cs"
-				if premake.findfile(prj, testname) then
-					return "SubTypeForm"
-				end
-			end
-		end
-
-		if action == "EmbeddedResource" and fname:endswith(".resx") then
-			-- is there a matching *.cs file?
-			local basename = fname:sub(1, -6)
-			local testname = path.getname(basename .. ".cs")
-			if premake.findfile(prj, testname) then
-				if premake.findfile(prj, basename .. ".Designer.cs") then
-					return "DesignerType", testname
-				else
-					return "Dependency", testname
-				end
-			else
-				-- is there a matching *.Designer.cs?
-				testname = path.getname(basename .. ".Designer.cs")
-				if premake.findfile(prj, testname) then
-					return "AutoGenerated"
-				end
-			end
-		end
-				
-		if action == "Content" then
-			return "CopyNewest"
-		end
-		
-		return "None"
-	end
-
-
---
--- Write out the <Files> element.
---
-
-	function cs2005.files(prj)
-		local tr = premake.project.buildsourcetree(prj)
-		premake.tree.traverse(tr, {
-			onleaf = function(node)
-				local action = premake.dotnet.getbuildaction(node.cfg)
-				local fname  = path.translate(premake.esc(node.cfg.name), "\\")
-				local elements, dependency = getelements(prj, action, node.path)
-
-				if elements == "None" then
-					_p('    <%s Include="%s" />', action, fname)
-				else
-					_p('    <%s Include="%s">', action, fname)
-					if elements == "AutoGen" then
-						_p('      <AutoGen>True</AutoGen>')
-					elseif elements == "AutoGenerated" then
-						_p('      <SubType>Designer</SubType>')
-						_p('      <Generator>ResXFileCodeGenerator</Generator>')
-						_p('      <LastGenOutput>%s.Designer.cs</LastGenOutput>', premake.esc(path.getbasename(node.name)))
-					elseif elements == "SubTypeDesigner" then
-						_p('      <SubType>Designer</SubType>')
-					elseif elements == "SubTypeForm" then
-						_p('      <SubType>Form</SubType>')
-					elseif elements == "PreserveNewest" then
-						_p('      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>')
-					end
-					if dependency then
-						_p('      <DependentUpon>%s</DependentUpon>', path.translate(premake.esc(dependency), "\\"))
-					end
-					_p('    </%s>', action)
-				end
-			end
-		}, false)
-	end
-
-
---
--- Write the opening PropertyGroup, which contains the project-level settings.
---
-
-	function cs2005.projectsettings_old(prj)
-		local version = {
-			vs2005 = '8.0.50727',
-			vs2008 = '9.0.21022',
-			vs2010 = '8.0.30703',
-			vs2012 = '8.0.30703',
-		}
-		
-		local frameworks = {
-			vs2010 = "4.0",
-			vs2012 = "4.5",
-		}
-
-		_p('  <PropertyGroup>')
-		_p('    <Configuration Condition=" \'$(Configuration)\' == \'\' ">%s</Configuration>', premake.esc(prj.solution.configurations[1]))
-		_p('    <Platform Condition=" \'$(Platform)\' == \'\' ">%s</Platform>', cs2005.arch(prj))
-		_p('    <ProductVersion>%s</ProductVersion>', version[_ACTION])
-		_p('    <SchemaVersion>2.0</SchemaVersion>')
-		_p('    <ProjectGuid>{%s}</ProjectGuid>', prj.uuid)
-		_p('    <OutputType>%s</OutputType>', premake.dotnet.getkind(prj))
-		_p('    <AppDesignerFolder>Properties</AppDesignerFolder>')
-		_p('    <RootNamespace>%s</RootNamespace>', prj.buildtarget.basename)
-		_p('    <AssemblyName>%s</AssemblyName>', prj.buildtarget.basename)
-
-		local framework = prj.framework or frameworks[_ACTION]
-		if framework then
-			_p('    <TargetFrameworkVersion>v%s</TargetFrameworkVersion>', framework)
-		end
-
-		if _ACTION >= "vs2010" then
-			_p('    <TargetFrameworkProfile>Client</TargetFrameworkProfile>')
-			_p('    <FileAlignment>512</FileAlignment>')
-		end
-		
-		_p('  </PropertyGroup>')
-	end
-
-
---
--- The main function: write the project file.
---
-
-	function cs2005.generate(prj)
-		io.eol = "\r\n"
-		io.indent = "  "
-
-		cs2005.projectelement(prj)
-		cs2005.projectsettings_old(prj)
-
-		for cfg in premake.eachconfig(prj) do
-			cs2005.propertygroup(cfg)
-
-			if cfg.flags.Symbols then
-				_p('    <DebugSymbols>true</DebugSymbols>')
-				_p('    <DebugType>full</DebugType>')
-			else
-				_p('    <DebugType>pdbonly</DebugType>')
-			end
-			_p('    <Optimize>%s</Optimize>', iif(cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed, "true", "false"))
-			_p('    <OutputPath>%s</OutputPath>', cfg.buildtarget.directory)
-			_p('    <DefineConstants>%s</DefineConstants>', table.concat(premake.esc(cfg.defines), ";"))
-			_p('    <ErrorReport>prompt</ErrorReport>')
-			_p('    <WarningLevel>4</WarningLevel>')
-			if cfg.flags.Unsafe then
-				_p('    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>')
-			end
-			if cfg.flags.FatalWarnings then
-				_p('    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>')
-			end
-			_p('  </PropertyGroup>')
-		end
-
-		_p('  <ItemGroup>')
-		for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do
-			_p('    <ProjectReference Include="%s">', path.translate(path.getrelative(prj.location, vstudio.projectfile(ref)), "\\"))
-			_p('      <Project>{%s}</Project>', ref.uuid)
-			_p('      <Name>%s</Name>', premake.esc(ref.name))
-			_p('    </ProjectReference>')
-		end
-		for _, linkname in ipairs(premake.getlinks(prj, "system", "basename")) do
-			_p('    <Reference Include="%s" />', premake.esc(linkname))
-		end
-		_p('  </ItemGroup>')
-
-		_p('  <ItemGroup>')
-		cs2005.files(prj)
-		_p('  </ItemGroup>')
-
-		_p('  <Import Project="$(MSBuildBinPath)\\Microsoft.CSharp.targets" />')
-		_p('  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')
-		_p('       Other similar extension points exist, see Microsoft.Common.targets.')
-		_p('  <Target Name="BeforeBuild">')
-		_p('  </Target>')
-		_p('  <Target Name="AfterBuild">')
-		_p('  </Target>')
-		_p('  -->')
-		_p('</Project>')
-		
-	end
-
+
+
+	function cs2005.generate_ng(prj)
+		io.eol = "\r\n"
+		io.indent = "  "
+		
+		cs2005.projectelement(prj)
+		cs2005.projectsettings(prj)
+
+		for cfg in project.eachconfig(prj) do
+			cs2005.propertygroup(cfg)
+			cs2005.flags(cfg)		
+		end
+
+		cs2005.projectReferences(prj)
+
+
+	--[[
+		_p('  <ItemGroup>')
+		cs2005.files(prj)
+		_p('  </ItemGroup>')
+
+		_p('  <Import Project="$(MSBuildBinPath)\\Microsoft.CSharp.targets" />')
+		_p('  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')
+		_p('       Other similar extension points exist, see Microsoft.Common.targets.')
+		_p('  <Target Name="BeforeBuild">')
+		_p('  </Target>')
+		_p('  <Target Name="AfterBuild">')
+		_p('  </Target>')
+		_p('  -->')
+	--]]
+
+		_p('</Project>')
+
+		print("** Warning: C# projects have not been ported yet")
+	end
+
+
+--
+-- Write the opening <Project> element.
+--
+
+	function cs2005.projectelement(prj)
+		local toolversion = {
+			vs2005 = '',
+			vs2008 = ' ToolsVersion="3.5"',
+			vs2010 = ' ToolsVersion="4.0"',
+			vs2012 = ' ToolsVersion="4.0"',
+		}
+
+		if _ACTION > "vs2008" then
+			_p('<?xml version="1.0" encoding="utf-8"?>')
+		end
+		_p('<Project%s DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">', toolversion[_ACTION])
+	end
+
+
+--
+-- Write the opening PropertyGroup, which contains the project-level settings.
+--
+
+	function cs2005.projectsettings(prj)
+		local version = {
+			vs2005 = '8.0.50727',
+			vs2008 = '9.0.21022',
+			vs2010 = '8.0.30703',
+			vs2012 = '8.0.30703',
+		}
+		
+		local frameworks = {
+			vs2010 = "4.0",
+			vs2012 = "4.5",
+		}
+
+		_p(1,'<PropertyGroup>')
+		
+		-- find the first configuration in the project, use as the default
+		local cfg = project.getfirstconfig(prj)
+		
+		_p(2,'<Configuration Condition=" \'$(Configuration)\' == \'\' ">%s</Configuration>', premake.esc(cfg.buildcfg))
+		_p(2,'<Platform Condition=" \'$(Platform)\' == \'\' ">%s</Platform>', cs2005.arch(prj))
+		
+		_p(2,'<ProductVersion>%s</ProductVersion>', version[_ACTION])
+		_p(2,'<SchemaVersion>2.0</SchemaVersion>')
+		_p(2,'<ProjectGuid>{%s}</ProjectGuid>', prj.uuid)
+		
+		_p(2,'<OutputType>%s</OutputType>', dotnet.getkind(cfg))
+		_p(2,'<AppDesignerFolder>Properties</AppDesignerFolder>')
+
+		local target = cfg.buildtarget
+		_p(2,'<RootNamespace>%s</RootNamespace>', target.basename)
+		_p(2,'<AssemblyName>%s</AssemblyName>', target.basename)
+
+		local framework = prj.framework or frameworks[_ACTION]
+		if framework then
+			_p(2,'<TargetFrameworkVersion>v%s</TargetFrameworkVersion>', framework)
+		end
+
+		if _ACTION >= "vs2010" then
+			_p(2,'<TargetFrameworkProfile>Client</TargetFrameworkProfile>')
+			_p(2,'<FileAlignment>512</FileAlignment>')
+		end
+		
+		_p(1,'</PropertyGroup>')
+	end
+
+
+--
+-- Write the flags for a particular configuration.
+--
+
+	function cs2005.flags(cfg)
+		if cfg.flags.Symbols then
+			_p(2,'<DebugSymbols>true</DebugSymbols>')
+			_p(2,'<DebugType>full</DebugType>')
+		else
+			_p(2,'<DebugType>pdbonly</DebugType>')
+		end
+
+		_p(2,'<Optimize>%s</Optimize>', iif(premake.config.isoptimizedbuild(cfg), "true", "false"))
+
+		_p(2,'<OutputPath>%s</OutputPath>', cfg.buildtarget.directory)
+
+		_p(2,'<DefineConstants>%s</DefineConstants>', table.concat(premake.esc(cfg.defines), ";"))
+
+		_p(2,'<ErrorReport>prompt</ErrorReport>')
+		_p(2,'<WarningLevel>4</WarningLevel>')
+
+		if cfg.flags.Unsafe then
+			_p(2,'<AllowUnsafeBlocks>true</AllowUnsafeBlocks>')
+		end
+		
+		if cfg.flags.FatalWarnings then
+			_p(2,'<TreatWarningsAsErrors>true</TreatWarningsAsErrors>')
+		end
+
+		_p(1,'</PropertyGroup>')			
+	end
+
+
+--
+-- Write the list of project dependencies.
+--
+	function cs2005.projectReferences(prj)
+		_p(1,'<ItemGroup>')
+
+	--[[
+		for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do
+			_p('    <ProjectReference Include="%s">', path.translate(path.getrelative(prj.location, vstudio.projectfile(ref)), "\\"))
+			_p('      <Project>{%s}</Project>', ref.uuid)
+			_p('      <Name>%s</Name>', premake.esc(ref.name))
+			_p('    </ProjectReference>')
+		end
+		for _, linkname in ipairs(premake.getlinks(prj, "system", "basename")) do
+			_p('    <Reference Include="%s" />', premake.esc(linkname))
+		end
+	--]]
+	
+		_p(1,'</ItemGroup>')
+	end
+
+
+--
+-- Return the Visual Studio architecture identification string. The logic
+-- to select this is getting more complicated in VS2010, but I haven't 
+-- tackled all the permutations yet.
+--
+
+	function cs2005.arch(prj)
+		return "AnyCPU"
+	end
+
+
+--
+-- Write the PropertyGroup element for a specific configuration block.
+--
+
+	function cs2005.propertygroup(cfg)
+		_p(1,'<PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' ">', premake.esc(cfg.buildcfg), cs2005.arch(cfg))
+		if _ACTION > "vs2008" then
+			_p(2,'<PlatformTarget>%s</PlatformTarget>', cs2005.arch(cfg))
+		end
+	end
+
+
+
+-----------------------------------------------------------------------------
+-- Everything below this point is a candidate for deprecation
+-----------------------------------------------------------------------------
+
+--
+-- Figure out what elements a particular source code file need in its item
+-- block, based on its build action and any related files in the project.
+-- 
+	
+	local function getelements(prj, action, fname)
+	
+		if action == "Compile" and fname:endswith(".cs") then
+			if fname:endswith(".Designer.cs") then
+				-- is there a matching *.cs file?
+				local basename = fname:sub(1, -13)
+				local testname = basename .. ".cs"
+				if premake.findfile(prj, testname) then
+					return "Dependency", testname
+				end
+				-- is there a matching *.resx file?
+				testname = basename .. ".resx"
+				if premake.findfile(prj, testname) then
+					return "AutoGen", testname
+				end
+			else
+				-- is there a *.Designer.cs file?
+				local basename = fname:sub(1, -4)
+				local testname = basename .. ".Designer.cs"
+				if premake.findfile(prj, testname) then
+					return "SubTypeForm"
+				end
+			end
+		end
+
+		if action == "EmbeddedResource" and fname:endswith(".resx") then
+			-- is there a matching *.cs file?
+			local basename = fname:sub(1, -6)
+			local testname = path.getname(basename .. ".cs")
+			if premake.findfile(prj, testname) then
+				if premake.findfile(prj, basename .. ".Designer.cs") then
+					return "DesignerType", testname
+				else
+					return "Dependency", testname
+				end
+			else
+				-- is there a matching *.Designer.cs?
+				testname = path.getname(basename .. ".Designer.cs")
+				if premake.findfile(prj, testname) then
+					return "AutoGenerated"
+				end
+			end
+		end
+				
+		if action == "Content" then
+			return "CopyNewest"
+		end
+		
+		return "None"
+	end
+
+
+--
+-- Write out the <Files> element.
+--
+
+	function cs2005.files(prj)
+		local tr = premake.project.buildsourcetree(prj)
+		premake.tree.traverse(tr, {
+			onleaf = function(node)
+				local action = premake.dotnet.getbuildaction(node.cfg)
+				local fname  = path.translate(premake.esc(node.cfg.name), "\\")
+				local elements, dependency = getelements(prj, action, node.path)
+
+				if elements == "None" then
+					_p('    <%s Include="%s" />', action, fname)
+				else
+					_p('    <%s Include="%s">', action, fname)
+					if elements == "AutoGen" then
+						_p('      <AutoGen>True</AutoGen>')
+					elseif elements == "AutoGenerated" then
+						_p('      <SubType>Designer</SubType>')
+						_p('      <Generator>ResXFileCodeGenerator</Generator>')
+						_p('      <LastGenOutput>%s.Designer.cs</LastGenOutput>', premake.esc(path.getbasename(node.name)))
+					elseif elements == "SubTypeDesigner" then
+						_p('      <SubType>Designer</SubType>')
+					elseif elements == "SubTypeForm" then
+						_p('      <SubType>Form</SubType>')
+					elseif elements == "PreserveNewest" then
+						_p('      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>')
+					end
+					if dependency then
+						_p('      <DependentUpon>%s</DependentUpon>', path.translate(premake.esc(dependency), "\\"))
+					end
+					_p('    </%s>', action)
+				end
+			end
+		}, false)
+	end
+
+
+--
+-- Write the opening PropertyGroup, which contains the project-level settings.
+--
+
+	function cs2005.projectsettings_old(prj)
+		local version = {
+			vs2005 = '8.0.50727',
+			vs2008 = '9.0.21022',
+			vs2010 = '8.0.30703',
+			vs2012 = '8.0.30703',
+		}
+		
+		local frameworks = {
+			vs2010 = "4.0",
+			vs2012 = "4.5",
+		}
+
+		_p('  <PropertyGroup>')
+		_p('    <Configuration Condition=" \'$(Configuration)\' == \'\' ">%s</Configuration>', premake.esc(prj.solution.configurations[1]))
+		_p('    <Platform Condition=" \'$(Platform)\' == \'\' ">%s</Platform>', cs2005.arch(prj))
+		_p('    <ProductVersion>%s</ProductVersion>', version[_ACTION])
+		_p('    <SchemaVersion>2.0</SchemaVersion>')
+		_p('    <ProjectGuid>{%s}</ProjectGuid>', prj.uuid)
+		_p('    <OutputType>%s</OutputType>', premake.dotnet.getkind(prj))
+		_p('    <AppDesignerFolder>Properties</AppDesignerFolder>')
+		_p('    <RootNamespace>%s</RootNamespace>', prj.buildtarget.basename)
+		_p('    <AssemblyName>%s</AssemblyName>', prj.buildtarget.basename)
+
+		local framework = prj.framework or frameworks[_ACTION]
+		if framework then
+			_p('    <TargetFrameworkVersion>v%s</TargetFrameworkVersion>', framework)
+		end
+
+		if _ACTION >= "vs2010" then
+			_p('    <TargetFrameworkProfile>Client</TargetFrameworkProfile>')
+			_p('    <FileAlignment>512</FileAlignment>')
+		end
+		
+		_p('  </PropertyGroup>')
+	end
+
+
+--
+-- The main function: write the project file.
+--
+
+	function cs2005.generate(prj)
+		io.eol = "\r\n"
+		io.indent = "  "
+
+		cs2005.projectelement(prj)
+		cs2005.projectsettings_old(prj)
+
+		for cfg in premake.eachconfig(prj) do
+			cs2005.propertygroup(cfg)
+
+			if cfg.flags.Symbols then
+				_p('    <DebugSymbols>true</DebugSymbols>')
+				_p('    <DebugType>full</DebugType>')
+			else
+				_p('    <DebugType>pdbonly</DebugType>')
+			end
+			_p('    <Optimize>%s</Optimize>', iif(cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed, "true", "false"))
+			_p('    <OutputPath>%s</OutputPath>', cfg.buildtarget.directory)
+			_p('    <DefineConstants>%s</DefineConstants>', table.concat(premake.esc(cfg.defines), ";"))
+			_p('    <ErrorReport>prompt</ErrorReport>')
+			_p('    <WarningLevel>4</WarningLevel>')
+			if cfg.flags.Unsafe then
+				_p('    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>')
+			end
+			if cfg.flags.FatalWarnings then
+				_p('    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>')
+			end
+			_p('  </PropertyGroup>')
+		end
+
+		_p('  <ItemGroup>')
+		for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do
+			_p('    <ProjectReference Include="%s">', path.translate(path.getrelative(prj.location, vstudio.projectfile(ref)), "\\"))
+			_p('      <Project>{%s}</Project>', ref.uuid)
+			_p('      <Name>%s</Name>', premake.esc(ref.name))
+			_p('    </ProjectReference>')
+		end
+		for _, linkname in ipairs(premake.getlinks(prj, "system", "basename")) do
+			_p('    <Reference Include="%s" />', premake.esc(linkname))
+		end
+		_p('  </ItemGroup>')
+
+		_p('  <ItemGroup>')
+		cs2005.files(prj)
+		_p('  </ItemGroup>')
+
+		_p('  <Import Project="$(MSBuildBinPath)\\Microsoft.CSharp.targets" />')
+		_p('  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')
+		_p('       Other similar extension points exist, see Microsoft.Common.targets.')
+		_p('  <Target Name="BeforeBuild">')
+		_p('  </Target>')
+		_p('  <Target Name="AfterBuild">')
+		_p('  </Target>')
+		_p('  -->')
+		_p('</Project>')
+		
+	end
+

src/actions/vstudio/vs200x_vcproj.lua

 		_p(2,'<Configuration')
 		_x(3,'Name="%s"', vstudio.configname(cfg))
 
-		local outdir = path.translate(config.gettargetinfo(cfg).directory)
+		local outdir = path.translate(cfg.buildtarget.directory)
 		_x(3,'OutputDirectory="%s"', outdir)
 
 		_x(3,'IntermediateDirectory="%s"', path.translate(project.getrelative(cfg.project, cfg.objdir)))
 			_x(4,'AdditionalDependencies="%s"', vc200x.links(cfg))
 		end
 
-		_x(4,'OutputFile="$(OutDir)\\%s"', config.gettargetinfo(cfg).name)
+		_x(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name)
 
 		if cfg.kind ~= premake.STATICLIB then
 			_p(4,'LinkIncremental="%s"', iif(premake.config.canincrementallink(cfg) , 2, 1))
 			_p(4,'GenerateDebugInformation="%s"', bool(vc200x.symbols(cfg) ~= 0))
 	
 			if vc200x.symbols(cfg) >= 3 then
-				_x(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', config.gettargetinfo(cfg).basename)
+				_x(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', cfg.buildtarget.basename)
 			end
 	
 			_p(4,'SubSystem="%s"', iif(cfg.kind == "ConsoleApp", 1, 2))
 			end
 	
 			if cfg.kind == "SharedLib" then
-				local implibname = config.getlinkinfo(cfg).fullpath
+				local implibname = cfg.linktarget.fullpath
 				-- I can't actually stop the import lib, but I can hide it in the objects directory
 				if cfg.flags.NoImportLib then
 					implibname = path.join(cfg.objdir, path.getname(implibname))
 			_x(4,'AdditionalDependencies="%s"', table.concat(toolset.getlinks(cfg), " "))
 		end
 			
-		_x(4,'OutputFile="$(OutDir)\\%s"', config.gettargetinfo(cfg).name)
+		_x(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name)
 
 		if cfg.kind ~= premake.STATICLIB then
 			_p(4,'LinkIncremental="0"')
 --
 
 	function vc200x.programDatabase(cfg)
-		local target = config.gettargetinfo(cfg)
+		local target = cfg.buildtarget
 		_x(4,'ProgramDataBaseFileName="$(OutDir)\\%s%s.pdb"', target.prefix, target.basename)
 	end
 
 			end
 			
 			if cfg.kind == "SharedLib" then
-				local implibname = config.getlinkinfo(cfg).fullpath
+				local implibname = cfg.linktarget.fullpath
 				_p(4,'ImportLibrary="%s"', iif(cfg.flags.NoImportLib, cfg.objectsdir .. "\\" .. path.getname(implibname), implibname))
 			end
 			

src/actions/vstudio/vs2010_vcxproj.lua

 --
 
 	function vc2010.outputProperties(cfg)
-		local target = config.gettargetinfo(cfg)
+		local target = cfg.buildtarget
 
 		_p(1,'<PropertyGroup %s>', vc2010.condition(cfg))
 
 		vc2010.debuginfo(cfg)
 
 		if cfg.flags.Symbols and cfg.debugformat ~= "c7" then
-			local filename = config.gettargetinfo(cfg).basename
+			local filename = cfg.buildtarget.basename
 			_p(3,'<ProgramDataBaseFileName>$(OutDir)%s.pdb</ProgramDataBaseFileName>', filename)
 		end
 
 		vc2010.additionalLibraryDirectories(cfg)
 
 		if cfg.kind == premake.SHAREDLIB then
-			local implibname = config.getlinkinfo(cfg).fullpath
+			local implibname = cfg.linktarget.fullpath
 			_x(3,'<ImportLibrary>%s</ImportLibrary>', path.translate(implibname))
 		end
 

src/project/config.lua

 -- Copyright (c) 2011-2012 Jason Perkins and the Premake project
 --
 
-	premake5.config = { }
+	premake5.config = {}
 	local project = premake5.project
 	local config = premake5.config
 	local oven = premake5.oven
 		cfg.longname = table.concat({ cfg.buildcfg, cfg.platform }, "|")
 		cfg.shortname = table.concat({ cfg.buildcfg, cfg.platform }, " ")
 		cfg.shortname = cfg.shortname:gsub(" ", "_"):lower()
+
+		if cfg.project and cfg.kind then
+			cfg.buildtarget = config.gettargetinfo(cfg)
+			oven.expandtokens(cfg, nil, nil, "buildtarget")
+			cfg.linktarget = config.getlinkinfo(cfg)
+			oven.expandtokens(cfg, nil, nil, "linktarget")
+		end
 	end
 
 
 		info.extension  = extension
 		info.abspath    = path.join(directory, info.name)
 		info.fullpath   = path.join(info.directory, info.name)
+		info.relpath    = info.fullpath
 		info.bundlename = bundlename
 		info.bundlepath = path.join(info.directory, bundlepath)
 		info.prefix     = prefix
 --
 
 	function config.getlinkinfo(cfg)
-		-- have I cached results from a previous call?
-		if cfg.linkinfo then
-			return cfg.linkinfo
-		end
-
 		-- if an import library is in use, switch the target kind
 		local kind = cfg.kind
 		local field = "target"
 			end
 		end
 
-		local info = buildtargetinfo(cfg, kind, field)
-
-		-- cache the results for future calls
-		cfg.linkinfo = info
-		return info
+		return buildtargetinfo(cfg, kind, field)
 	end
 
 
 					-- any kind of path info, because I don't know the target name
 					elseif not prj.externalname then
 						if part == "basename" then
-							item = config.getlinkinfo(prjcfg).basename
+							item = prjcfg.linktarget.basename
 						else
-							item = path.rebase(config.getlinkinfo(prjcfg).fullpath, 
+							item = path.rebase(prjcfg.linktarget.fullpath, 
 											   project.getlocation(prjcfg.project), 
 											   project.getlocation(cfg.project))
 							if part == "directory" then
 --
 
 	function config.gettargetinfo(cfg)
-		-- have I cached results from a previous call?
-		if cfg.targetinfo then
-			return cfg.targetinfo
-		end
-
-		local info = buildtargetinfo(cfg, cfg.kind, "target")
-
-		-- cache the results for future calls
-		cfg.targetinfo = info
-		return info
+		return buildtargetinfo(cfg, cfg.kind, "target")
 	end

src/project/project.lua

 		cfg.solution = prj.solution
 		cfg.project = prj
 		cfg.architecture = cfg.architecture or architecture
-
+		
 		-- fill in any calculated values
 		premake5.config.bake(cfg)
 

src/tools/gcc.lua

 			end
 
 			if cfg.system == "windows" and not cfg.flags.NoImportLib then
-				table.insert(flags, '-Wl,--out-implib="' .. config.getlinkinfo(cfg).fullpath .. '"')
+				table.insert(flags, '-Wl,--out-implib="' .. cfg.linktarget.fullpath .. '"')
 			end
 		end
 	
 				-- skip external project references, since I have no way
 				-- to know the actual output target path
 				if not link.project.externalname then
-					local linkinfo = config.getlinkinfo(link)
 					if link.kind == premake.STATICLIB then
 						-- Don't use "-l" flag when linking static libraries; instead use 
 						-- path/libname.a to avoid linking a shared library of the same
 						-- name if one is present
-						table.insert(result, project.getrelative(cfg.project, linkinfo.abspath))
+						table.insert(result, project.getrelative(cfg.project, link.linktarget.abspath))
 					else
-						table.insert(result, "-l" .. linkinfo.basename)
+						table.insert(result, "-l" .. link.linktarget.basename)
 					end
 				end
 			end

tests/oven/test_tokens.lua

 		test.isequal(os.getcwd() .. "/build/MySolution", sln.location)
 	end
 
+
+--
+-- Verify that target information is available.
+--
+
+	function suite.canAccessBuildTarget()
+		_OS = "windows"
+		targetdir "%{cfg.buildcfg}"
+		testapi "%{cfg.buildtarget.relpath}"
+		prepare()
+		test.isequal("Debug/MyProject.exe", cfg.testapi)
+	end
+
+	function suite.canAccessLinkTarget()
+		_OS = "windows"
+		kind "SharedLib"
+		testapi "%{cfg.linktarget.relpath}"
+		prepare()
+		test.isequal("MyProject.lib", cfg.testapi)
+	end
+
 		

tests/tools/test_gcc.lua

 	local suite = T.tools_gcc
 
 	local gcc = premake.tools.gcc
+	local project = premake5.project
 
 
 --
 	local sln, prj, cfg
 
 	function suite.setup()
-		sln, prj = test.createsolution()
+		sln = test.createsolution()
 		system "Linux"
 	end
 
 	local function prepare()
+		prj = premake.solution.getproject_ng(sln, 1)
 		cfg = premake5.project.getconfig(prj, "Debug")
 	end