mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-16 11:06:49 +01:00
3dcb451f85
To note, this file is currently formatted with CRLF line endings, rather than LF, to allow the file to be viewed with Notepad.
483 lines
19 KiB
Lua
Executable File
483 lines
19 KiB
Lua
Executable File
-- Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
|
--
|
|
-- This software is provided 'as-is', without any express or implied
|
|
-- warranty. In no event will the authors be held liable for any damages
|
|
-- arising from the use of this software.
|
|
--
|
|
-- Permission is granted to anyone to use this software for any purpose,
|
|
-- including commercial applications, and to alter it and redistribute it
|
|
-- freely.
|
|
--
|
|
-- Meta-build system using premake created and maintained by
|
|
-- Benjamin Henning <b.henning@digipen.edu>
|
|
|
|
--[[
|
|
premake4.lua
|
|
|
|
This script sets up the entire premake system. It's responsible for executing
|
|
all of the definition scripts for the SDL2 library and the entire test suite,
|
|
or demos for the iOS platform. It handles each specific platform and uses the
|
|
setup state to generate both the configuration header file needed to build
|
|
SDL2 and the premake lua script to generate the target project files.
|
|
]]
|
|
|
|
-- string utility functions
|
|
dofile "util/sdl_string.lua"
|
|
-- utility file wrapper for some useful functions
|
|
dofile "util/sdl_file.lua"
|
|
-- system for defining SDL projects
|
|
dofile "util/sdl_projects.lua"
|
|
-- offers a utility function for finding dependencies specifically on windows
|
|
dofile "util/sdl_depends.lua"
|
|
-- system for generating a *config.h file used to build the SDL2 library
|
|
dofile "util/sdl_gen_config.lua"
|
|
-- functions to handle complicated dependency checks using CMake-esque functions
|
|
dofile "util/sdl_check_compile.lua"
|
|
-- a list of dependency functions for the SDL2 project and any other projects
|
|
dofile "util/sdl_dependency_checkers.lua"
|
|
|
|
-- the following are various options for configuring the meta-build system
|
|
newoption {
|
|
trigger = "to",
|
|
value = "path",
|
|
description = "Set the base output directory for the generated and executed lua file."
|
|
}
|
|
|
|
newoption {
|
|
trigger = "mingw",
|
|
description = "Runs the premake generation script targeted to MinGW."
|
|
}
|
|
|
|
newoption {
|
|
trigger = "cygwin",
|
|
description = "Runs the premake generation script targeted to Cygwin."
|
|
}
|
|
|
|
newoption {
|
|
trigger = "ios",
|
|
description = "Runs the premake generation script targeted to iOS."
|
|
}
|
|
|
|
-- determine the localized destination path
|
|
local baseLoc = "./"
|
|
if _OPTIONS["to"] then
|
|
baseLoc = _OPTIONS["to"]:gsub("\\", "/")
|
|
end
|
|
|
|
local deps = SDL_getDependencies()
|
|
for _,v in ipairs(deps) do
|
|
newoption {
|
|
trigger = v:lower(),
|
|
description = "Force on the dependency: " .. v
|
|
}
|
|
end
|
|
|
|
-- clean action
|
|
if _ACTION == "clean" then
|
|
-- this is kept the way it is because premake's default method of cleaning the
|
|
-- build tree is not very good standalone, whereas the following correctly
|
|
-- cleans every build option
|
|
print("Cleaning the build environment...")
|
|
os.rmdir(baseLoc .. "/SDL2")
|
|
os.rmdir(baseLoc .. "/SDL2main")
|
|
os.rmdir(baseLoc .. "/SDL2test")
|
|
os.rmdir(baseLoc .. "/tests")
|
|
os.rmdir(baseLoc .. "/Demos")
|
|
os.rmdir(baseLoc .. "/ipch") -- sometimes shows up
|
|
os.remove(baseLoc .. "/SDL.sln")
|
|
os.remove(baseLoc .. "/SDL.suo")
|
|
os.remove(baseLoc .. "/SDL.v11.suo")
|
|
os.remove(baseLoc .. "/SDL.sdf")
|
|
os.remove(baseLoc .. "/SDL.ncb")
|
|
os.remove(baseLoc .. "/SDL-gen.lua")
|
|
os.remove(baseLoc .. "/SDL_config_premake.h")
|
|
os.remove(baseLoc .. "/Makefile")
|
|
os.rmdir(baseLoc .. "/SDL.xcworkspace")
|
|
os.exit()
|
|
end
|
|
|
|
-- only run through standard execution if not in help mode
|
|
if _OPTIONS["help"] == nil then
|
|
-- load all of the project definitions
|
|
local results = os.matchfiles("projects/**.lua")
|
|
for _,dir in ipairs(results) do
|
|
dofile(dir)
|
|
end
|
|
|
|
-- figure out which configuration template to use
|
|
local premakeConfigHeader = baseLoc .. "/SDL_config_premake.h"
|
|
-- minimal configuration is the default
|
|
local premakeTemplateHeader = "./config/SDL_config_minimal.template.h"
|
|
if SDL_getos() == "windows" or SDL_getos() == "mingw" then
|
|
premakeTemplateHeader = "./config/SDL_config_windows.template.h"
|
|
elseif SDL_getos() == "macosx" then
|
|
premakeTemplateHeader = "./config/SDL_config_macosx.template.h"
|
|
elseif SDL_getos() == "ios" then
|
|
premakeTemplateHeader = "./config/SDL_config_iphoneos.template.h"
|
|
elseif os.get() == "linux" then
|
|
premakeTemplateHeader = "./config/SDL_config_linux.template.h"
|
|
elseif SDL_getos() == "cygwin" then
|
|
premakeTemplateHeader = "./config/SDL_config_cygwin.template.h"
|
|
end
|
|
|
|
local genFile = baseLoc .. "/SDL-gen.lua"
|
|
local file = fileopen(genFile, "wt")
|
|
print("Generating " .. genFile .. "...")
|
|
-- begin generating the config header file
|
|
startGeneration(premakeConfigHeader, premakeTemplateHeader)
|
|
|
|
-- begin generating the actual premake script
|
|
file:print(0, "-- Premake script generated by Simple DirectMedia Layer meta-build script")
|
|
file:print(1, 'solution "SDL"')
|
|
local platforms = { }
|
|
local platformsIndexed = { }
|
|
for n,p in pairs(projects) do
|
|
if p.platforms and #p.platforms ~= 0 then
|
|
for k,v in pairs(p.platforms) do
|
|
platforms[v] = true
|
|
end
|
|
end
|
|
end
|
|
for n,v in pairs(platforms) do
|
|
platformsIndexed[#platformsIndexed + 1] = n
|
|
end
|
|
file:print(2, implode(platformsIndexed, 'platforms {', '"', '"', ', ', '}'))
|
|
file:print(2, 'configurations { "Debug", "Release" }')
|
|
for n,p in pairs(projects) do
|
|
if p.compat then
|
|
local proj = {}
|
|
if p.projectLocation ~= nil then
|
|
proj.location = p.projectLocation .. "/" .. p.name
|
|
else
|
|
proj.location = p.name .. "/"
|
|
end
|
|
proj.includedirs = { path.getrelative(baseLoc,
|
|
path.getdirectory(premakeConfigHeader)),
|
|
path.getrelative(baseLoc, "../include") }
|
|
proj.libdirs = { }
|
|
proj.files = { }
|
|
local links = { }
|
|
local dbgCopyTable = { }
|
|
local relCopyTable = { }
|
|
-- custom links that shouldn't exist...
|
|
-- (these should always happen before dependencies)
|
|
if p.customLinks ~= nil then
|
|
for k,lnk in pairs(p.customLinks) do
|
|
table.insert(links, lnk)
|
|
end
|
|
end
|
|
-- setup project dependencies
|
|
local dependencyLocs = { }
|
|
if p.projectDependencies ~= nil and #p.projectDependencies ~= 0 then
|
|
for k,projname in pairs(p.projectDependencies) do
|
|
local depproj = projects[projname]
|
|
-- validation that it exists and can be linked to
|
|
if depproj ~= nil and (depproj.kind == "SharedLib" or depproj.kind == "StaticLib") then
|
|
if depproj.kind == "SharedLib" then
|
|
local deplocation = nil
|
|
if depproj.projectLocation ~= nil then
|
|
deplocation = depproj.projectLocation .. "/" .. p.name
|
|
else
|
|
deplocation = depproj.name .. "/"
|
|
end
|
|
table.insert(dependencyLocs, { location = deplocation, name = projname })
|
|
else -- static lib
|
|
-- we are now dependent on everything the static lib is dependent on
|
|
if depproj.customLinks ~= nil then
|
|
for k,lnk in pairs(depproj.customLinks) do
|
|
table.insert(links, lnk)
|
|
end
|
|
end
|
|
-- also include links from dependencies
|
|
for i,d in pairs(depproj.dependencyTree) do
|
|
if d.links then
|
|
for k,v in pairs(d.links) do
|
|
local propPath = v:gsub("\\", "/")
|
|
table.insert(links, propPath)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- finally, depend on the project itself
|
|
table.insert(links, projname)
|
|
elseif depproj == nil then
|
|
print("Warning: Missing external dependency for project: ".. p.name ..
|
|
". Be sure you setup project dependencies in a logical order.")
|
|
else
|
|
print("Warning: Cannot link " .. p.name .. " to second project " ..
|
|
projname .. " because the second project is not a library.")
|
|
end
|
|
end
|
|
end
|
|
-- iterate across all root directories, matching source directories
|
|
local dirs = createDirTable(p.sourcedir)
|
|
-- but first, handle any files specifically set in the project, rather than
|
|
-- its dependencies
|
|
-- register c and h files in this directory
|
|
if (p.files ~= nil and #p.files ~= 0) or (p.paths ~= nil and #p.paths ~= 0) then
|
|
-- handle all lists of files
|
|
if p.files ~= nil and #p.files ~= 0 then
|
|
for k,filepat in pairs(p.files) do
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat)) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
end
|
|
end -- end props files if
|
|
-- add all .c/.h files from each path
|
|
-- handle all related paths
|
|
if p.paths ~= nil and #p.paths ~= 0 then
|
|
for j,filepat in ipairs(p.paths) do
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.c")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.h")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
-- mac osx
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.m")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
end
|
|
end -- end of props paths if
|
|
end -- end of check for files/paths in main project
|
|
-- if this project has any configuration flags, add them to the current file
|
|
if p.config then
|
|
addConfig(p.config)
|
|
end
|
|
-- now, handle files and paths for dependencies
|
|
for i,props in ipairs(p.dependencyTree) do
|
|
if props.compat then
|
|
-- register c and h files in this directory
|
|
-- handle all lists of files
|
|
if props.files ~= nil and #props.files ~= 0 then
|
|
for k,filepat in pairs(props.files) do
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat)) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
end
|
|
end -- end props files if
|
|
-- add all .c/.h files from each path
|
|
-- handle all related paths
|
|
if props.paths ~= nil and #props.paths ~= 0 then
|
|
for j,filepat in ipairs(props.paths) do
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.c")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.h")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
-- mac osx
|
|
for k,f in pairs(os.matchfiles(p.sourcedir .. filepat .. "*.m")) do
|
|
table.insert(proj.files, path.getrelative(baseLoc, f))
|
|
end
|
|
end
|
|
end -- end of props paths if
|
|
-- if this dependency has any special configuration flags, add 'em
|
|
if props.config then
|
|
addConfig(props.config)
|
|
end -- end of props config if check
|
|
end -- end check for compatibility
|
|
end -- end of props loop
|
|
--local debugConfig = configuration("Debug")
|
|
local debugConfig = {}
|
|
local releaseConfig = {}
|
|
debugConfig.defines = { "USING_PREMAKE_CONFIG_H", "_DEBUG" }
|
|
releaseConfig.defines = { "USING_PREMAKE_CONFIG_H", "NDEBUG" }
|
|
-- setup per-project defines
|
|
if p.defines ~= nil then
|
|
for k,def in pairs(p.defines) do
|
|
table.insert(debugConfig.defines, def)
|
|
table.insert(releaseConfig.defines, def)
|
|
end
|
|
end
|
|
debugConfig.buildoptions = { }
|
|
if SDL_getos() == "windows" then
|
|
table.insert(debugConfig.buildoptions, "/MDd")
|
|
end
|
|
debugConfig.linkoptions = { }
|
|
releaseConfig.buildoptions = {}
|
|
releaseConfig.linkoptions = {}
|
|
local baseBuildDir = "/Build"
|
|
if os.get() == "windows" then
|
|
baseBuildDir = "/Win32"
|
|
end
|
|
debugConfig.flags = { "Symbols" }
|
|
debugConfig.targetdir = proj.location .. baseBuildDir .. "/Debug"
|
|
releaseConfig.flags = { "OptimizeSpeed" }
|
|
releaseConfig.targetdir = proj.location .. baseBuildDir .. "/Release"
|
|
-- setup postbuild options
|
|
local dbgPostbuildcommands = { }
|
|
local relPostbuildcommands = { }
|
|
-- handle copying depended shared libraries to correct folders
|
|
if os.get() == "windows" then
|
|
for k,deploc in pairs(dependencyLocs) do
|
|
table.insert(dbgCopyTable, { src = deploc.location .. baseBuildDir .. "/Debug/" .. deploc.name .. ".dll",
|
|
dst = debugConfig.targetdir .. "/" .. deploc.name .. ".dll" })
|
|
table.insert(relCopyTable, { src = deploc.location .. baseBuildDir .. "/Release/" .. deploc.name .. ".dll",
|
|
dst = releaseConfig.targetdir .. "/" .. deploc.name .. ".dll" })
|
|
end
|
|
end
|
|
if p.copy ~= nil then
|
|
for k,file in pairs(p.copy) do
|
|
-- the following builds relative paths native to the current system for copying, other
|
|
-- than the copy command itself, this is essentially cross-platform for paths
|
|
|
|
-- all custom copies should be relative to the current working directory
|
|
table.insert(dbgCopyTable, { src = path.getrelative(baseLoc, p.sourcedir .. "/" .. file), dst = debugConfig.targetdir .. "/" .. file })
|
|
table.insert(relCopyTable, { src = path.getrelative(baseLoc, p.sourcedir .. "/" .. file), dst = releaseConfig.targetdir .. "/" .. file })
|
|
end
|
|
end
|
|
for k,file in pairs(dbgCopyTable) do
|
|
-- all copies should be relative to project location, based on platform
|
|
local relLocation = "./"
|
|
--if os.get() == "windows" then
|
|
relLocation = proj.location
|
|
--end
|
|
local fromPath = "./" .. path.getrelative(relLocation, file.src)
|
|
local toPath = "./" .. path.getrelative(relLocation, file.dst)
|
|
local toPathParent = path.getdirectory(toPath)
|
|
local copyCommand = "cp"
|
|
local destCheck = "if [ ! -d \\\"" .. toPathParent .. "\\\" ]; then mkdir -p \\\"" .. toPathParent .. "\\\"; fi"
|
|
if SDL_getos() ~= "windows" and fromPath:find("*") ~= nil then
|
|
-- to path must be a directory for * copies
|
|
toPath = path.getdirectory(toPath)
|
|
end
|
|
if SDL_getos() == "windows" then
|
|
fromPath = path.translate(fromPath, "/"):gsub("/", "\\\\")
|
|
toPath = path.translate(toPath, "/"):gsub("/", "\\\\")
|
|
toPathParent = path.translate(toPathParent, "/"):gsub("/", "\\\\")
|
|
copyCommand = "copy"
|
|
destCheck = "if not exist \\\"" .. toPathParent .. "\\\" ( mkdir \\\"" .. toPathParent .. "\\\" )"
|
|
else
|
|
fromPath = path.translate(fromPath, nil):gsub("\\", "/")
|
|
toPath = path.translate(toPath, nil):gsub("\\", "/")
|
|
end
|
|
-- command will check for destination directory to exist and, if it doesn't,
|
|
-- it will make the directory and then copy over any assets
|
|
local quotedFromPath = fromPath
|
|
if SDL_getos() == "windows" or fromPath:find("*") == nil then
|
|
quotedFromPath = '\\"' .. quotedFromPath .. '\\"'
|
|
end
|
|
table.insert(dbgPostbuildcommands, destCheck)
|
|
table.insert(dbgPostbuildcommands,
|
|
copyCommand .. " " ..
|
|
quotedFromPath .. " \\\"" ..
|
|
toPath .. "\\\"")
|
|
end
|
|
for k,file in pairs(relCopyTable) do
|
|
-- all copies should be relative to project location, based on platform
|
|
local relLocation = "./"
|
|
relLocation = proj.location
|
|
local fromPath = "./" .. path.getrelative(relLocation, file.src)
|
|
local toPath = "./" .. path.getrelative(relLocation, file.dst)
|
|
local toPathParent = path.getdirectory(toPath)
|
|
local copyCommand = "cp"
|
|
local destCheck = "if [ ! -d \\\"" .. toPathParent .. "\\\" ]; then mkdir -p \\\"" .. toPathParent .. "\\\"; fi"
|
|
if SDL_getos() ~= "windows" and fromPath:find("*") ~= nil then
|
|
-- to path must be a directory for * copies
|
|
toPath = path.getdirectory(toPath)
|
|
end
|
|
if SDL_getos() == "windows" then
|
|
fromPath = path.translate(fromPath, "/"):gsub("/", "\\\\")
|
|
toPath = path.translate(toPath, "/"):gsub("/", "\\\\")
|
|
toPathParent = path.translate(toPathParent, "/"):gsub("/", "\\\\")
|
|
copyCommand = "copy"
|
|
destCheck = "if not exist \\\"" .. toPathParent .. "\\\" ( mkdir \\\"" .. toPathParent .. "\\\" )"
|
|
else
|
|
fromPath = path.translate(fromPath, nil):gsub("\\", "/")
|
|
toPath = path.translate(toPath, nil):gsub("\\", "/")
|
|
end
|
|
-- command will check for destination directory to exist and, if it doesn't,
|
|
-- it will make the directory and then copy over any assets
|
|
local quotedFromPath = fromPath
|
|
if SDL_getos() == "windows" or fromPath:find("*") == nil then
|
|
quotedFromPath = '\\"' .. quotedFromPath .. '\\"'
|
|
end
|
|
table.insert(relPostbuildcommands, destCheck)
|
|
table.insert(relPostbuildcommands,
|
|
copyCommand .. " " ..
|
|
quotedFromPath .. " \\\"" ..
|
|
toPath .. "\\\"")
|
|
end
|
|
debugConfig.postbuildcommands = dbgPostbuildcommands
|
|
debugConfig.links = links
|
|
releaseConfig.postbuildcommands = relPostbuildcommands
|
|
releaseConfig.links = links -- release links?
|
|
for i,d in pairs(p.dependencyTree) do
|
|
if d.includes then
|
|
for k,v in pairs(d.includes) do
|
|
local propPath = v:gsub("\\", "/")
|
|
proj.includedirs[propPath] = propPath
|
|
end
|
|
end
|
|
if d.libs then
|
|
for k,v in pairs(d.libs) do
|
|
local propPath = v:gsub("\\", "/")
|
|
proj.libdirs[propPath] = propPath
|
|
end
|
|
end
|
|
if d.links then
|
|
for k,v in pairs(d.links) do
|
|
local propPath = v:gsub("\\", "/")
|
|
debugConfig.links[#debugConfig.links + 1] = propPath
|
|
end
|
|
end
|
|
end
|
|
if #proj.files > 0 then
|
|
file:print(1, 'project "' .. p.name .. '"')
|
|
file:print(2, 'targetname "' .. p.name .. '"')
|
|
-- note: commented out because I think this hack is unnecessary
|
|
--if iOSMode and p.kind == "ConsoleApp" then
|
|
-- hack for iOS where we cannot build "tools"/ConsoleApps in
|
|
-- Xcode for iOS, so we convert them over to WindowedApps
|
|
-- p.kind = "WindowedApp"
|
|
--end
|
|
file:print(2, 'kind "' .. p.kind .. '"')
|
|
file:print(2, 'language "' .. p.language .. '"')
|
|
file:print(2, 'location "' .. proj.location .. '"')
|
|
file:print(2, 'flags { "NoExceptions" }') -- NoRTTI
|
|
file:print(2, 'buildoptions { }')--"/GS-" }')
|
|
file:print(2, implode(proj.includedirs, 'includedirs {', '"', '"', ', ', '}'))
|
|
file:print(2, implode(proj.libdirs, 'libdirs {', '"', '"', ', ', '}'))
|
|
file:print(2, implode(proj.files, 'files {', '"', '"', ', ', '}'))
|
|
-- debug configuration
|
|
file:print(2, 'configuration "Debug"')
|
|
file:print(3, 'targetdir "' .. debugConfig.targetdir .. '"')
|
|
-- debug dir is relative to the solution's location
|
|
file:print(3, 'debugdir "' .. debugConfig.targetdir .. '"')
|
|
file:print(3, implode(debugConfig.defines, 'defines {', '"', '"', ', ', '}'))
|
|
file:print(3, implode(debugConfig.links, "links {", '"', '"', ', ', "}"))
|
|
if SDL_getos() == "mingw" then
|
|
-- static runtime
|
|
file:print(3, 'linkoptions { "-lmingw32 -static-libgcc" }')
|
|
end
|
|
if SDL_getos() == "cygwin" then
|
|
file:print(3, 'linkoptions { "-static-libgcc" }')
|
|
end
|
|
file:print(3, implode(debugConfig.flags, "flags {", '"', '"', ', ', "}"))
|
|
file:print(3, implode(debugConfig.postbuildcommands, "postbuildcommands {", '"', '"', ', ', "}"))
|
|
-- release configuration
|
|
file:print(2, 'configuration "Release"')
|
|
file:print(3, 'targetdir "' .. releaseConfig.targetdir .. '"')
|
|
-- debug dir is relative to the solution's location
|
|
file:print(3, 'debugdir "' .. releaseConfig.targetdir .. '"')
|
|
file:print(3, implode(releaseConfig.defines, 'defines {', '"', '"', ', ', '}'))
|
|
file:print(3, implode(releaseConfig.links, "links {", '"', '"', ', ', "}"))
|
|
if SDL_getos() == "mingw" then
|
|
-- static runtime
|
|
file:print(3, 'linkoptions { "-lmingw32 -static-libgcc" }')
|
|
end
|
|
file:print(3, implode(releaseConfig.flags, "flags {", '"', '"', ', ', "}"))
|
|
file:print(3, implode(releaseConfig.postbuildcommands, "postbuildcommands {", '"', '"', ', ', "}"))
|
|
end -- end check for valid project (files to build)
|
|
end -- end compatibility check for projects
|
|
end -- end for loop for projects
|
|
|
|
endGeneration() -- finish generating the config header file
|
|
file:close()
|
|
|
|
-- generation is over, now execute the generated file, setup the premake
|
|
-- solution, and let premake execute the action and generate the project files
|
|
dofile(genFile)
|
|
end -- end check for not being in help mode
|