premake/premake4.lua
author Sam Lantinga <slouken@libsdl.org>
Fri, 28 Nov 2014 04:51:33 -0800
changeset 9246 a761913e5e91
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rwxr-xr-x
Fixed bug 2786 - "UCS-2-INTERNAL" iconv encoding is not supported everywhere, use UTF-16LE instead

Jonas Kulla

src/main/windows/SDL_windows_main.c:137:
cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));

I'm trying to compile an SDL2 application for windows using the mingw-w64 32bit toolchain provided by my distro (Fedora 19). However, even the simplest test program that does nothing at all fails to startup with a "Fatal error - out of memory" message because the mingw iconv library provided by my distro does not support the "UCS-2-INTERNAL" encoding and the conversion returns null.

From my little bit of research, it turns out that even though this encoding is supported by the external GNU libiconv library, some glibc versions (?) don't support it with their internal iconv routines, and will instead provide the native endian encoding when "UCS-2" is specified.

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