cnq3/build/premake5.lua

707 lines
16 KiB
Lua

--[[
There are only 2 build toolchains supported:
- Visual C++ on Windows
- GCC on Linux
@TODO: prevent UNICODE and _UNICODE from being #define'd with premake
@TODO: enable Minimal Rebuild from premake (instead of adding /Gm)
--]]
newoption
{
trigger = "quake3dir",
description = "Quake 3 directory path, used for copying the binaries and running the debugger"
}
if not _OPTIONS["quake3dir"] then
error "quake3dir must be specified on the command-line"
end
-- relative to the LUA script
path_root = "../.."
path_src = path_root.."/cnq3/code"
path_build = path_root.."/cnq3/build"
path_bin = path_root.."/.bin"
-- relative to the makefile
make_path_git_scripts = ".."
make_path_git_header = "../../code/qcommon/git.h"
make_path_bin = "../../../.bin"
-- the only absolute path we allow
abs_path_q3 = path.getabsolute(_OPTIONS["quake3dir"]) -- os.realpath won't work if we pass in an env. var. here
extra_warnings = 1
local function GetBinDirName()
return "%{cfg.buildcfg}_%{cfg.platform}"
end
local function CreateGitPreBuildCommand(scriptExtension)
local make_path_script = string.format("%s/create_git_header%s", make_path_git_scripts, scriptExtension)
return string.format("\"%s\" \"%s\"", make_path_script, make_path_git_header)
end
local function CreateExeCopyPostBuildCommand(copyCommand, exeName, exeExtension)
local make_path_exe = string.format("%s/%s/%s%s", make_path_bin, GetBinDirName(), exeName, exeExtension)
return string.format("%s \"%s\" \"%s\"", copyCommand, make_path_exe, abs_path_q3)
end
local function WIN_CreatePdbCopyPostBuildCommand(exeName)
local make_path_pdb = string.format("%s/%s/%s.pdb", make_path_bin, GetBinDirName(), exeName)
return string.format("copy \"%s\" \"%s\"", make_path_pdb, abs_path_q3)
end
local function SetTargetAndLink(dirPath)
targetdir(dirPath)
libdirs(dirPath)
end
local function AddSourcesAndHeaders(dirPath)
files
{
path_src.."/"..dirPath.."/*.cpp",
path_src.."/"..dirPath.."/*.c",
path_src.."/"..dirPath.."/*.h",
}
end
local function AddSources(dirPath)
files
{
path_src.."/"..dirPath.."/*.cpp",
path_src.."/"..dirPath.."/*.c"
}
end
local function AddHeaders(dirPath)
files { path_src.."/"..dirPath.."/*.h" }
end
local function AddSourcesFromArray(dir, sourceFiles)
for idx,path in pairs(sourceFiles) do
files { string.format("%s/%s/%s", path_src, dir, path) }
end
end
local function AddAssemblerSourcesFromArray(dir, fileNames)
for idx,path in pairs(fileNames) do
files { string.format("%s/%s/%s.asm", path_src, dir, path) }
end
end
local function GetMakePath(premakePath)
return "../"..premakePath
end
-- premake tokens for this script:
-- cfg.buildcfg -> "debug", "release"
-- cfg.architecture -> "x86", "x86_64"
-- cfg.system -> "windows", "linux"
-- cfg.platform -> "x32", "x64"
local function GetLibJpegTurboNasmFlags()
libjpeg_turbo_nasm_flags_map =
{
windows_x32 = "-fwin32 -DWIN32",
windows_x64 = "-fwin64 -DWIN64 -D__x86_64__",
linux_x32 = "-felf32 -DELF",
linux_x64 = "-felf64 -DELF -D__x86_64__"
}
return "%{libjpeg_turbo_nasm_flags_map[cfg.system..\"_\"..cfg.platform]}"
end
local function GetCompilerObjectExtension()
if _ACTION == "gmake" then
return ".o"
end
return ".obj"
end
local function GetExeNameSuffix()
platform_exe_name_suffix_map =
{
x32 = "-x86",
x64 = "-x64"
}
return "%{platform_exe_name_suffix_map[cfg.platform]}"
end
local function ApplyProjectSettings()
--
-- General
--
filter { }
location ( path_build.."/".._ACTION )
rtti "Off"
exceptionhandling "Off"
flags { "NoPCH", "StaticRuntime", "NoManifest", "NoNativeWChar" }
filter "configurations:debug"
defines { "DEBUG", "_DEBUG" }
flags { }
filter "configurations:release"
defines { "NDEBUG" }
flags -- others: NoIncrementalLink NoCopyLocal NoImplicitLink NoBufferSecurityChecks
{
"NoMinimalRebuild",
"OptimizeSize",
"NoFramePointer",
"EnableSSE2",
"FloatFast",
"MultiProcessorCompile",
"NoRuntimeChecks"
}
-- Build directories
filter { }
SetTargetAndLink ( string.format("%s/%s", path_bin, GetBinDirName()) )
--
-- Visual C++
--
-- Some build options:
-- /GT => Support Fiber-Safe Thread-Local Storage
-- /GS- => Buffer Security Check disabled
-- /GL => Whole Program Optimization
-- /Zi => Debug info, but not for edit and continue
-- /Os => Favor size over speed
-- /Gm => Enable Minimal Rebuild
filter "action:vs*"
symbols "On"
editandcontinue "Off"
defines { "_CRT_SECURE_NO_WARNINGS", "WIN32", "_WIN32" }
if extra_warnings == 1 then
flags { "ExtraWarnings" }
end
filter { "action:vs*", "kind:WindowedApp" }
flags { "WinMain" }
filter { "action:vs*", "configurations:debug" }
buildoptions { "/Gm" }
linkoptions { "" }
filter { "action:vs*", "configurations:release" }
flags { "LinkTimeOptimization" } -- I had no success with GCC's -flto
buildoptions { "/GL" }
linkoptions { "" }
-- disable the "conversion from 'X' to 'Y', possible loss of data" warning
-- this should be removed once the x64 port is complete
filter { "action:vs*", "platforms:x64" }
buildoptions { "/wd4267" }
--
-- GCC
--
-- "-g1" is the minimum amount of debug information
-- it should be just enough to get a symbolic stack trace
filter "action:gmake"
symbols "On"
buildoptions { "-Wno-unused-parameter -Wno-write-strings" }
linkoptions { "" }
filter { "action:gmake", "configurations:rebug" }
buildoptions { "" }
linkoptions { "" }
filter { "action:gmake", "configurations:release" }
buildoptions { "-g1" }
linkoptions { "" }
end
local function ApplyLibProjectSettings()
ApplyProjectSettings()
end
local function ApplyExeProjectSettings(exeName, server)
ApplyProjectSettings()
filter { }
exeName = exeName..GetExeNameSuffix()
targetname(exeName)
local server_sources =
{
"qcommon/cmd.cpp",
"qcommon/cm_load.cpp",
"qcommon/cm_patch.cpp",
"qcommon/cm_polylib.cpp",
"qcommon/cm_test.cpp",
"qcommon/cm_trace.cpp",
"qcommon/common.cpp",
"qcommon/crash.cpp",
"qcommon/cvar.cpp",
"qcommon/files.cpp",
"qcommon/huffman.cpp",
"qcommon/huffman_static.cpp",
"qcommon/json.cpp",
"qcommon/md4.cpp",
"qcommon/md5.cpp",
"qcommon/msg.cpp",
"qcommon/net_chan.cpp",
"qcommon/net_ip.cpp",
"qcommon/q_math.c",
"qcommon/q_shared.c",
"qcommon/unzip.cpp",
"qcommon/vm.cpp",
"qcommon/vm_interpreted.cpp",
"qcommon/vm_x86.cpp",
"server/sv_bot.cpp",
"server/sv_ccmds.cpp",
"server/sv_client.cpp",
"server/sv_game.cpp",
"server/sv_init.cpp",
"server/sv_main.cpp",
"server/sv_net_chan.cpp",
"server/sv_snapshot.cpp",
"server/sv_world.cpp"
}
local server_sources_windows =
{
"win32/win_main.cpp",
"win32/win_shared.cpp",
"win32/win_exception.cpp",
"win32/win_syscon.cpp"
}
local server_sources_unix =
{
"unix/unix_main.cpp",
"unix/unix_shared.cpp",
"unix/linux_signals.cpp"
}
local client_sources =
{
"client/cl_avi.cpp",
"client/cl_browser.cpp",
"client/cl_cgame.cpp",
"client/cl_cin.cpp",
"client/cl_console.cpp",
"client/cl_input.cpp",
"client/cl_keys.cpp",
"client/cl_main.cpp",
"client/cl_net_chan.cpp",
"client/cl_parse.cpp",
"client/cl_scrn.cpp",
"client/cl_ui.cpp",
"client/snd_codec.cpp",
"client/snd_codec_wav.cpp",
"client/snd_dma.cpp",
"client/snd_main.cpp",
"client/snd_mem.cpp",
"client/snd_mix.cpp",
"qcommon/cmd.cpp",
"qcommon/cm_load.cpp",
"qcommon/cm_patch.cpp",
"qcommon/cm_polylib.cpp",
"qcommon/cm_test.cpp",
"qcommon/cm_trace.cpp",
"qcommon/common.cpp",
"qcommon/crash.cpp",
"qcommon/cvar.cpp",
"qcommon/files.cpp",
"qcommon/huffman.cpp",
"qcommon/huffman_static.cpp",
"qcommon/json.cpp",
"qcommon/md4.cpp",
"qcommon/md5.cpp",
"qcommon/msg.cpp",
"qcommon/net_chan.cpp",
"qcommon/net_ip.cpp",
"qcommon/q_math.c",
"qcommon/q_shared.c",
"qcommon/unzip.cpp",
"qcommon/vm.cpp",
"qcommon/vm_interpreted.cpp",
"qcommon/vm_x86.cpp",
"server/sv_bot.cpp",
"server/sv_ccmds.cpp",
"server/sv_client.cpp",
"server/sv_game.cpp",
"server/sv_init.cpp",
"server/sv_main.cpp",
"server/sv_net_chan.cpp",
"server/sv_snapshot.cpp",
"server/sv_world.cpp"
}
local client_sources_windows =
{
"win32/win_input.cpp",
"win32/win_main.cpp",
"win32/win_shared.cpp",
"win32/win_exception.cpp",
"win32/win_snd.cpp",
"win32/win_syscon.cpp",
"win32/win_wndproc.cpp",
"win32/win_glimp.cpp",
"win32/win_qgl.c"
}
local client_sources_unix =
{
"unix/unix_main.cpp",
"unix/unix_shared.cpp",
"unix/linux_joystick.c",
"unix/linux_signals.cpp",
"unix/linux_qgl.c",
"unix/linux_snd.c",
"unix/linux_glimp.cpp"
}
AddHeaders("botlib")
AddHeaders("qcommon")
AddHeaders("server")
AddHeaders("client")
AddHeaders("cgame")
AddHeaders("game")
AddHeaders("ui")
links { "botlib" }
if (server == 1) then
AddSourcesFromArray(".", server_sources)
else
AddSourcesFromArray(".", client_sources)
includedirs { path_src.."/freetype/include" }
AddHeaders("renderer")
links { "renderer", "freetype", "libjpeg-turbo" }
end
filter { "system:windows" }
if (server == 1) then
AddSourcesFromArray(".", server_sources_windows)
else
AddSourcesFromArray(".", client_sources_windows)
end
AddHeaders("win32")
filter { "system:not windows" }
if (server == 1) then
AddSourcesFromArray(".", server_sources_unix)
else
AddSourcesFromArray(".", client_sources_unix)
end
-- create git info header
-- copy the binaries over to the test q3 install
-- it seems that "filter" doesn't work with "prebuildcommands", "postbuildcommands"
filter { }
if os.is("windows") then
prebuildcommands { path.translate(CreateGitPreBuildCommand(".cmd"), "\\") }
postbuildcommands { path.translate(CreateExeCopyPostBuildCommand("copy", exeName, ".exe"), "\\") }
postbuildcommands { path.translate(WIN_CreatePdbCopyPostBuildCommand(exeName), "\\") }
else
prebuildcommands { CreateGitPreBuildCommand(".sh") }
postbuildcommands { CreateExeCopyPostBuildCommand("cp -u", exeName, "") }
end
-- create VC++ debug settings
filter "action:vs*"
local abs_path_exe = string.format("%s\\%s.exe", abs_path_q3, exeName)
debugcommand(abs_path_exe)
if (server == 1) then
debugargs { "+set fs_game $(CPMADIR) +set sv_pure 0" }
else
debugargs { "+set fs_game $(CPMADIR) +set sv_pure 0 +set r_fullscreen 0" }
end
debugdir(abs_path_q3)
filter "system:windows"
links { "Winmm", "ws2_32", "Version" }
if (server == 0) then
links { "opengl32" }
end
filter "system:not windows"
links { "dl", "m", "backtrace" }
if (server == 0) then
buildoptions { "-pthread" }
links { "X11", "pthread" }
end
-- RC will compile the .rc into a .res
-- LINK accepts .res files directly
filter "action:vs*"
linkoptions { path.translate(path_src.."/win32/winquake.res", "\\"), "/STACK:8388608" }
filter { "action:vs*", "configurations:release" }
linkoptions { "/OPT:REF", "/OPT:ICF" }
-- force everything to be compiled as C++ for now
-- otherwise, we run into problems (that should really be fixed)
filter "action:gmake"
buildoptions { "-x c++" }
end
local function ApplyLibJpegTurboProjectSettings()
local jpeg_sources =
{
"jcapimin.c",
"jcapistd.c",
"jccoefct.c",
"jccolor.c",
"jcdctmgr.c",
"jchuff.c",
"jcinit.c",
"jcmainct.c",
"jcmarker.c",
"jcmaster.c",
"jcomapi.c",
"jcparam.c",
"jcphuff.c",
"jcprepct.c",
"jcsample.c",
"jctrans.c",
"jdapimin.c",
"jdapistd.c",
"jdatadst.c",
"jdatasrc.c",
"jdcoefct.c",
"jdcolor.c",
"jddctmgr.c",
"jdhuff.c",
"jdinput.c",
"jdmainct.c",
"jdmarker.c",
"jdmaster.c",
"jdmerge.c",
"jdphuff.c",
"jdpostct.c",
"jdsample.c",
"jdtrans.c",
"jerror.c",
"jfdctflt.c",
"jfdctfst.c",
"jfdctint.c",
"jidctflt.c",
"jidctfst.c",
"jidctint.c",
"jidctred.c",
"jquant1.c",
"jquant2.c",
"jutils.c",
"jmemmgr.c"
}
local jpeg_asm_sources_x86 =
{
"jsimdcpu",
"jfdctflt-3dn",
"jidctflt-3dn",
"jquant-3dn",
"jccolor-mmx",
"jcgray-mmx",
"jcsample-mmx",
"jdcolor-mmx",
"jdmerge-mmx",
"jdsample-mmx",
"jfdctfst-mmx",
"jfdctint-mmx",
"jidctfst-mmx",
"jidctint-mmx",
"jidctred-mmx",
"jquant-mmx",
"jfdctflt-sse",
"jidctflt-sse",
"jquant-sse",
"jccolor-sse2",
"jcgray-sse2",
"jchuff-sse2",
"jcsample-sse2",
"jdcolor-sse2",
"jdmerge-sse2",
"jdsample-sse2",
"jfdctfst-sse2",
"jfdctint-sse2",
"jidctflt-sse2",
"jidctfst-sse2",
"jidctint-sse2",
"jidctred-sse2",
"jquantf-sse2",
"jquanti-sse2"
}
local jpeg_asm_sources_x64 =
{
"jfdctflt-sse-64",
"jccolor-sse2-64",
"jcgray-sse2-64",
"jchuff-sse2-64",
"jcsample-sse2-64",
"jdcolor-sse2-64",
"jdmerge-sse2-64",
"jdsample-sse2-64",
"jfdctfst-sse2-64",
"jfdctint-sse2-64",
"jidctflt-sse2-64",
"jidctfst-sse2-64",
"jidctint-sse2-64",
"jidctred-sse2-64",
"jquantf-sse2-64",
"jquanti-sse2-64"
}
AddSourcesFromArray("libjpeg-turbo", jpeg_sources)
includedirs { path_src.."/libjpeg-turbo", path_src.."/libjpeg-turbo/simd" }
defines { "WITH_SIMD" }
filter "platforms:x32"
AddAssemblerSourcesFromArray("libjpeg-turbo/simd", jpeg_asm_sources_x86)
files { path_src.."/libjpeg-turbo/simd/jsimd_i386.c" }
defines { "SIZEOF_SIZE_T=4" }
filter "platforms:x64"
AddAssemblerSourcesFromArray("libjpeg-turbo/simd", jpeg_asm_sources_x64)
files { path_src.."/libjpeg-turbo/simd/jsimd_x86_64.c" }
defines { "SIZEOF_SIZE_T=8" }
local asm_inc_path = GetMakePath(path_src.."/libjpeg-turbo")
local nasm_flags = GetLibJpegTurboNasmFlags()
local nasm_includes
if os.is("windows") then
asm_inc_path = path.translate(asm_inc_path, "\\")
nasm_includes = string.format("-I%s\\ -I%s\\win\\ -I%s\\simd\\", asm_inc_path, asm_inc_path, asm_inc_path)
else
nasm_includes = string.format("-I%s/ -I%s/win/ -I%s/simd/", asm_inc_path, asm_inc_path, asm_inc_path)
end
local obj_file_path = string.format("%s%s", "%{cfg.targetdir}/%{file.basename}", GetCompilerObjectExtension())
local command = string.format("nasm -o%s %s %s %s", obj_file_path, nasm_flags, nasm_includes, "%{file.relpath}")
if os.is("windows") then
command = path.translate(command, "\\")
obj_file_path = path.translate(obj_file_path, "\\")
end
filter "files:**.asm"
buildmessage "%{file.basename}.asm"
buildcommands { command }
buildoutputs { obj_file_path }
extra_warnings = 0
ApplyLibProjectSettings()
extra_warnings = 1
end
solution "cnq3"
location ( path_build.."/".._ACTION )
platforms { "x32", "x64" }
configurations { "debug", "release" }
project "cnq3"
kind "WindowedApp"
language "C++"
ApplyExeProjectSettings("cnq3", 0)
project "cnq3-server"
kind "WindowedApp"
language "C++"
defines { "DEDICATED" }
ApplyExeProjectSettings("cnq3-server", 1)
project "botlib"
kind "StaticLib"
language "C++"
defines { "BOTLIB" }
AddSourcesAndHeaders("botlib")
ApplyLibProjectSettings()
project "renderer"
kind "StaticLib"
language "C++"
AddSourcesAndHeaders("renderer")
includedirs { path_src.."/freetype/include" }
ApplyLibProjectSettings()
project "libjpeg-turbo"
kind "StaticLib"
language "C"
ApplyLibJpegTurboProjectSettings()
project "freetype"
local ft_sources =
{
"base/ftbbox.c",
"base/ftsynth.c",
"base/ftbase.c",
"base/ftglyph.c",
"base/ftinit.c",
"base/ftstroke.c",
"base/ftsystem.c",
"sfnt/sfnt.c",
"smooth/smooth.c",
"truetype/truetype.c"
}
kind "StaticLib"
language "C"
AddSourcesFromArray("freetype/src", ft_sources)
includedirs { path_src.."/freetype/include" }
defines { "_LIB", "FT2_BUILD_LIBRARY", "_BIND_TO_CURRENT_VCLIBS_VERSION=1" }
ApplyLibProjectSettings()
filter "action:vs*"
buildoptions { "/wd4324" } -- "structure was padded due to __declspec(align())"