-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathPremake5.lua
405 lines (326 loc) · 12.9 KB
/
Premake5.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
-- Ontario Tech Teaching and Education Repository (OTTER) Framework
-- Shawn Matthews (Jan 1st, 2020)
-- This premake file sets up an easy to use framework for developing graphics applications, and allows easy addition
-- of other frameworks and libraries where required.
-- Originally named GOOP (Graphics with Object Oriented Programming), this project was renamed in 2020 to reflect it's
-- more general usage for other courses and concepts
-- This build config is inspired by the Hazel Engine build system (https://github.com/TheCherno/Hazel), as well as
-- David Arpe's CMAKE system
-- See the readme for more information
-- TODO:
-- Provide a system for modules to add resources or DLLs to the output projects
-- Determine the root directory where we are calling premake from (this is our working directory)
local rootDir = path.getabsolute(_WORKING_DIR)
-- Get all the directories in our projects directory
local projects = os.matchdirs(rootDir .. "/projects/*")
local modules = os.matchdirs(rootDir .. "/modules/*")
local sampleGroups = os.matchdirs(rootDir .. "/samples/*")
-- Select the last item in the project directory to be our startup project
-- (this is easily changed in VS, this is just to be handy)
if #projects > 0 then
startup = path.getbasename(projects[#projects])
else
startup = ""
end
-- This function concatenates two LUA tables, returning a new result
-- @param table1 The starting table
-- @param table2 The table to append to table1
-- @returns All elements in table1, followed by all elements in table2
function concat(table1, table2)
local result = {}
for ix=1, #table1 do
result[ix] = table1[ix]
end
for ix=1,#table2 do
result[#table1 + ix] = table2[ix]
end
return result
end
-- Log what the startup project will be
premake.info("Startup project: " .. startup)
-- This is our solution name
workspace "OTTER"
-- Processor architecture
architecture "x64"
-- Set which project to run on debug
startproject(startup)
-- Our configs are basically with and without compiler optimizations
configurations {
"Debug",
"Release"
}
-- The directory name for our output
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
group("Dependencies")
-- These are other dependency projects that we want to include in our solution (each needs their own premake)
include "dependencies/glfw3"
include "dependencies/glad"
include "dependencies/imgui"
include "dependencies/stbs"
include "dependencies/spdlog"
include "dependencies/tinyGLTF"
-- Add all the core dependencies to the project includes
-- We will reserve the first include directory for the project's source
-- We will append our module's include directories to this list
ProjIncludes = {
"RESERVED",
"dependencies/glfw3/include",
"dependencies/glad/include",
"dependencies/imgui",
"dependencies/GLM/include",
"dependencies/stbs",
"dependencies/fmod/include",
"dependencies/spdlog/include",
"dependencies/entt",
"dependencies/cereal",
"dependencies/gzip",
"dependencies/tinyGLTF",
"dependencies/json",
"dependencies/bullet3/include",
}
-- These are all the default dependencies that require linking
Dependencies = {
"GLFW",
"Glad",
"stbs",
"ImGui",
"opengl32.lib",
"imagehlp.lib",
"dependencies/gzip/zlib.lib",
"tinyGLTF",
}
DependenciesDebug = {
"dependencies/bullet3/lib/Bullet3Common_Debug.lib",
"dependencies/bullet3/lib/BulletCollision_Debug.lib",
"dependencies/bullet3/lib/BulletDynamics_Debug.lib",
"dependencies/bullet3/lib/BulletInverseDynamics_Debug.lib",
"dependencies/bullet3/lib/BulletSoftBody_Debug.lib",
"dependencies/bullet3/lib/LinearMath_Debug.lib",
"dependencies/fmod/lib/fmodstudioL_vc.lib",
"dependencies/fmod/lib/fmodL_vc.lib",
}
DependenciesRelease = {
"dependencies/bullet3/lib/Bullet3Common.lib",
"dependencies/bullet3/lib/BulletCollision.lib",
"dependencies/bullet3/lib/BulletDynamics.lib",
"dependencies/bullet3/lib/BulletInverseDynamics.lib",
"dependencies/bullet3/lib/BulletSoftBody.lib",
"dependencies/bullet3/lib/LinearMath.lib",
"dependencies/fmod/lib/fmodstudio_vc.lib",
"dependencies/fmod/lib/fmod_vc.lib",
}
-- These are what we are linking to (mostly other projects)
-- We keep it as a seperate list so we don't accidentally link modules together
-- We will append our modules to this list
ProjLinks = { }
for k, v in pairs(Dependencies) do ProjLinks[k] = v end
ProjDebugLinks = { }
for k, v in pairs(DependenciesDebug) do ProjDebugLinks[k] = v end
ProjReleaseLinks = { }
for k, v in pairs(DependenciesRelease) do ProjDebugLinks[k] = v end
-- This function handles creating the default project for a module, if no premake folder is given
-- @param folderName The path to the module, as collected from os.matchdirs
function CreateDefaultModule(folderName)
premake.info(" Adding module from: " .. folderName)
local projName = path.getname(folderName)
premake.info(" Selected module name: " .. projName)
-- We make a list of what to link against, since we don't want to modify Dependencies or the ProjLinks
local linkList = {}
for k, v in pairs(Dependencies) do table.insert(linkList, v) end
local linkListDebug = {}
for k, v in pairs(DependenciesDebug) do table.insert(linkListDebug, v) end
local linkListRelease = {}
for k, v in pairs(DependenciesRelease) do table.insert(linkListRelease, v) end
-- We'll look for any libs the module may have
local libs = os.matchfiles(folderName .. "/libs/*.lib")
premake.info(" Looking for libs at: " .. folderName .. "/libs/*.lib")
premake.info(" Found " .. #libs .. " libraries")
-- Iterate over libs and link them to this module, and against all the client projects
if #libs > 0 then
for k, v in pairs(libs) do
premake.info(" Adding lib to module: " .. v)
table.insert(linkList, path.getrelative(rootDir, v))
end
end
local relpath = path.getrelative(rootDir, folderName)
local srcdir = path.join(relpath, "src")
project(projName)
location(relpath)
kind "StaticLib"
language "C++"
cppdialect "C++17"
-- Sets RuntimLibrary to MultiThreaded (non DLL version for static linking)
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("obj/" .. outputdir .. "/%{prj.name}")
files {
"%{prj.location}\\src\\**.c",
"%{prj.location}\\src\\**.cpp",
"%{prj.location}\\include\\**.h",
"%{prj.location}\\include\\**.hpp"
}
-- Modules should only link to dependencies by default
links(linkList)
-- We update the reserved include directory to be the project's source directory
ProjIncludes[1] = path.join(relpath, "include")
-- Defines what directories we want to include
includedirs(ProjIncludes)
configuration "vs"
buildoptions { "/bigobj" }
filter "system:windows"
systemversion "latest"
defines {
"WINDOWS",
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
links(linkListDebug)
filter "configurations:Release"
runtime "Release"
optimize "on"
links(linkListRelease)
end
-- Executes an xcopy command to copy all newer files from one folder to another
function CopyFolder(sourcePath, destPath)
os.execute("xcopy /Q /E /Y /I /C \"" .. sourcePath .. "\" \"" .. destPath .. "\"")
end
if not os.isdir(path.join(rootDir, "shared_assets")) then
os.mkdir(path.join(rootDir, "shared_assets"))
end
if not os.isdir(path.join(rootDir, "shared_assets", "dll")) then
os.mkdir(path.join(rootDir, "shared_assets", "dll"))
end
if not os.isdir(path.join(rootDir, "shared_assets", "res")) then
os.mkdir(path.join(rootDir, "shared_assets", "res"))
end
-- Generate the modules
group("Modules")
for k, v in pairs(modules) do
-- We will use the relative path for including in premake
vRel = path.getrelative(rootDir, v)
premake.info("Adding module: " .. vRel)
-- If there is a premake file for the module, we will use it
if os.isfile(path.join(vRel, "premake.lua")) or os.isfile(path.join(vRel, "premake5.lua")) then
include(vRel)
-- Otherwise we will generate one for the module
elseif (os.isdir(path.join(vRel, "src"))) or (os.isdir(path.join(vRel, "libs"))) then
premake.info(" Generating project for module: " .. vRel)
CreateDefaultModule(v)
end
-- If the module has a dll folder, copy it over into the shared assets
if os.isdir(path.join(vRel, "dll")) then
premake.info(" Copying module dlls to shared_assets")
local sourcePath = path.join(vRel, "dll")
local destPath = path.join(rootDir, "shared_assets", "dll")
CopyFolder(sourcePath, destPath)
end
-- If the module has a res folder, copy it over into the shared assets
if os.isdir(path.join(vRel, "res")) then
premake.info(" Copying module resources to shared_assets")
local sourcePath = path.join(vRel, "res")
local destPath = path.join(rootDir, "shared_assets", "res")
CopyFolder(sourcePath, destPath)
end
-- Add the module to the list of projects to link
table.insert(ProjLinks, path.getbasename(vRel))
end
-- We'll add the include directories for all modules after they have been generated (so that we can use ProjIncludes in module generation)
for k, v in pairs(modules) do
table.insert(ProjIncludes, path.join(v, "include"))
end
-- This function will create projects for all the paths in a table, and set the group name to the given value
-- @param groupName The name to group the projects under in the workspace
-- @param folders The table of folders that contain the projects to add
function AddProjects(groupName, folders)
premake.info("Building Group: " .. groupName)
group(groupName)
-- Iterate over all the projects (k is the index)
for k, proj in pairs(folders) do
-- Extract the project name
local name = path.getbasename(proj)
-- Extract a relative path for the project
local relpath = path.getrelative(rootDir, proj)
-- Log the project in the console
premake.info(" Adding project: " .. name)
premake.info(" Source: " .. relpath)
-- Add project to the solution
project(name)
-- Root folder of the project
location(relpath)
-- Output type of the project
kind "ConsoleApp"
-- Language (we are using MSVC)
language "C++"
-- C++ version (we are using the c++17 standard)
cppdialect "C++17"
-- Sets RuntimLibrary to MultiThreaded (non DLL version for static linking)
staticruntime "on"
-- This is where we will output our compiled program
targetdir ("%{wks.location}\\bin\\" .. outputdir .. "\\%{prj.name}")
-- This is where we will output our intermediate files
objdir ("%{wks.location}\\obj\\" .. outputdir .. "\\%{prj.name}")
-- Set the debug working directory to the output directory
debugdir ("%{wks.location}bin\\%{outputdir}\\%{prj.name}")
-- Gets the absolute directory of the current project
absdir = "%{wks.location}bin\\%{outputdir}\\%{prj.name}"
-- Gets our project's resource file location
resdir = "%{prj.location}res"
-- Gets the location of the project's source code
local srcdir = path.join(relpath, "src")
-- These are the commands that get executed after build, but before debugging
postbuildcommands {
-- This step copies over anything in the dll folder to the output directory
"(xcopy /Q /E /Y /I /C \"%{wks.location}shared_assets\\dll\" \"%{absdir}\")",
"(xcopy /Q /E /Y /I /C \"%{wks.location}dependencies\\dll\" \"%{absdir}\")",
-- This step ensures that the project has a resource directory
"(IF NOT EXIST \"%{resdir}\" mkdir \"%{resdir}\")",
"(xcopy /Q /E /Y /I /C \"%{wks.location}shared_assets\\res\" \"%{absdir}\")",
-- This step copies all the resources to the output directory
"(xcopy /Q /E /Y /I /C \"%{resdir}\" \"%{absdir}\")"
}
-- Our source files are everything in the src folder
files {
"%{prj.location}\\src\\**.h",
"%{prj.location}\\src\\**.cpp",
"%{prj.location}\\src\\**.c",
"%{prj.location}\\src\\**.hpp"
}
-- Disable CRT secure warnings
defines {
"_CRT_SECURE_NO_WARNINGS"
}
-- We update the reserved include directory to be the project's source directory
ProjIncludes[1] = srcdir
-- Defines what directories we want to include
includedirs(ProjIncludes)
-- Link to the dependencies and modules
links(ProjLinks)
buildoptions { "/bigobj" }
-- This filters for our windows builds
filter "system:windows"
systemversion "latest"
-- Set some defines for the windows builds
defines {
"GLFW_INCLUDE_NONE",
"WINDOWS"
}
-- Filters for our debug configurations
filter "configurations:Debug"
runtime "Debug"
symbols "on"
links(ProjLinksDebug)
-- Filters for release configuration
filter "configurations:Release"
runtime "Release"
optimize "on"
links(ProjLinksRelease)
end
end
-- Add the User Projects and Sample Projects
AddProjects("Projects", projects)
for k, proj in pairs(sampleGroups) do
local name = path.getbasename(proj);
local samples = os.matchdirs(proj .. "/*")
AddProjects("Samples - " .. name, samples)
end