premake/premake4.lua
author Sam Lantinga <slouken@libsdl.org>
Sun, 17 Aug 2014 14:57:52 -0700
changeset 9086 c5e33f9a0d03
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rwxr-xr-x
Fixed bug 2655 - OSX: Window position and global mouse coord spaces are different

Tim McDaniel

On OSX, with revision 8729, the coordinate space for window position and the coordinate space for global mouse position don't match. For a non-fullscreen window, the window position is global relative to the bottom of the menubar. The global mouse position is relative to the top of the screen. This affects Cocoa_WarpMouse and potentially other things as well. Further, the coordinate system for window position is now affected by what screen it is on. For example, if I have two equal size screens oriented side by side such that the tops of the screens are equal in global space, with the menubar on one screen, and a window straddles the two screens, the window's y position makes no sense. The window's y position depends on what screen "most" of the window is on. So if I move the window horizontally just a bit, the y position of my window is now different by the size of the menubar, even though the window was not moved vertically.

I'd like to reiterate that this was a fairly fundamental change (and a breaking change for us). If SDL OSX is to really support multi-display configurations, this is especially problematic.

If the real concern is preventing windows from going under the menubar, then perhaps a solution involving something like overriding [NSWindow constrainFrameRect] would be less problematic than redefining the global window coord space for the main display.
     1 -- Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     2 --
     3 -- This software is provided 'as-is', without any express or implied
     4 -- warranty.  In no event will the authors be held liable for any damages
     5 -- arising from the use of this software.
     6 --
     7 -- Permission is granted to anyone to use this software for any purpose,
     8 -- including commercial applications, and to alter it and redistribute it
     9 -- freely.
    10 --
    11 -- Meta-build system using premake created and maintained by
    12 -- Benjamin Henning <b.henning@digipen.edu>
    13 
    14 --[[
    15 premake4.lua
    16 
    17 	This script sets up the entire premake system. It's responsible for executing
    18 	all of the definition scripts for the SDL2 library and the entire test suite,
    19 	or demos for the iOS platform. It handles each specific platform and uses the
    20 	setup state to generate both the configuration header file needed to build
    21 	SDL2 and the premake lua script to generate the target project files.
    22 ]]
    23 
    24 -- string utility functions
    25 dofile "util/sdl_string.lua"
    26 -- utility file wrapper for some useful functions
    27 dofile "util/sdl_file.lua"
    28 -- system for defining SDL projects
    29 dofile "util/sdl_projects.lua"
    30 -- offers a utility function for finding dependencies specifically on windows
    31 dofile "util/sdl_depends.lua"
    32 -- system for generating a *config.h file used to build the SDL2 library
    33 dofile "util/sdl_gen_config.lua"
    34 -- functions to handle complicated dependency checks using CMake-esque functions
    35 dofile "util/sdl_check_compile.lua"
    36 -- a list of dependency functions for the SDL2 project and any other projects
    37 dofile "util/sdl_dependency_checkers.lua"
    38 
    39 -- the following are various options for configuring the meta-build system
    40 newoption {
    41 	trigger = "to",
    42 	value   = "path",
    43 	description = "Set the base output directory for the generated and executed lua file."
    44 }
    45 
    46 newoption {
    47 	trigger = "mingw",
    48 	description = "Runs the premake generation script targeted to MinGW."
    49 }
    50 
    51 newoption {
    52 	trigger = "cygwin",
    53 	description = "Runs the premake generation script targeted to Cygwin."
    54 }
    55 
    56 newoption {
    57 	trigger = "ios",
    58 	description = "Runs the premake generation script targeted to iOS."
    59 }
    60 
    61 -- determine the localized destination path
    62 local baseLoc = "./"
    63 if _OPTIONS["to"] then
    64 	baseLoc = _OPTIONS["to"]:gsub("\\", "/")
    65 end
    66 
    67 local deps = SDL_getDependencies()
    68 for _,v in ipairs(deps) do
    69 	newoption {
    70 		trigger = v:lower(),
    71 		description = "Force on the dependency: " .. v
    72 	}
    73 end
    74 
    75 -- clean action
    76 if _ACTION == "clean" then
    77 	-- this is kept the way it is because premake's default method of cleaning the
    78 	-- build tree is not very good standalone, whereas the following correctly
    79 	-- cleans every build option
    80 	print("Cleaning the build environment...")
    81 	os.rmdir(baseLoc .. "/SDL2")
    82 	os.rmdir(baseLoc .. "/SDL2main")
    83 	os.rmdir(baseLoc .. "/SDL2test")
    84 	os.rmdir(baseLoc .. "/tests")
    85 	os.rmdir(baseLoc .. "/Demos")
    86 	os.rmdir(baseLoc .. "/ipch") -- sometimes shows up
    87 	os.remove(baseLoc .. "/SDL.sln")
    88 	os.remove(baseLoc .. "/SDL.suo")
    89 	os.remove(baseLoc .. "/SDL.v11.suo")
    90 	os.remove(baseLoc .. "/SDL.sdf")
    91 	os.remove(baseLoc .. "/SDL.ncb")
    92 	os.remove(baseLoc .. "/SDL-gen.lua")
    93 	os.remove(baseLoc .. "/SDL_config_premake.h")
    94 	os.remove(baseLoc .. "/Makefile")
    95 	os.rmdir(baseLoc .. "/SDL.xcworkspace")
    96 	os.exit()
    97 end
    98 
    99 -- only run through standard execution if not in help mode
   100 if _OPTIONS["help"] == nil then
   101 	-- load all of the project definitions
   102 	local results = os.matchfiles("projects/**.lua")
   103 	for _,dir in ipairs(results) do
   104 		dofile(dir)
   105 	end
   106 
   107 	-- figure out which configuration template to use
   108 	local premakeConfigHeader = baseLoc .. "/SDL_config_premake.h"
   109 	-- minimal configuration is the default
   110 	local premakeTemplateHeader = "./config/SDL_config_minimal.template.h"
   111 	if SDL_getos() == "windows" or SDL_getos() == "mingw" then
   112 		premakeTemplateHeader = "./config/SDL_config_windows.template.h"
   113 	elseif SDL_getos() == "macosx" then
   114 		premakeTemplateHeader = "./config/SDL_config_macosx.template.h"
   115 	elseif SDL_getos() == "ios" then
   116 		premakeTemplateHeader = "./config/SDL_config_iphoneos.template.h"
   117 	elseif os.get() == "linux" then
   118 		premakeTemplateHeader = "./config/SDL_config_linux.template.h"
   119 	elseif SDL_getos() == "cygwin" then
   120 		premakeTemplateHeader = "./config/SDL_config_cygwin.template.h"
   121 	end
   122 
   123 	local genFile = baseLoc .. "/SDL-gen.lua"
   124 	local file = fileopen(genFile, "wt")
   125 	print("Generating " .. genFile .. "...")
   126 	-- begin generating the config header file
   127 	startGeneration(premakeConfigHeader, premakeTemplateHeader)
   128 
   129 	-- begin generating the actual premake script
   130 	file:print(0, "-- Premake script generated by Simple DirectMedia Layer meta-build script")
   131 	file:print(1, 'solution "SDL"')
   132 	local platforms = { }
   133 	local platformsIndexed = { }
   134 		for n,p in pairs(projects) do
   135 			if p.platforms and #p.platforms ~= 0 then
   136 				for k,v in pairs(p.platforms) do
   137 					platforms[v] = true
   138 				end
   139 			end
   140 		end
   141 		for n,v in pairs(platforms) do
   142 			platformsIndexed[#platformsIndexed + 1] = n
   143 		end
   144 		file:print(2, implode(platformsIndexed, 'platforms {', '"', '"', ', ', '}'))
   145 		file:print(2, 'configurations { "Debug", "Release" }')
   146 		for n,p in pairs(projects) do
   147 			if p.compat then
   148 				local proj = {}
   149 				if p.projectLocation ~= nil then
   150 					proj.location = p.projectLocation .. "/" .. p.name
   151 				else
   152 					proj.location = p.name .. "/"
   153 				end
   154 				proj.includedirs = { path.getrelative(baseLoc,
   155 					path.getdirectory(premakeConfigHeader)),
   156 					path.getrelative(baseLoc, "../include") }
   157 				proj.libdirs = { }
   158 				proj.files = { }
   159 				local links = { }
   160 				local dbgCopyTable = { }
   161 				local relCopyTable = { }
   162 				-- custom links that shouldn't exist...
   163 				-- (these should always happen before dependencies)
   164 				if p.customLinks ~= nil then
   165 					for k,lnk in pairs(p.customLinks) do
   166 						table.insert(links, lnk)
   167 					end
   168 				end
   169 				-- setup project dependencies
   170 				local dependencyLocs = { }
   171 				if p.projectDependencies ~= nil and #p.projectDependencies ~= 0 then
   172 					for k,projname in pairs(p.projectDependencies) do
   173 						local depproj = projects[projname]
   174 						-- validation that it exists and can be linked to
   175 						if depproj ~= nil and (depproj.kind == "SharedLib" or depproj.kind == "StaticLib") then
   176 							if depproj.kind == "SharedLib" then
   177 								local deplocation = nil
   178 								if depproj.projectLocation ~= nil then
   179 									deplocation = depproj.projectLocation .. "/" .. p.name
   180 								else
   181 									deplocation = depproj.name .. "/"
   182 								end
   183 								table.insert(dependencyLocs, { location = deplocation, name = projname })
   184 							else -- static lib
   185 								-- we are now dependent on everything the static lib is dependent on
   186 								if depproj.customLinks ~= nil then
   187 									for k,lnk in pairs(depproj.customLinks) do
   188 										table.insert(links, lnk)
   189 									end
   190 								end
   191 								-- also include links from dependencies
   192 								for i,d in pairs(depproj.dependencyTree) do
   193 									if d.links then
   194 										for k,v in pairs(d.links) do
   195 											local propPath = v:gsub("\\", "/")
   196 											table.insert(links, propPath)
   197 										end
   198 									end
   199 								end
   200 							end
   201 							-- finally, depend on the project itself
   202 							table.insert(links, projname)
   203 						elseif depproj == nil then
   204 							print("Warning: Missing external dependency for project: ".. p.name ..
   205 								". Be sure you setup project dependencies in a logical order.")
   206 						else
   207 							print("Warning: Cannot link " .. p.name .. " to second project " ..
   208 								projname .. " because the second project is not a library.")
   209 						end
   210 					end
   211 				end
   212 				-- iterate across all root directories, matching source directories
   213 				local dirs = createDirTable(p.sourcedir)
   214 				-- but first, handle any files specifically set in the project, rather than
   215 				-- its dependencies
   216 				-- register c and h files in this directory
   217 				if (p.files ~= nil and #p.files ~= 0) or (p.paths ~= nil and #p.paths ~= 0) then
   218 					-- handle all lists of files
   219 					if p.files ~= nil and #p.files ~= 0 then
   220 						for k,filepat in pairs(p.files) do
   221 							for k,f in pairs(os.matchfiles(p.sourcedir .. filepat)) do
   222 								table.insert(proj.files, path.getrelative(baseLoc, f))
   223 							end
   224 						end
   225 					end -- end props files if
   226 					-- add all .c/.h files from each path
   227 					-- handle all related paths
   228 					if p.paths ~= nil and #p.paths ~= 0 then
   229 						for j,filepat in ipairs(p.paths) do
   230 							for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.c")) do
   231 								table.insert(proj.files, path.getrelative(baseLoc, f))
   232 							end
   233 							for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.h")) do
   234 								table.insert(proj.files, path.getrelative(baseLoc, f))
   235 							end
   236 							-- mac osx
   237 							for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.m")) do
   238 								table.insert(proj.files, path.getrelative(baseLoc, f))
   239 							end
   240 						end
   241 					end -- end of props paths if
   242 				end -- end of check for files/paths in main project
   243 				-- if this project has any configuration flags, add them to the current file
   244 				if p.config then
   245 					addConfig(p.config)
   246 				end
   247 				-- now, handle files and paths for dependencies
   248 				for i,props in ipairs(p.dependencyTree) do
   249 					if props.compat then
   250 						-- register c and h files in this directory
   251 						-- handle all lists of files
   252 						if props.files ~= nil and #props.files ~= 0 then
   253 							for k,filepat in pairs(props.files) do
   254 								for k,f in pairs(os.matchfiles(p.sourcedir .. filepat)) do
   255 									table.insert(proj.files, path.getrelative(baseLoc, f))
   256 								end
   257 							end
   258 						end -- end props files if
   259 						-- add all .c/.h files from each path
   260 						-- handle all related paths
   261 						if props.paths ~= nil and #props.paths ~= 0 then
   262 							for j,filepat in ipairs(props.paths) do
   263 								for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.c")) do
   264 									table.insert(proj.files, path.getrelative(baseLoc, f))
   265 								end
   266 								for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.h")) do
   267 									table.insert(proj.files, path.getrelative(baseLoc, f))
   268 								end
   269 								-- mac osx
   270 								for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.m")) do
   271 									table.insert(proj.files, path.getrelative(baseLoc, f))
   272 								end
   273 							end
   274 						end -- end of props paths if
   275 						-- if this dependency has any special configuration flags, add 'em
   276 						if props.config then
   277 							addConfig(props.config)
   278 						end -- end of props config if check
   279 					end -- end check for compatibility
   280 				end -- end of props loop
   281 				--local debugConfig = configuration("Debug")
   282 				local debugConfig = {}
   283 				local releaseConfig = {}
   284 				debugConfig.defines = { "USING_PREMAKE_CONFIG_H", "_DEBUG" }
   285 				releaseConfig.defines = { "USING_PREMAKE_CONFIG_H", "NDEBUG" }
   286 				-- setup per-project defines
   287 				if p.defines ~= nil then
   288 					for k,def in pairs(p.defines) do
   289 						table.insert(debugConfig.defines, def)
   290 						table.insert(releaseConfig.defines, def)
   291 					end
   292 				end
   293 				debugConfig.buildoptions = { }
   294 				if SDL_getos() == "windows" then
   295 					table.insert(debugConfig.buildoptions, "/MDd")
   296 				end
   297 				debugConfig.linkoptions = { }
   298 				releaseConfig.buildoptions = {}
   299 				releaseConfig.linkoptions = {}
   300 				local baseBuildDir = "/Build"
   301 				if os.get() == "windows" then
   302 					baseBuildDir = "/Win32"
   303 				end
   304 				debugConfig.flags = { "Symbols" }
   305 				debugConfig.targetdir = proj.location .. baseBuildDir .. "/Debug"
   306 				releaseConfig.flags = { "OptimizeSpeed" }
   307 				releaseConfig.targetdir = proj.location .. baseBuildDir .. "/Release"
   308 				-- setup postbuild options
   309 				local dbgPostbuildcommands = { }
   310 				local relPostbuildcommands = { }
   311 				-- handle copying depended shared libraries to correct folders
   312 				if os.get() == "windows" then
   313 					for k,deploc in pairs(dependencyLocs) do
   314 						table.insert(dbgCopyTable, { src = deploc.location .. baseBuildDir .. "/Debug/" .. deploc.name .. ".dll",
   315 							dst = debugConfig.targetdir .. "/" .. deploc.name .. ".dll" })
   316 						table.insert(relCopyTable, { src = deploc.location .. baseBuildDir .. "/Release/" .. deploc.name .. ".dll",
   317 							dst = releaseConfig.targetdir .. "/" .. deploc.name .. ".dll" })
   318 					end
   319 				end
   320 				if p.copy ~= nil then
   321 					for k,file in pairs(p.copy) do
   322 						-- the following builds relative paths native to the current system for copying, other
   323 						-- than the copy command itself, this is essentially cross-platform for paths
   324 					
   325 						-- all custom copies should be relative to the current working directory
   326 						table.insert(dbgCopyTable, { src = path.getrelative(baseLoc, p.sourcedir .. "/" .. file), dst = debugConfig.targetdir .. "/" .. file })
   327 						table.insert(relCopyTable, { src = path.getrelative(baseLoc, p.sourcedir .. "/" .. file), dst = releaseConfig.targetdir .. "/" .. file })
   328 					end
   329 				end
   330 				for k,file in pairs(dbgCopyTable) do
   331 					-- all copies should be relative to project location, based on platform
   332 					local relLocation = "./"
   333 					--if os.get() == "windows" then
   334 						relLocation = proj.location
   335 					--end
   336 					local fromPath = "./" .. path.getrelative(relLocation, file.src)
   337 					local toPath = "./" .. path.getrelative(relLocation, file.dst)
   338 					local toPathParent = path.getdirectory(toPath)
   339 					local copyCommand = "cp"
   340 					local destCheck = "if [ ! -d \\\"" .. toPathParent .. "\\\" ]; then mkdir -p \\\"" .. toPathParent .. "\\\"; fi"
   341 					if SDL_getos() ~= "windows" and fromPath:find("*") ~= nil then
   342 						-- to path must be a directory for * copies
   343 						toPath = path.getdirectory(toPath)
   344 					end
   345 					if SDL_getos() == "windows" then
   346 						fromPath = path.translate(fromPath, "/"):gsub("/", "\\\\")
   347 						toPath = path.translate(toPath, "/"):gsub("/", "\\\\")
   348 						toPathParent = path.translate(toPathParent, "/"):gsub("/", "\\\\")
   349 						copyCommand = "copy"
   350 						destCheck = "if not exist \\\"" .. toPathParent .. "\\\" ( mkdir \\\"" .. toPathParent .. "\\\" )"
   351 					else
   352 						fromPath = path.translate(fromPath, nil):gsub("\\", "/")
   353 						toPath = path.translate(toPath, nil):gsub("\\", "/")
   354 					end
   355 					-- command will check for destination directory to exist and, if it doesn't,
   356 					-- it will make the directory and then copy over any assets
   357 					local quotedFromPath = fromPath
   358 					if SDL_getos() == "windows" or fromPath:find("*") == nil then
   359 						quotedFromPath = '\\"' .. quotedFromPath .. '\\"'
   360 					end
   361 					table.insert(dbgPostbuildcommands, destCheck)
   362 					table.insert(dbgPostbuildcommands,
   363 						copyCommand .. " " ..
   364 						quotedFromPath .. " \\\"" ..
   365 						toPath .. "\\\"")
   366 				end
   367 				for k,file in pairs(relCopyTable) do
   368 					-- all copies should be relative to project location, based on platform
   369 					local relLocation = "./"
   370 					relLocation = proj.location
   371 					local fromPath = "./" .. path.getrelative(relLocation, file.src)
   372 					local toPath = "./" .. path.getrelative(relLocation, file.dst)
   373 					local toPathParent = path.getdirectory(toPath)
   374 					local copyCommand = "cp"
   375 					local destCheck = "if [ ! -d \\\"" .. toPathParent .. "\\\" ]; then mkdir -p \\\"" .. toPathParent .. "\\\"; fi"
   376 					if SDL_getos() ~= "windows" and fromPath:find("*") ~= nil then
   377 						-- to path must be a directory for * copies
   378 						toPath = path.getdirectory(toPath)
   379 					end
   380 					if SDL_getos() == "windows" then
   381 						fromPath = path.translate(fromPath, "/"):gsub("/", "\\\\")
   382 						toPath = path.translate(toPath, "/"):gsub("/", "\\\\")
   383 						toPathParent = path.translate(toPathParent, "/"):gsub("/", "\\\\")
   384 						copyCommand = "copy"
   385 						destCheck = "if not exist \\\"" .. toPathParent .. "\\\" ( mkdir \\\"" .. toPathParent .. "\\\" )"
   386 					else
   387 						fromPath = path.translate(fromPath, nil):gsub("\\", "/")
   388 						toPath = path.translate(toPath, nil):gsub("\\", "/")
   389 					end
   390 					-- command will check for destination directory to exist and, if it doesn't,
   391 					-- it will make the directory and then copy over any assets
   392 					local quotedFromPath = fromPath
   393 					if SDL_getos() == "windows" or fromPath:find("*") == nil then
   394 						quotedFromPath = '\\"' .. quotedFromPath .. '\\"'
   395 					end
   396 					table.insert(relPostbuildcommands, destCheck)
   397 					table.insert(relPostbuildcommands,
   398 						copyCommand .. " " ..
   399 						quotedFromPath .. " \\\"" ..
   400 						toPath .. "\\\"")
   401 				end
   402 				debugConfig.postbuildcommands = dbgPostbuildcommands
   403 				debugConfig.links = links
   404 				releaseConfig.postbuildcommands = relPostbuildcommands
   405 				releaseConfig.links = links -- release links?
   406 				for i,d in pairs(p.dependencyTree) do
   407 					if d.includes then
   408 						for k,v in pairs(d.includes) do
   409 							local propPath = v:gsub("\\", "/")
   410 							proj.includedirs[propPath] = propPath
   411 						end
   412 					end
   413 					if d.libs then
   414 						for k,v in pairs(d.libs) do
   415 							local propPath = v:gsub("\\", "/")
   416 							proj.libdirs[propPath] = propPath
   417 						end
   418 					end
   419 					if d.links then
   420 						for k,v in pairs(d.links) do
   421 							local propPath = v:gsub("\\", "/")
   422 							debugConfig.links[#debugConfig.links + 1] = propPath
   423 						end
   424 					end
   425 				end
   426 				if #proj.files > 0 then
   427 					file:print(1, 'project "' .. p.name .. '"')
   428 					file:print(2, 'targetname "' .. p.name .. '"')
   429 					-- note: commented out because I think this hack is unnecessary
   430 					--if iOSMode and p.kind == "ConsoleApp" then
   431 						-- hack for iOS where we cannot build "tools"/ConsoleApps in
   432 						-- Xcode for iOS, so we convert them over to WindowedApps
   433 					--	p.kind = "WindowedApp"
   434 					--end
   435 					file:print(2, 'kind "' .. p.kind .. '"')
   436 					file:print(2, 'language "' .. p.language .. '"')
   437 					file:print(2, 'location "' .. proj.location .. '"')
   438 					file:print(2, 'flags { "NoExceptions" }') -- NoRTTI
   439 					file:print(2, 'buildoptions { }')--"/GS-" }')
   440 					file:print(2, implode(proj.includedirs, 'includedirs {', '"', '"', ', ', '}'))
   441 					file:print(2, implode(proj.libdirs, 'libdirs {', '"', '"', ', ', '}'))
   442 					file:print(2, implode(proj.files, 'files {', '"', '"', ', ', '}'))
   443 					-- debug configuration
   444 					file:print(2, 'configuration "Debug"')
   445 					file:print(3, 'targetdir "' .. debugConfig.targetdir .. '"')
   446 					-- debug dir is relative to the solution's location
   447 					file:print(3, 'debugdir "' .. debugConfig.targetdir .. '"')
   448 					file:print(3, implode(debugConfig.defines, 'defines {', '"', '"', ', ', '}'))
   449 					file:print(3, implode(debugConfig.links, "links {", '"', '"', ', ', "}"))
   450 					if SDL_getos() == "mingw" then
   451 						-- static runtime
   452 						file:print(3, 'linkoptions { "-lmingw32 -static-libgcc" }')
   453 					end
   454 					if SDL_getos() == "cygwin" then
   455 						file:print(3, 'linkoptions { "-static-libgcc" }')
   456 					end
   457 					file:print(3, implode(debugConfig.flags, "flags {", '"', '"', ', ', "}"))
   458 					file:print(3, implode(debugConfig.postbuildcommands, "postbuildcommands {", '"', '"', ', ', "}"))
   459 					-- release configuration
   460 					file:print(2, 'configuration "Release"')
   461 					file:print(3, 'targetdir "' .. releaseConfig.targetdir .. '"')
   462 					-- debug dir is relative to the solution's location
   463 					file:print(3, 'debugdir "' .. releaseConfig.targetdir .. '"')
   464 					file:print(3, implode(releaseConfig.defines, 'defines {', '"', '"', ', ', '}'))
   465 					file:print(3, implode(releaseConfig.links, "links {", '"', '"', ', ', "}"))
   466 					if SDL_getos() == "mingw" then
   467 						-- static runtime
   468 						file:print(3, 'linkoptions { "-lmingw32 -static-libgcc" }')
   469 					end
   470 					file:print(3, implode(releaseConfig.flags, "flags {", '"', '"', ', ', "}"))
   471 					file:print(3, implode(releaseConfig.postbuildcommands, "postbuildcommands {", '"', '"', ', ', "}"))
   472 				end -- end check for valid project (files to build)
   473 			end -- end compatibility check for projects
   474 		end -- end for loop for projects
   475 
   476 	endGeneration() -- finish generating the config header file
   477 	file:close()
   478 
   479 	-- generation is over, now execute the generated file, setup the premake
   480 	-- solution, and let premake execute the action and generate the project files
   481 	dofile(genFile)
   482 end -- end check for not being in help mode