Jason Perkins avatar Jason Perkins committed 81375aa

Initial support for VC 2010 Makefile projects

Comments (0)

Files changed (10)

src/actions/vstudio/_vstudio.lua

 		-- temporary, until I can phase out the legacy implementations
 		isnextgen = true,
 
-		valid_kinds     = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" },
+		valid_kinds     = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile" },
 
 		valid_languages = { "C", "C++", "C#" },
 

src/actions/vstudio/vs2010_vcxproj.lua

 
 		for cfg in project.eachconfig(prj) do
 			vc2010.outputProperties(cfg)
+			vc2010.nmakeProperties(cfg)
 		end
 
 		for cfg in project.eachconfig(prj) do
-			_p(1,'<ItemDefinitionGroup %s>', vc2010.condition(cfg))
-			vc2010.clCompile(cfg)
-			vc2010.resourceCompile(cfg)
-			vc2010.link(cfg)
-			vc2010.buildEvents(cfg)
-			vc2010.imageXex(cfg)
-			vc2010.deploy(cfg)
-			_p(1,'</ItemDefinitionGroup>')
+			vc2010.itemDefinitionGroup(cfg)
 		end
 
 		vc2010.assemblyReferences(prj)
 --
 
 	function vc2010.projectConfigurations(prj)
+
 		-- build a list of all architectures used in this project
 		local platforms = {}
 		for cfg in project.eachconfig(prj) do
 		vc2010.projectGuid(prj)
 
 		-- try to determine what kind of targets we're building here
-		local isWin, isManaged
+		local isWin, isManaged, isMakefile
 		for cfg in project.eachconfig(prj) do
 			if cfg.system == premake.WINDOWS then
 				isWin = true
 			if cfg.flags.Managed then
 				isManaged = true
 			end
+			if cfg.kind == premake.MAKEFILE then
+				isMakefile = true
+			end
 		end
 
 		if isWin then
-			if isManaged then
-				_p(2,'<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>')
-				_p(2,'<Keyword>ManagedCProj</Keyword>')
+			if isMakefile then
+				_p(2,'<Keyword>MakeFileProj</Keyword>')
 			else
-				_p(2,'<Keyword>Win32Proj</Keyword>')
+				if isManaged then
+					_p(2,'<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>')
+					_p(2,'<Keyword>ManagedCProj</Keyword>')
+				else
+					_p(2,'<Keyword>Win32Proj</Keyword>')
+				end
+				_p(2,'<RootNamespace>%s</RootNamespace>', prj.name)
 			end
-			_p(2,'<RootNamespace>%s</RootNamespace>', prj.name)
 		end
 
 		_p(1,'</PropertyGroup>')
 		vc2010.useOfMfc(cfg)
 		vc2010.clrSupport(cfg)
 		vc2010.characterSet(cfg)
+
+		if cfg.kind == premake.MAKEFILE then
+			vc2010.outDir(cfg)
+			vc2010.intDir(cfg)
+		end
+
 		_p(1,'</PropertyGroup>')
 	end
 
 
 
 --
--- Write the output property group, which  includes the output and intermediate
+-- Write the output property group, which includes the output and intermediate
 -- directories, manifest, etc.
 --
 
 	function vc2010.outputProperties(cfg)
-		vc2010.propertyGroup(cfg)
-		vc2010.linkIncremental(cfg)
-		vc2010.ignoreImportLibrary(cfg)
-		vc2010.outDir(cfg)
-		vc2010.outputFile(cfg)
-		vc2010.intDir(cfg)
-		vc2010.targetName(cfg)
-		vc2010.targetExt(cfg)
-		vc2010.imageXexOutput(cfg)
-		vc2010.generateManifest(cfg)
-		_p(1,'</PropertyGroup>')
+		if cfg.kind ~= premake.MAKEFILE then
+			vc2010.propertyGroup(cfg)
+			vc2010.linkIncremental(cfg)
+			vc2010.ignoreImportLibrary(cfg)
+			vc2010.outDir(cfg)
+			vc2010.outputFile(cfg)
+			vc2010.intDir(cfg)
+			vc2010.targetName(cfg)
+			vc2010.targetExt(cfg)
+			vc2010.imageXexOutput(cfg)
+			vc2010.generateManifest(cfg)
+			_p(1,'</PropertyGroup>')
+		end
+	end
+
+
+--
+-- Write the NMake property group for Makefile projects, which includes the custom
+-- build commands, output file location, etc.
+--
+
+	function vc2010.nmakeProperties(cfg)
+		if cfg.kind == premake.MAKEFILE then
+			vc2010.propertyGroup(cfg)
+			vc2010.nmakeOutput(cfg)
+			_p(1,'</PropertyGroup>')
+		end
+	end
+
+
+--
+-- Write a configuration's item definition group, which contains all
+-- of the per-configuration compile and link settings.
+--
+
+	function vc2010.itemDefinitionGroup(cfg)
+		if cfg.kind ~= premake.MAKEFILE then
+			_p(1,'<ItemDefinitionGroup %s>', vc2010.condition(cfg))
+			vc2010.clCompile(cfg)
+			vc2010.resourceCompile(cfg)
+			vc2010.link(cfg)
+			vc2010.buildEvents(cfg)
+			vc2010.imageXex(cfg)
+			vc2010.deploy(cfg)
+			_p(1,'</ItemDefinitionGroup>')
+
+		else
+			if cfg == project.getfirstconfig(cfg.project) then
+				_p(1,'<ItemDefinitionGroup>')
+				_p(1,'</ItemDefinitionGroup>')
+			end
+		end
 	end
 
 
 --
 
 	function vc2010.clCompile(cfg)
-		_p(2,'<ClCompile>')
-		vc2010.precompiledHeader(cfg)
-		vc2010.warningLevel(cfg)
-		vc2010.treatWarningAsError(cfg)
-        vc2010.basicRuntimeChecks(cfg)
-		vc2010.preprocessorDefinitions(cfg.defines)
-		vc2010.additionalIncludeDirectories(cfg, cfg.includedirs)
-		vc2010.forceIncludes(cfg)
-		vc2010.debugInformationFormat(cfg)
-		vc2010.programDataBaseFileName(cfg)
-		vc2010.optimization(cfg)
-		vc2010.functionLevelLinking(cfg)
-		vc2010.intrinsicFunctions(cfg)
-		vc2010.minimalRebuild(cfg)
-		vc2010.omitFramePointers(cfg)
-		vc2010.stringPooling(cfg)
-		vc2010.runtimeLibrary(cfg)
-		vc2010.exceptionHandling(cfg)
-		vc2010.runtimeTypeInfo(cfg)
-		vc2010.treatWChar_tAsBuiltInType(cfg)
-		vc2010.floatingPointModel(cfg)
-		vc2010.enableEnhancedInstructionSet(cfg)
-		vc2010.multiProcessorCompilation(cfg)
-		vc2010.additionalCompileOptions(cfg)
-		vc2010.compileAs(cfg)
-		_p(2,'</ClCompile>')
+		if cfg.kind ~= premake.MAKEFILE then
+			_p(2,'<ClCompile>')
+			vc2010.precompiledHeader(cfg)
+			vc2010.warningLevel(cfg)
+			vc2010.treatWarningAsError(cfg)
+			vc2010.basicRuntimeChecks(cfg)
+			vc2010.preprocessorDefinitions(cfg, cfg.defines)
+			vc2010.additionalIncludeDirectories(cfg, cfg.includedirs)
+			vc2010.forceIncludes(cfg)
+			vc2010.debugInformationFormat(cfg)
+			vc2010.programDataBaseFileName(cfg)
+			vc2010.optimization(cfg)
+			vc2010.functionLevelLinking(cfg)
+			vc2010.intrinsicFunctions(cfg)
+			vc2010.minimalRebuild(cfg)
+			vc2010.omitFramePointers(cfg)
+			vc2010.stringPooling(cfg)
+			vc2010.runtimeLibrary(cfg)
+			vc2010.exceptionHandling(cfg)
+			vc2010.runtimeTypeInfo(cfg)
+			vc2010.treatWChar_tAsBuiltInType(cfg)
+			vc2010.floatingPointModel(cfg)
+			vc2010.enableEnhancedInstructionSet(cfg)
+			vc2010.multiProcessorCompilation(cfg)
+			vc2010.additionalCompileOptions(cfg)
+			vc2010.compileAs(cfg)
+			_p(2,'</ClCompile>')
+		end
 	end
 
 
 --
 
 	function vc2010.resourceCompile(cfg)
-		if cfg.system ~= premake.XBOX360 then
+		if cfg.kind ~= premake.MAKEFILE and cfg.system ~= premake.XBOX360 then
 			_p(2,'<ResourceCompile>')
-			vc2010.preprocessorDefinitions(table.join(cfg.defines, cfg.resdefines))
+			vc2010.preprocessorDefinitions(cfg, table.join(cfg.defines, cfg.resdefines))
 			vc2010.additionalIncludeDirectories(cfg, table.join(cfg.includedirs, cfg.resincludedirs))
 			_p(2,'</ResourceCompile>')
 		end
 --
 
 	function vc2010.link(cfg)
-		local explicit = vstudio.needsExplicitLink(cfg)
+		if cfg.kind ~= premake.MAKEFILE then
+			local explicit = vstudio.needsExplicitLink(cfg)
 
-		_p(2,'<Link>')
+			_p(2,'<Link>')
 
-		vc2010.subSystem(cfg)
-		vc2010.generateDebugInformation(cfg)
-		vc2010.optimizeReferences(cfg)
+			vc2010.subSystem(cfg)
+			vc2010.generateDebugInformation(cfg)
+			vc2010.optimizeReferences(cfg)
 
-		if cfg.kind ~= premake.STATICLIB then
-			vc2010.linkDynamic(cfg, explicit)
+			if cfg.kind ~= premake.STATICLIB then
+				vc2010.linkDynamic(cfg, explicit)
+			end
+
+			_p(2,'</Link>')
+
+			if cfg.kind == premake.STATICLIB then
+				vc2010.linkStatic(cfg)
+			end
+
+			vc2010.linkLibraryDependencies(cfg, explicit)
 		end
-
-		_p(2,'</Link>')
-
-		if cfg.kind == premake.STATICLIB then
-			vc2010.linkStatic(cfg)
-		end
-
-		vc2010.linkLibraryDependencies(cfg, explicit)
 	end
 
 	function vc2010.linkDynamic(cfg, explicit)
 		end
 	end
 
+
 	function vc2010.additionalLinkOptions(cfg)
 		if #cfg.linkoptions > 0 then
 			local opts = table.concat(cfg.linkoptions, " ")
 
 
 	function vc2010.characterSet(cfg)
-		_p(2,'<CharacterSet>%s</CharacterSet>', iif(cfg.flags.Unicode, "Unicode", "MultiByte"))
+		if cfg.kind ~= premake.MAKEFILE then
+			_p(2,'<CharacterSet>%s</CharacterSet>', iif(cfg.flags.Unicode, "Unicode", "MultiByte"))
+		end
 	end
 
 
 
 
 	function vc2010.configurationType(cfg)
-		_p(2,'<ConfigurationType>%s</ConfigurationType>', vc2010.configType(cfg))
+		local types = {
+			SharedLib = "DynamicLibrary",
+			StaticLib = "StaticLibrary",
+			ConsoleApp = "Application",
+			WindowedApp = "Application",
+			Makefile = "Makefile",
+		}
+		_p(2,'<ConfigurationType>%s</ConfigurationType>', types[cfg.kind])
 	end
 
 
 
 
 	function vc2010.entryPointSymbol(cfg)
-		if vc2010.configType(cfg) == "Application" and
+		if (cfg.kind == premake.CONSOLEAPP or cfg.kind == premake.WINDOWEDAPP) and
 		   not cfg.flags.WinMain and
 		   not cfg.flags.Managed and
 		   cfg.system ~= premake.XBOX360
 	end
 
 
+	function vc2010.nmakeOutput(cfg)
+		_p(2,'<NMakeOutput>$(OutDir)%s</NMakeOutput>', cfg.buildtarget.name)
+	end
+
+
 	function vc2010.objectFileName(filecfg)
 		local objectname = project.getfileobject(filecfg.project, filecfg.abspath)
 		if objectname ~= path.getbasename(filecfg.abspath) then
 
 	function vc2010.outputFile(cfg)
 		if cfg.system == premake.XBOX360 then
-			_x(2,'<OutputFile>$(OutDir)%s</OutputFile>', cfg.buildtarget.name)
+			_p(2,'<OutputFile>$(OutDir)%s</OutputFile>', cfg.buildtarget.name)
 		end
 	end
 
 	end
 
 
-	function vc2010.preprocessorDefinitions(defines)
+	function vc2010.preprocessorDefinitions(cfg, defines)
 		if #defines > 0 then
 			defines = table.concat(defines, ";")
 			_x(3,'<PreprocessorDefinitions>%s;%%(PreprocessorDefinitions)</PreprocessorDefinitions>', defines)
 
 
 --
--- Map Premake's project kinds to Visual Studio configuration types.
---
-
-	function vc2010.configType(cfg)
-		local map = {
-			SharedLib = "DynamicLibrary",
-			StaticLib = "StaticLibrary",
-			ConsoleApp = "Application",
-			WindowedApp = "Application"
-		}
-		return map[cfg.kind]
-	end
-
-
---
 -- Output an individual project XML element, with an optional configuration
 -- condition.
 --

tests/actions/vstudio/vc2010/test_config_props.lua

 	local sln, prj, cfg
 
 	function suite.setup()
-		sln, prj = test.createsolution()
+		sln = test.createsolution()
 	end
 
 	local function prepare()
+		prj = premake.solution.getproject_ng(sln, 1)
 		cfg = project.getconfig(prj, "Debug")
 		vc2010.configurationProperties(cfg)
 	end
 		]]
 	end
 
+
+--
+-- Check the default settings for a Makefile configuration: new
+-- configuration type, no character set, output and intermediate
+-- folders are moved up from their normal location in the output
+-- configuration element.
+--
+
+	function suite.structureIsCorrect_onMakefile()
+		kind "Makefile"
+		prepare()
+		test.capture [[
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+		<ConfigurationType>Makefile</ConfigurationType>
+		<UseDebugLibraries>false</UseDebugLibraries>
+		<OutDir>.\</OutDir>
+		<IntDir>obj\Debug\</IntDir>
+	</PropertyGroup>
+		]]
+	end

tests/actions/vstudio/vc2010/test_globals.lua

 	</PropertyGroup>
 		]]
 	end
+
+
+--
+-- Makefile projects set new keyword and drop the root namespace.
+--
+
+	function suite.keywordIsCorrect_onMakefile()
+		kind "Makefile"
+		prepare()
+		test.capture [[
+	<PropertyGroup Label="Globals">
+		<ProjectGuid>{42B5DBC6-AE1F-903D-F75D-41E363076E92}</ProjectGuid>
+		<Keyword>MakeFileProj</Keyword>
+	</PropertyGroup>
+		]]
+	end

tests/actions/vstudio/vc2010/test_item_def_group.lua

+--
+-- tests/actions/vstudio/vc2010/test_item_def_group.lua
+-- Check the item definition groups, containing compile and link flags.
+-- Copyright (c) 2013 Jason Perkins and the Premake project
+--
+
+	local suite = test.declare("vs2010_config_props")
+	local vc2010 = premake.vstudio.vc2010
+	local project = premake5.project
+
+
+--
+-- Setup
+--
+
+	local sln, prj, cfg
+
+	function suite.setup()
+		sln = test.createsolution()
+	end
+
+	local function prepare(buildcfg)
+		prj = premake.solution.getproject_ng(sln, 1)
+		cfg = project.getconfig(prj, buildcfg or "Debug")
+		vc2010.itemDefinitionGroup(cfg)
+	end
+
+
+--
+-- Check generation of opening element for typical C++ project.
+--
+
+	function suite.structureIsCorrect_onDefaultValues()
+		prepare()
+		test.capture [[
+	<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+		]]
+	end
+
+
+--
+-- Makefile projects omit the condition and all contents.
+--
+
+	function suite.structureIsCorrect_onMakefile()
+		kind "Makefile"
+		prepare()
+		test.capture [[
+	<ItemDefinitionGroup>
+	</ItemDefinitionGroup>
+		]]
+	end
+
+
+
+--
+-- Because the item definition group for makefile projects is not
+-- tied to a particular condition, it should only get written for
+-- the first configuration.
+--
+
+	function suite.skipped_onSubsequentConfigs()
+		kind "Makefile"
+		prepare("Release")
+		test.isemptycapture()
+	end

tests/actions/vstudio/vc2010/test_link.lua

 		</Link>
 		]]
 	end
-

tests/actions/vstudio/vc2010/test_nmake_props.lua

+--
+-- tests/actions/vstudio/vc2010/test_nmake_props.lua
+-- Check makefile project generation.
+-- Copyright (c) 2013 Jason Perkins and the Premake project
+--
+
+	local suite = test.declare("vs2010_nmake_props")
+	local vc2010 = premake.vstudio.vc2010
+	local project = premake5.project
+
+
+--
+-- Setup
+--
+
+	local sln, prj, cfg
+
+	function suite.setup()
+		sln = test.createsolution()
+		kind "Makefile"
+	end
+
+	local function prepare()
+		prj = premake.solution.getproject_ng(sln, 1)
+		cfg = project.getconfig(prj, "Debug")
+		vc2010.nmakeProperties(cfg)
+	end
+
+
+--
+-- Check the structure with the default project values.
+--
+
+	function suite.structureIsCorrect_onDefaultValues()
+		prepare()
+		test.capture [[
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+		<NMakeOutput>$(OutDir)MyProject</NMakeOutput>
+	</PropertyGroup>
+		]]
+	end
+
+
+--
+-- Element should be skipped for non-Makefile projects.
+--
+
+	function suite.skips_onNonMakefile()
+		kind "ConsoleApp"
+		prepare()
+		test.isemptycapture()
+	end
+
+
+--
+-- Make sure the target file extension is included.
+--
+
+	function suite.usesTargetExtension()
+		targetextension ".exe"
+		prepare()
+		test.capture [[
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+		<NMakeOutput>$(OutDir)MyProject.exe</NMakeOutput>
+	</PropertyGroup>
+		]]
+	end

tests/actions/vstudio/vc2010/test_output_props.lua

 
 
 --
+-- This entire block gets skipped for Makefile projects.
+--
+
+	function suite.omitsBlock_onMakefile()
+		kind "Makefile"
+		prepare()
+		test.isemptycapture()
+	end
+
+
+--
 -- Xbox360 adds an extra <OutputFile> element to the block.
 --
 

tests/actions/vstudio/vc2010/test_resource_compile.lua

 		]]
 	end
 
+
 --
 -- If defines are specified, the <PreprocessorDefinitions> element should be added.
 --

tests/premake4.lua

 	dofile("actions/vstudio/vc2010/test_files.lua")
 	dofile("actions/vstudio/vc2010/test_filter_ids.lua")
 	dofile("actions/vstudio/vc2010/test_filters.lua")
+	dofile("actions/vstudio/vc2010/test_item_def_group.lua")
 	dofile("actions/vstudio/vc2010/test_link.lua")
+	dofile("actions/vstudio/vc2010/test_nmake_props.lua")
 	dofile("actions/vstudio/vc2010/test_output_props.lua")
 	dofile("actions/vstudio/vc2010/test_project_configs.lua")
 	dofile("actions/vstudio/vc2010/test_project_refs.lua")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.