2025-02-19 11:07:09 -08:00
local semver = require ( " semver " )
2025-06-28 04:08:18 -07:00
print ( " Premake version: " .. _PREMAKE_VERSION )
if ( semver ( _PREMAKE_VERSION ) < semver ( " 5.0.0-beta5 " ) ) then
2025-02-19 11:07:09 -08:00
print ( " Requires Premake 5.0.0-beta5 or later " )
2025-06-28 04:08:18 -07:00
print ( " Aborting " )
2025-02-19 11:07:09 -08:00
os.exit ( 1 )
end
2025-06-28 04:08:18 -07:00
local function print_options ( )
local options = " "
local tkeys = { }
for key , _ in pairs ( _OPTIONS ) do table.insert ( tkeys , key ) end
table.sort ( tkeys )
for _ , key in pairs ( tkeys ) do
local value = _OPTIONS [ key ]
options = options .. " -- " .. key
if ( value and value ~= " " ) then
options = options .. " = " .. value
end
end
print ( " Premake options: " .. options )
end
print_options ( )
print ( " " )
print ( " -------------------------------------------------------------------------------- " )
print ( " Environment " )
print ( " " )
print ( " AR : " .. ( os.getenv ( " AR " ) or " unset " ) )
print ( " CC : " .. ( os.getenv ( " CC " ) or " unset " ) )
print ( " CXX : " .. ( os.getenv ( " CXX " ) or " unset " ) )
print ( " HOSTTYPE : " .. ( os.getenv ( " HOSTTYPE " ) or " unset " ) )
print ( " PKG_CONFIG : " .. ( os.getenv ( " PKG_CONFIG " ) or " unset " ) )
print ( " " )
print ( " CFLAGS : " .. ( os.getenv ( " CFLAGS " ) or " unset " ) )
print ( " CXXFLAGS : " .. ( os.getenv ( " CXXFLAGS " ) or " unset " ) )
print ( " LDFLAGS : " .. ( os.getenv ( " LDFLAGS " ) or " unset " ) )
print ( " -------------------------------------------------------------------------------- " )
print ( " " )
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " android " , description = " Use non-working Android cross-compiling mode " }
newoption { category = " Pyrogenesis " , trigger = " coverage " , description = " Enable code coverage data collection (GCC only) " }
newoption { category = " Pyrogenesis " , trigger = " gles " , description = " Use non-working OpenGL ES 2.0 mode " }
newoption { category = " Pyrogenesis " , trigger = " minimal-flags " , description = " Only set compiler/linker flags that are really needed. Has no effect on Windows builds " }
newoption { category = " Pyrogenesis " , trigger = " outpath " , description = " Location for generated project files " , default = " ../workspaces/default " }
2025-05-21 05:41:58 -07:00
newoption { category = " Pyrogenesis " , trigger = " sanitize-address " , description = " Enable ASAN if available " }
newoption { category = " Pyrogenesis " , trigger = " sanitize-thread " , description = " Enable TSAN if available " }
newoption { category = " Pyrogenesis " , trigger = " sanitize-undefined-behaviour " , description = " Enable UBSAN if available " }
2025-05-22 08:31:54 -07:00
newoption { category = " Pyrogenesis " , trigger = " strip-binaries " , description = " Strip created binaries " }
2024-10-24 10:27:03 -07:00
newoption { category = " Pyrogenesis " , trigger = " with-system-cpp-httplib " , description = " Search standard paths for cpp-httplib, instead of using bundled copy " }
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " with-system-cxxtest " , description = " Search standard paths for cxxtest, instead of using bundled copy " }
newoption { category = " Pyrogenesis " , trigger = " with-lto " , description = " Enable Link Time Optimization (LTO) " }
2025-08-04 08:27:45 -07:00
newoption { category = " Pyrogenesis " , trigger = " with-system-mozjs " , description = " Search standard paths for libmozjs128, instead of using bundled copy " }
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " with-system-nvtt " , description = " Search standard paths for nvidia-texture-tools library, instead of using bundled copy " }
newoption { category = " Pyrogenesis " , trigger = " with-valgrind " , description = " Enable Valgrind support (non-Windows only) " }
newoption { category = " Pyrogenesis " , trigger = " without-audio " , description = " Disable use of OpenAL/Ogg/Vorbis APIs " }
newoption { category = " Pyrogenesis " , trigger = " without-atlas " , description = " Disable Atlas scenario/map editor and ActorEditor " }
2025-05-29 19:55:50 -07:00
newoption { category = " Pyrogenesis " , trigger = " without-dap-interface " , description = " Disable Dap interface project " }
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " without-lobby " , description = " Disable the use of gloox and the multiplayer lobby " }
newoption { category = " Pyrogenesis " , trigger = " without-miniupnpc " , description = " Disable use of miniupnpc for port forwarding " }
newoption { category = " Pyrogenesis " , trigger = " without-nvtt " , description = " Disable use of NVTT " }
newoption { category = " Pyrogenesis " , trigger = " without-pch " , description = " Disable generation and usage of precompiled headers " }
newoption { category = " Pyrogenesis " , trigger = " without-tests " , description = " Disable generation of test projects " }
2017-10-30 06:52:05 -07:00
-- OS X specific options
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " macosx-version-min " , description = " Set minimum required version of the OS X API, the build will possibly fail if an older SDK is used, while newer API functions will be weakly linked (i.e. resolved at runtime) " }
newoption { category = " Pyrogenesis " , trigger = " sysroot " , description = " Set compiler system root path, used for building against a non-system SDK. For example /usr/local becomes SYSROOT/user/local " }
2017-10-30 06:52:05 -07:00
-- Install options
2024-12-20 22:00:30 -08:00
newoption { category = " Pyrogenesis " , trigger = " bindir " , description = " Directory for executables (typically '/usr/games'); default is to be relocatable " }
newoption { category = " Pyrogenesis " , trigger = " datadir " , description = " Directory for data files (typically '/usr/share/games/0ad'); default is ../data/ relative to executable " }
newoption { category = " Pyrogenesis " , trigger = " libdir " , description = " Directory for libraries (typically '/usr/lib/games/0ad'); default is ./ relative to executable " }
2017-10-30 06:52:05 -07:00
-- Root directory of project checkout relative to this .lua file
rootdir = " ../.. "
2024-12-14 22:52:39 -08:00
-- Determine C compiler
local cc = nil
if os.getenv ( " CC " ) then
2017-10-30 06:52:05 -07:00
cc = os.getenv ( " CC " )
2024-12-14 22:52:39 -08:00
elseif _OPTIONS [ " cc " ] then
cc = _OPTIONS [ " cc " ]
else
-- assumes cc name is toolset name
cc = premake.action . current ( ) . toolset
2017-10-30 06:52:05 -07:00
end
2022-05-14 23:45:53 -07:00
-- detect CPU architecture (simplistic)
2022-05-15 14:22:49 -07:00
-- The user can target an architecture with HOSTTYPE, but the game still selects some know value.
2017-10-30 06:52:05 -07:00
arch = " x86 "
2022-01-13 06:42:42 -08:00
macos_arch = " x86_64 "
2022-05-15 14:22:49 -07:00
2017-10-30 06:52:05 -07:00
if _OPTIONS [ " android " ] then
arch = " arm "
elseif os.istarget ( " windows " ) then
2022-05-15 14:22:49 -07:00
if os.getenv ( " HOSTTYPE " ) then
arch = os.getenv ( " HOSTTYPE " )
elseif os.getenv ( " PROCESSOR_ARCHITECTURE " ) == " amd64 " or os.getenv ( " PROCESSOR_ARCHITEW6432 " ) == " amd64 " then
2017-10-30 06:52:05 -07:00
arch = " amd64 "
end
else
2022-05-15 14:22:49 -07:00
local machine = " x86_64 "
if os.getenv ( " HOSTTYPE " ) and os.getenv ( " HOSTTYPE " ) ~= ' ' then
machine = os.getenv ( " HOSTTYPE " )
else
os.execute ( cc .. " -dumpmachine > .gccmachine.tmp " )
local f = io.open ( " .gccmachine.tmp " , " r " )
machine = f : read ( " *line " )
f : close ( )
end
2022-05-14 23:45:53 -07:00
-- Special handling on mac os where xcode needs special flags.
2024-12-11 14:34:38 -08:00
-- TODO: We should look into "universal" macOS compilation.
2022-01-13 06:42:42 -08:00
if os.istarget ( " macosx " ) then
2022-05-14 23:45:53 -07:00
if string.find ( machine , " arm64 " ) then
2017-10-30 06:52:05 -07:00
arch = " aarch64 "
2022-05-14 23:45:53 -07:00
macos_arch = " arm64 "
2017-10-30 06:52:05 -07:00
else
2022-05-14 23:45:53 -07:00
arch = " amd64 "
macos_arch = " x86_64 "
2017-10-30 06:52:05 -07:00
end
2022-05-14 23:45:53 -07:00
elseif string.find ( machine , " x86_64 " ) == 1 or string.find ( machine , " amd64 " ) == 1 then
arch = " amd64 "
elseif string.find ( machine , " i.86 " ) == 1 then
arch = " x86 "
elseif string.find ( machine , " arm " ) == 1 then
arch = " arm "
elseif string.find ( machine , " aarch64 " ) == 1 then
arch = " aarch64 "
elseif string.find ( machine , " e2k " ) == 1 then
arch = " e2k "
2026-03-05 14:38:44 -08:00
elseif string.find ( machine , " loongarch64 " ) == 1 then
arch = " loong64 "
2022-05-14 23:45:53 -07:00
elseif string.find ( machine , " ppc64 " ) == 1 or string.find ( machine , " powerpc64 " ) == 1 then
arch = " ppc64 "
2026-03-05 14:38:44 -08:00
elseif string.find ( machine , " riscv64 " ) == 1 then
arch = " riscv64 "
2022-05-14 23:45:53 -07:00
else
print ( " WARNING: Cannot determine architecture from GCC, assuming x86 " )
2017-10-30 06:52:05 -07:00
end
end
2025-05-01 03:45:47 -07:00
-- On Windows check if wxWidgets is available, if not disable atlas and emit warning.
-- This is because there are currently not prebuilt binaries provided.
if not _OPTIONS [ " without-atlas " ] and os.istarget ( " windows " ) then
local win_libs_dir = rootdir .. " /libraries/ " .. ( arch == " amd64 " and " win64 " or " win32 " )
if not os.isfile ( win_libs_dir .. " /wxwidgets/include/wx/wx.h " ) then
print ( " wxWidgets not found, disabling atlas " )
_OPTIONS [ " without-atlas " ] = " "
end
end
2025-04-26 11:53:09 -07:00
-- External libraries should know about arch.
dofile ( " extern_libs5.lua " )
2020-06-23 08:06:57 -07:00
-- Test whether we need to link libexecinfo.
-- This is mostly the case on musl systems, as well as on BSD systems : only glibc provides the
-- backtrace symbols we require in the libc, for other libcs we use the libexecinfo library.
local link_execinfo = false
if os.istarget ( " bsd " ) then
link_execinfo = true
elseif os.istarget ( " linux " ) then
local _ , link_errorCode = os.outputof ( cc .. " ./tests/execinfo.c -o /dev/null " )
if link_errorCode ~= 0 then
link_execinfo = true
end
end
2024-10-27 12:06:39 -07:00
-- Test whether system mozjs is built with --enable-debug
-- The pc file doesn't specify the required -DDEBUG needed in that case
local mozjs_is_debug_build = false
if _OPTIONS [ " with-system-mozjs " ] then
2025-08-04 08:27:45 -07:00
local _ , errorCode = os.outputof ( cc .. " $(pkg-config mozjs-128 --cflags) ./tests/mozdebug.c -o /dev/null " )
2024-10-27 12:06:39 -07:00
if errorCode ~= 0 then
mozjs_is_debug_build = true
end
end
2017-10-30 06:52:05 -07:00
-- Set up the Workspace
workspace " pyrogenesis "
targetdir ( rootdir .. " /binaries/system " )
libdirs ( rootdir .. " /binaries/system " )
location ( _OPTIONS [ " outpath " ] )
configurations { " Release " , " Debug " }
2025-08-04 03:39:55 -07:00
startproject " pyrogenesis "
2017-10-30 06:52:05 -07:00
source_root = rootdir .. " /source/ " -- default for most projects - overridden by local in others
-- Rationale: projects should not have any additional include paths except for
-- those required by external libraries. Instead, we should always write the
-- full relative path, e.g. #include "maths/Vector3d.h". This avoids confusion
-- ("which file is meant?") and avoids enormous include path lists.
-- projects: engine static libs, main exe, atlas, atlas frontends, test.
--------------------------------------------------------------------------------
-- project helper functions
--------------------------------------------------------------------------------
function project_set_target ( project_name )
-- Note: On Windows, ".exe" is added on the end, on unices the name is used directly
local obj_dir_prefix = _OPTIONS [ " outpath " ] .. " /obj/ " .. project_name .. " _ "
filter " Debug "
objdir ( obj_dir_prefix .. " Debug " )
targetsuffix ( " _dbg " )
filter " Release "
objdir ( obj_dir_prefix .. " Release " )
filter { }
end
function project_set_build_flags ( )
editandcontinue " Off "
2025-05-22 08:31:54 -07:00
if _OPTIONS [ ' strip-binaries ' ] then
symbols " Off "
else
2017-10-30 06:52:05 -07:00
symbols " On "
end
2025-05-21 05:41:58 -07:00
-- ASAN, TSAN, UBSAN
local sanitizers = { }
if _OPTIONS [ ' sanitize-address ' ] then
table.insert ( sanitizers , ' Address ' )
end
if _OPTIONS [ ' sanitize-thread ' ] then
table.insert ( sanitizers , ' Thread ' )
end
if _OPTIONS [ ' sanitize-undefined-behaviour ' ] then
table.insert ( sanitizers , ' UndefinedBehavior ' )
end
sanitize ( sanitizers )
2017-10-30 06:52:05 -07:00
-- disable Windows debug heap, since it makes malloc/free hugely slower when
-- running inside a debugger
if os.istarget ( " windows " ) then
debugenvs { " _NO_DEBUG_HEAP=1 " }
end
2025-07-29 02:09:16 -07:00
if os.istarget ( " windows " ) then
-- mozilla 115 linked list destructor in debug build
defines { " __PRETTY_FUNCTION__=__FUNCSIG__ " }
end
2024-10-27 12:06:39 -07:00
filter { " Debug " , " action:vs* " }
2017-10-30 06:52:05 -07:00
defines { " DEBUG " }
filter " Release "
if os.istarget ( " windows " ) or not _OPTIONS [ " minimal-flags " ] then
optimize " Speed "
end
2024-11-03 11:09:25 -08:00
if _OPTIONS [ " with-lto " ] then
2025-02-19 11:07:09 -08:00
linktimeoptimization ( " On " )
2024-11-03 11:09:25 -08:00
end
2017-10-30 06:52:05 -07:00
defines { " NDEBUG " , " CONFIG_FINAL=1 " }
filter { }
2024-10-27 12:06:39 -07:00
if mozjs_is_debug_build then
defines " DEBUG "
end
2017-10-30 06:52:05 -07:00
if _OPTIONS [ " gles " ] then
defines { " CONFIG2_GLES=1 " }
end
if _OPTIONS [ " without-audio " ] then
defines { " CONFIG2_AUDIO=0 " }
end
if _OPTIONS [ " without-nvtt " ] then
defines { " CONFIG2_NVTT=0 " }
end
if _OPTIONS [ " without-lobby " ] then
defines { " CONFIG2_LOBBY=0 " }
end
if _OPTIONS [ " without-miniupnpc " ] then
defines { " CONFIG2_MINIUPNPC=0 " }
end
2025-05-29 19:55:50 -07:00
if _OPTIONS [ " without-dap-interface " ] then
defines { " CONFIG2_DAP_INTERFACE=0 " }
end
2025-07-05 07:04:08 -07:00
-- hide warnings caused by library includes
externalwarnings " Off "
2017-10-30 06:52:05 -07:00
-- various platform-specific build flags
if os.istarget ( " windows " ) then
2018-02-26 13:49:49 -08:00
flags { " MultiProcessorCompile " }
2020-12-31 07:37:28 -08:00
-- Since KB4088875 Windows 7 has a soft requirement for SSE2.
-- Windows 8+ and Firefox ESR52 make it hard requirement.
-- Finally since VS2012 it's enabled implicitely when not set.
vectorextensions " SSE2 "
2025-08-04 05:39:56 -07:00
-- SpiderMonkey only supports building with MSVC on a best-effort basis,
-- and the traditional MSVC preprocessor is incompatible with some headers.
-- Use the modern, standard-compliant MSVC preprocessor instead.
usestandardpreprocessor " On "
2017-10-30 06:52:05 -07:00
-- use native wchar_t type (not typedef to unsigned short)
nativewchar " on "
2025-07-05 07:04:08 -07:00
-- enable most of the standard warnings
warnings " Extra "
2025-04-29 14:06:24 -07:00
-- FIXME: conversion warnings, should add -Wconversion to gcc and clang flags as well
disablewarnings { " 4267 " }
2017-10-30 06:52:05 -07:00
else -- *nix
2024-11-17 06:32:15 -08:00
-- exclude most non-essential build options for minimal-flags
if not _OPTIONS [ " minimal-flags " ] then
2017-10-30 06:52:05 -07:00
buildoptions {
2024-11-17 06:32:15 -08:00
-- enable most of the standard warnings
2025-06-21 10:04:25 -07:00
" -Wall " ,
2024-11-17 06:32:15 -08:00
" -Wextra " ,
2025-04-29 14:06:24 -07:00
-- "-Wconversion", FIXME: should seriously consider fixing so this warning can be enabled.
2024-11-17 06:32:15 -08:00
-- add some other useful warnings that need to be enabled explicitly
" -Wunused-parameter " ,
" -Wredundant-decls " , -- (useful for finding some multiply-included header files)
-- "-Wformat=2", -- (useful sometimes, but a bit noisy, so skip it by default)
-- "-Wcast-qual", -- (useful for checking const-correctness, but a bit noisy, so skip it by default)
" -Wnon-virtual-dtor " , -- (sometimes noisy but finds real bugs)
" -Wundef " , -- (useful for finding macro name typos)
2025-06-21 09:59:33 -07:00
-- disable some warnings that currently trigger
" -Wno-missing-field-initializers " , -- (this is common in external headers we can't fix)
" -Wno-reorder " , -- order of initialization list in constructors (lots of noise)
2024-11-17 06:32:15 -08:00
-- enable security features (stack checking etc) that shouldn't have
-- a significant effect on performance and can catch bugs
2025-05-04 02:19:32 -07:00
" -fstack-protector-strong " ,
2024-11-17 06:32:15 -08:00
-- always enable strict aliasing (useful in debug builds because of the warnings)
" -fstrict-aliasing " ,
-- don't omit frame pointers (for now), because performance will be impacted
-- negatively by the way this breaks profilers more than it will be impacted
-- positively by the optimisation
" -fno-omit-frame-pointer "
2017-10-30 06:52:05 -07:00
}
2024-11-17 06:32:15 -08:00
filter { " Release " }
2017-10-30 06:52:05 -07:00
buildoptions {
2024-11-17 06:32:15 -08:00
-- FORTIFY_SOURCE needs optimizations to be enabled
" -U_FORTIFY_SOURCE " , -- (avoid redefinition warning if already defined)
" -D_FORTIFY_SOURCE=2 " ,
2017-10-30 06:52:05 -07:00
}
2024-11-17 06:32:15 -08:00
filter { }
2017-10-30 06:52:05 -07:00
2025-07-29 02:22:33 -07:00
-- issues with gcc 12 to 14 with pch enabled, workaround for CI which sets CC=gcc-12
2024-11-17 06:32:15 -08:00
if cc == " gcc-12 " then
buildoptions {
2025-07-29 02:22:33 -07:00
-- mozilla
2024-11-17 06:32:15 -08:00
" -Wno-dangling-pointer " ,
2025-07-29 02:22:33 -07:00
-- fortify source
" -Wno-stringop-overflow " ,
" -Wno-attribute-warning " ,
" -Wno-array-bounds " ,
" -Wno-restrict " ,
2024-11-17 06:32:15 -08:00
}
2017-10-30 06:52:05 -07:00
end
2024-11-17 06:32:15 -08:00
if not _OPTIONS [ " without-pch " ] then
buildoptions {
-- do something (?) so that ccache can handle compilation with PCH enabled
-- (ccache 3.1+ also requires CCACHE_SLOPPINESS=time_macros for this to work)
" -fpch-preprocess "
}
2017-10-30 06:52:05 -07:00
end
2024-11-17 06:32:15 -08:00
if os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
buildoptions { " -fPIC " }
2025-05-21 05:41:58 -07:00
if next ( sanitizers ) == nil then
linkoptions { " -Wl,--no-undefined " , " -Wl,--as-needed " , " -Wl,-z,relro " }
end
2017-10-30 06:52:05 -07:00
end
2024-11-17 06:32:15 -08:00
if arch == " x86 " then
buildoptions {
-- To support intrinsics like __sync_bool_compare_and_swap on x86
-- we need to set -march to something that supports them (i686).
-- We use pentium3 to also enable other features like mmx and sse,
-- while tuning for generic to have good performance on every
-- supported CPU.
-- Note that all these features are already supported on amd64.
" -march=pentium3 -mtune=generic " ,
-- This allows x86 operating systems to handle the 2GB+ public mod.
" -D_FILE_OFFSET_BITS=64 "
}
2017-10-30 06:52:05 -07:00
end
2024-11-17 06:32:15 -08:00
end
2017-10-30 06:52:05 -07:00
2024-11-17 06:32:15 -08:00
if arch == " arm " then
-- disable warnings about va_list ABI change and use
-- compile-time flags for futher configuration.
buildoptions { " -Wno-psabi " }
if _OPTIONS [ " android " ] then
-- Android uses softfp, so we should too.
buildoptions { " -mfloat-abi=softfp " }
2017-10-30 06:52:05 -07:00
end
2024-11-17 06:32:15 -08:00
end
2017-10-30 06:52:05 -07:00
2024-11-17 06:32:15 -08:00
if _OPTIONS [ " coverage " ] then
buildoptions { " -fprofile-arcs " , " -ftest-coverage " }
links { " gcov " }
end
2017-10-30 06:52:05 -07:00
2024-11-17 06:32:15 -08:00
-- MacOS 10.12 only supports intel processors with SSE 4.1, so enable that.
if os.istarget ( " macosx " ) and arch == " amd64 " then
buildoptions { " -msse4.1 " }
end
-- Check if SDK path should be used
if _OPTIONS [ " sysroot " ] then
buildoptions { " -isysroot " .. _OPTIONS [ " sysroot " ] }
linkoptions { " -Wl,-syslibroot, " .. _OPTIONS [ " sysroot " ] }
end
-- On OS X, sometimes we need to specify the minimum API version to use
if _OPTIONS [ " macosx-version-min " ] then
buildoptions { " -mmacosx-version-min= " .. _OPTIONS [ " macosx-version-min " ] }
-- clang and llvm-gcc look at mmacosx-version-min to determine link target
-- and CRT version, and use it to set the macosx_version_min linker flag
linkoptions { " -mmacosx-version-min= " .. _OPTIONS [ " macosx-version-min " ] }
end
-- Only libc++ is supported on MacOS
if os.istarget ( " macosx " ) then
buildoptions { " -stdlib=libc++ " }
linkoptions { " -stdlib=libc++ " }
2017-10-30 06:52:05 -07:00
end
buildoptions {
-- Hide symbols in dynamic shared objects by default, for efficiency and for equivalence with
-- Windows - they should be exported explicitly with __attribute__ ((visibility ("default")))
" -fvisibility=hidden "
}
if _OPTIONS [ " bindir " ] then
defines { " INSTALLED_BINDIR= " .. _OPTIONS [ " bindir " ] }
end
if _OPTIONS [ " datadir " ] then
defines { " INSTALLED_DATADIR= " .. _OPTIONS [ " datadir " ] }
end
if _OPTIONS [ " libdir " ] then
defines { " INSTALLED_LIBDIR= " .. _OPTIONS [ " libdir " ] }
end
if os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
-- To use our local shared libraries, they need to be found in the
-- runtime dynamic linker path. Add their path to -rpath.
if _OPTIONS [ " libdir " ] then
linkoptions { " -Wl,-rpath, " .. _OPTIONS [ " libdir " ] }
else
-- On FreeBSD we need to allow use of $ORIGIN
if os.istarget ( " bsd " ) then
linkoptions { " -Wl,-z,origin " }
end
-- Adding the executable path and taking care of correct escaping
2025-02-19 11:07:09 -08:00
if _ACTION == " gmake " then
2017-10-30 06:52:05 -07:00
linkoptions { " -Wl,-rpath,'$$ORIGIN' " }
elseif _ACTION == " codeblocks " then
linkoptions { " -Wl,-R \\ \\ $$$ORIGIN " }
end
end
end
end
end
-- create a project and set the attributes that are common to all projects.
function project_create ( project_name , target_type )
project ( project_name )
language " C++ "
2025-07-28 10:01:41 -07:00
cppdialect " C++20 "
2017-10-30 06:52:05 -07:00
kind ( target_type )
2024-11-02 06:09:34 -07:00
filter " action:vs2022 "
toolset " v143 "
2017-10-30 06:52:05 -07:00
filter { }
2020-01-12 12:19:56 -08:00
filter " action:vs* "
buildoptions " /utf-8 "
2024-08-27 05:37:58 -07:00
-- disable LNK4221 warning, to avoid spending energy ordering projects in linker invocations
linkoptions " /ignore:4221 "
2020-01-12 12:19:56 -08:00
filter { }
2017-10-30 06:52:05 -07:00
project_set_target ( project_name )
project_set_build_flags ( )
end
-- OSX creates a .app bundle if the project type of the main application is set to "WindowedApp".
-- We don't want this because this bundle would be broken (it lacks all the resources and external dependencies, Info.plist etc...)
-- Windows opens a console in the background if it's set to ConsoleApp, which is not what we want.
-- I didn't check if this setting matters for linux, but WindowedApp works there.
function get_main_project_target_type ( )
if _OPTIONS [ " android " ] then
return " SharedLib "
elseif os.istarget ( " macosx " ) then
return " ConsoleApp "
else
return " WindowedApp "
end
end
-- source_root: rel_source_dirs and rel_include_dirs are relative to this directory
-- rel_source_dirs: A table of subdirectories. All source files in these directories are added.
-- rel_include_dirs: A table of subdirectories to be included.
-- extra_params: table including zero or more of the following:
-- * no_pch: If specified, no precompiled headers are used for this project.
-- * pch_dir: If specified, this directory will be used for precompiled headers instead of the default
-- <source_root>/pch/<projectname>/.
-- * extra_files: table of filenames (relative to source_root) to add to project
-- * extra_links: table of library names to add to link step
function project_add_contents ( source_root , rel_source_dirs , rel_include_dirs , extra_params )
for i , v in pairs ( rel_source_dirs ) do
local prefix = source_root .. v .. " / "
files { prefix .. " *.cpp " , prefix .. " *.h " , prefix .. " *.inl " , prefix .. " *.js " , prefix .. " *.asm " , prefix .. " *.mm " }
end
-- Put the project-specific PCH directory at the start of the
-- include path, so '#include "precompiled.h"' will look in
-- there first
local pch_dir
if not extra_params [ " pch_dir " ] then
pch_dir = source_root .. " pch/ " .. project ( ) . name .. " / "
else
pch_dir = extra_params [ " pch_dir " ]
end
includedirs { pch_dir }
-- Precompiled Headers
-- rationale: we need one PCH per static lib, since one global header would
-- increase dependencies. To that end, we can either include them as
-- "projectdir/precompiled.h", or add "source/PCH/projectdir" to the
-- include path and put the PCH there. The latter is better because
-- many projects contain several dirs and it's unclear where there the
-- PCH should be stored. This way is also a bit easier to use in that
-- source files always include "precompiled.h".
-- Notes:
-- * Visual Assist manages to use the project include path and can
-- correctly open these files from the IDE.
-- * precompiled.cpp (needed to "Create" the PCH) also goes in
-- the abovementioned dir.
if ( not _OPTIONS [ " without-pch " ] and not extra_params [ " no_pch " ] ) then
filter " action:vs* "
pchheader ( " precompiled.h " )
filter " action:xcode* "
pchheader ( " ../ " .. pch_dir .. " precompiled.h " )
filter { " action:not vs* " , " action:not xcode* " }
pchheader ( pch_dir .. " precompiled.h " )
filter { }
pchsource ( pch_dir .. " precompiled.cpp " )
2019-12-31 05:58:48 -08:00
defines { " CONFIG_ENABLE_PCH=1 " }
2017-10-30 06:52:05 -07:00
files { pch_dir .. " precompiled.h " , pch_dir .. " precompiled.cpp " }
else
2019-12-31 05:58:48 -08:00
defines { " CONFIG_ENABLE_PCH=0 " }
2017-10-30 06:52:05 -07:00
flags { " NoPCH " }
end
-- next is source root dir, for absolute (nonrelative) includes
-- (e.g. "lib/precompiled.h")
includedirs { source_root }
for i , v in pairs ( rel_include_dirs ) do
includedirs { source_root .. v }
end
if extra_params [ " extra_files " ] then
for i , v in pairs ( extra_params [ " extra_files " ] ) do
-- .rc files are only needed on Windows
if path.getextension ( v ) ~= " .rc " or os.istarget ( " windows " ) then
files { source_root .. v }
end
end
end
if extra_params [ " extra_links " ] then
links { extra_params [ " extra_links " ] }
end
end
-- Add command-line options to set up the manifest dependencies for Windows
function project_add_manifest ( )
2024-12-13 11:37:14 -08:00
-- To use XP-style themed controls, we need to use the manifest to specify the
-- desired version. (This must be set in the game's .exe in order to affect Atlas.)
-- We can remove it once we remove wxWidgets
2025-04-26 11:53:09 -07:00
if arch == " amd64 " then
linkoptions { " \" /manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' \" " }
else
linkoptions { " \" /manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' \" " }
end
2017-10-30 06:52:05 -07:00
end
--------------------------------------------------------------------------------
-- engine static libraries
--------------------------------------------------------------------------------
-- the engine is split up into several static libraries. this eases separate
-- distribution of those components, reduces dependencies a bit, and can
-- also speed up builds.
-- more to the point, it is necessary to efficiently support a separate
-- test executable that also includes much of the game code.
-- names of all static libs created. automatically added to the
-- main app project later (see explanation at end of this file)
static_lib_names = { }
static_lib_names_debug = { }
static_lib_names_release = { }
-- set up one of the static libraries into which the main engine code is split.
-- extra_params:
-- no_default_link: If specified, linking won't be done by default.
-- For the rest of extra_params, see project_add_contents().
-- note: rel_source_dirs and rel_include_dirs are relative to global source_root.
function setup_static_lib_project ( project_name , rel_source_dirs , extern_libs , extra_params )
local target_type = " StaticLib "
project_create ( project_name , target_type )
project_add_contents ( source_root , rel_source_dirs , { } , extra_params )
project_add_extern_libs ( extern_libs , target_type )
if not extra_params [ " no_default_link " ] then
table.insert ( static_lib_names , project_name )
end
2020-11-19 00:36:25 -08:00
-- Deactivate Run Time Type Information. Performance of dynamic_cast is very poor.
-- The exception to this principle is Atlas UI, which is not a static library.
rtti " off "
2025-04-26 11:53:09 -07:00
if os.istarget ( " windows " ) then
if arch == " amd64 " then
architecture ( " x86_64 " )
end
elseif os.istarget ( " macosx " ) then
2022-01-13 06:42:42 -08:00
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
if _OPTIONS [ " macosx-version-min " ] then
xcodebuildsettings { MACOSX_DEPLOYMENT_TARGET = _OPTIONS [ " macosx-version-min " ] }
end
2017-10-30 06:52:05 -07:00
end
end
function setup_third_party_static_lib_project ( project_name , rel_source_dirs , extern_libs , extra_params )
setup_static_lib_project ( project_name , rel_source_dirs , extern_libs , extra_params )
includedirs { source_root .. " third_party/ " .. project_name .. " /include/ " }
end
function setup_shared_lib_project ( project_name , rel_source_dirs , extern_libs , extra_params )
local target_type = " SharedLib "
project_create ( project_name , target_type )
project_add_contents ( source_root , rel_source_dirs , { } , extra_params )
project_add_extern_libs ( extern_libs , target_type )
if not extra_params [ " no_default_link " ] then
table.insert ( static_lib_names , project_name )
end
if os.istarget ( " windows " ) then
links { " delayimp " }
2025-04-26 11:53:09 -07:00
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2022-01-13 06:42:42 -08:00
elseif os.istarget ( " macosx " ) then
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
if _OPTIONS [ " macosx-version-min " ] then
xcodebuildsettings { MACOSX_DEPLOYMENT_TARGET = _OPTIONS [ " macosx-version-min " ] }
end
2017-10-30 06:52:05 -07:00
end
end
-- this is where the source tree is chopped up into static libs.
-- can be changed very easily; just copy+paste a new setup_static_lib_project,
-- or remove existing ones. static libs are automagically added to
-- main_exe link step.
function setup_all_libs ( )
-- relative to global source_root.
local source_dirs = { }
-- names of external libraries used (see libraries_dir comment)
local extern_libs = { }
source_dirs = {
" network " ,
}
extern_libs = {
2024-10-24 10:58:16 -07:00
" cpp_httplib " ,
2017-10-30 06:52:05 -07:00
" spidermonkey " ,
" enet " ,
Hide ip and port from users until they want to join, add optional password
Current issue with the lobby, is that we make ips of hosts public for
anyone to read. This patch consists of 3 parts.
1.) Removing ips and ports from lobby javascript
2.) Removing need of script on the server to attach public ips to game
stanza by asking the host using xmppclient as proxy.
3.) Implementing password protected matches, to deny this information to
not trusted players.
Further description:
Do not send ports and stunip to the bots.
Removed from stanza.
Do not send ip to the lobby.
Removed from mapping gamelist from backend to gui (still on the backend
side, because it is done by script on 0ad server).
Get ip and ports on request when trying to connect.
On the host side, ask stun server what is host's public ip and remember
it.
On the client side, send iq through xmppclient to the hosting player and
ask for ip, port and if Stun is used, then if answer is success,
continue
with connecting, else fail.
Add optional password for matches.
Add password required identifier to the stanza.
Allow host to setup password for the match. Hash it on the host side and
store inside Netserver. If no password is given, matches will behave
as it is not required.
On the client side, if password for the match is required, show
additional window before trying to connect and ask for password, then
hash it
and send with iq request for ip, port and stun.
Server will answer with ip, port and stun only if passwords matches,
else will asnwer with error string.
Some security:
Passwords are hashed before sending, so it is not easy to guess what
users typed. (per wraitii)
Hashes are using different salt as lobby hashing and not using usernames
as salt (as that is not doable), so they are different even typing the
same password as for the lobby account.
Client remembers which user was asked for connection data and iq's id of
request. If answer doesn't match these things, it is ignored. (thnx
user1)
Every request for connection data is logged with hostname of the
requester to the mainlog file (no ips).
If user gets iq to send connection data and is not hosting the match,
will respond with error string "not_server".
If server gets iq::result with connection data, request is ignored.
Differential revision: D3184
Reviewed by: @wraitii
Comments by: @Stan, @bb, @Imarok, @vladislavbelov
Tested in lobby
This was SVN commit r24728.
2021-01-20 10:31:39 -08:00
" sdl " ,
2021-01-06 07:26:11 -08:00
" boost " , -- dragged in via server->simulation.h->random and NetSession.h->lockfree
2020-11-26 13:01:32 -08:00
" fmt " ,
2025-06-19 15:06:41 -07:00
" libxml2 " ,
" iconv " ,
2017-10-30 06:52:05 -07:00
}
if not _OPTIONS [ " without-miniupnpc " ] then
table.insert ( extern_libs , " miniupnpc " )
end
setup_static_lib_project ( " network " , source_dirs , extern_libs , { } )
2020-08-01 03:52:59 -07:00
source_dirs = {
" rlinterface " ,
}
extern_libs = {
" boost " , -- dragged in via simulation.h and scriptinterface.h
2020-11-26 13:01:32 -08:00
" fmt " ,
2020-08-01 03:52:59 -07:00
" spidermonkey " ,
2024-10-24 10:58:16 -07:00
" cpp_httplib " ,
2020-08-01 03:52:59 -07:00
}
setup_static_lib_project ( " rlinterface " , source_dirs , extern_libs , { no_pch = 1 } )
2025-05-29 19:55:50 -07:00
if not _OPTIONS [ " without-dap-interface " ] then
source_dirs = {
" dapinterface " ,
}
extern_libs = {
" boost " , -- dragged in via simulation.h and scriptinterface.h
" fmt " ,
" spidermonkey " ,
" sockets "
}
setup_static_lib_project ( " dapinterface " , source_dirs , extern_libs , { no_pch = 1 } )
end
2017-10-30 06:52:05 -07:00
source_dirs = {
" third_party/tinygettext/src " ,
}
extern_libs = {
" iconv " ,
" boost " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2017-10-30 06:52:05 -07:00
}
setup_third_party_static_lib_project ( " tinygettext " , source_dirs , extern_libs , { } )
-- it's an external library and we don't want to modify its source to fix warnings, so we just disable them to avoid noise in the compile output
2017-11-29 13:16:10 -08:00
filter " action:vs* "
2017-10-30 06:52:05 -07:00
buildoptions {
" /wd4127 " ,
" /wd4309 " ,
" /wd4800 " ,
" /wd4100 " ,
" /wd4996 " ,
" /wd4099 " ,
" /wd4503 "
}
2017-11-29 13:16:10 -08:00
filter { }
2017-10-30 06:52:05 -07:00
if not _OPTIONS [ " without-lobby " ] then
source_dirs = {
" lobby " ,
" lobby/scripting " ,
" i18n " ,
" third_party/encryption "
}
extern_libs = {
" spidermonkey " ,
" boost " ,
" enet " ,
" gloox " ,
" icu " ,
" iconv " ,
2018-04-08 14:41:31 -07:00
" libsodium " ,
2020-11-26 13:01:32 -08:00
" tinygettext " ,
" fmt " ,
2017-10-30 06:52:05 -07:00
}
setup_static_lib_project ( " lobby " , source_dirs , extern_libs , { } )
else
source_dirs = {
" lobby/scripting " ,
" third_party/encryption "
}
extern_libs = {
" spidermonkey " ,
2018-04-08 14:41:31 -07:00
" boost " ,
2020-11-26 13:01:32 -08:00
" libsodium " ,
" fmt " ,
2017-10-30 06:52:05 -07:00
}
setup_static_lib_project ( " lobby " , source_dirs , extern_libs , { } )
files { source_root .. " lobby/Globals.cpp " }
end
source_dirs = {
" simulation2 " ,
" simulation2/components " ,
" simulation2/helpers " ,
" simulation2/scripting " ,
" simulation2/serialization " ,
" simulation2/system " ,
" simulation2/testcomponents " ,
}
extern_libs = {
" boost " ,
" spidermonkey " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2025-06-19 15:06:41 -07:00
" libxml2 " ,
" iconv " ,
2025-08-07 22:01:34 -07:00
" cxxtest " ,
2017-10-30 06:52:05 -07:00
}
setup_static_lib_project ( " simulation2 " , source_dirs , extern_libs , { } )
source_dirs = {
" scriptinterface " ,
" scriptinterface/third_party "
}
extern_libs = {
" boost " ,
" spidermonkey " ,
" valgrind " ,
" sdl " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2017-10-30 06:52:05 -07:00
}
setup_static_lib_project ( " scriptinterface " , source_dirs , extern_libs , { } )
source_dirs = {
" ps " ,
" ps/scripting " ,
" network/scripting " ,
" ps/GameSetup " ,
XMB Improvements, parse JS into XMB, make strings more efficient.
XMB format is bumped to 4, invalidating all cached files. The
differences are:
- element/attribute names are stored after the elements themselves, and
not before. This allows writing XMB data in one pass instead of two.
- names themselves becomes offsets (instead of arbitrary integers),
making getting the string from the int name much more efficient.
XMBFile is renamed to XMBData to clarify that it does not, in fact,
refer to a file on disk.
XMBData::GetElementString is also changed to return a const char*, thus
not creating an std::string. A string_view version is added where
convenient.
The XML->XMB and JS->XMB conversion functions and the corresponding
storage are moved to `ps/XMB`, since that format doesn't particularly
relate to XML. CXeromyces becomes lighter and more focused as a result.
The XML->XMB conversion also benefits from the above streamlining.
Note that in a few cases, string_view gets printed to CLogger via
data(), which is generally not legal, but we know that the strings are
null-terminated here. Our libfmt (version 4) doesn't support
string_view, that would be v5.
Differential Revision: https://code.wildfiregames.com/D3909
This was SVN commit r25375.
2021-05-04 06:02:34 -07:00
" ps/XMB " ,
2017-10-30 06:52:05 -07:00
" ps/XML " ,
" soundmanager " ,
" soundmanager/data " ,
" soundmanager/items " ,
" soundmanager/scripting " ,
" maths " ,
" maths/scripting " ,
" i18n " ,
" i18n/scripting " ,
}
extern_libs = {
" spidermonkey " ,
" sdl " , -- key definitions
" libxml2 " ,
" zlib " ,
" boost " ,
" enet " ,
" libcurl " ,
" tinygettext " ,
" icu " ,
" iconv " ,
2018-04-22 11:14:45 -07:00
" libsodium " ,
2025-08-06 14:20:49 -07:00
" libpng " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2021-12-08 14:14:43 -08:00
" freetype " ,
2024-10-24 10:58:16 -07:00
" cpp_httplib " ,
2017-10-30 06:52:05 -07:00
}
2026-03-01 07:38:33 -08:00
if not _OPTIONS [ " without-lobby " ] then
table.insert ( extern_libs , " gloox " )
end
2025-08-06 14:20:49 -07:00
if not _OPTIONS [ " without-miniupnpc " ] then
table.insert ( extern_libs , " miniupnpc " )
end
2023-04-16 15:28:55 -07:00
if not _OPTIONS [ " without-nvtt " ] then
table.insert ( extern_libs , " nvtt " )
end
2017-10-30 06:52:05 -07:00
if not _OPTIONS [ " without-audio " ] then
table.insert ( extern_libs , " openal " )
table.insert ( extern_libs , " vorbis " )
end
setup_static_lib_project ( " engine " , source_dirs , extern_libs , { } )
source_dirs = {
" graphics " ,
" graphics/scripting " ,
" renderer " ,
2021-12-14 22:43:41 -08:00
" renderer/backend " ,
2022-05-08 15:02:46 -07:00
" renderer/backend/dummy " ,
2021-12-14 22:43:41 -08:00
" renderer/backend/gl " ,
2022-05-08 15:02:46 -07:00
" renderer/backend/vulkan " ,
2017-10-30 06:52:05 -07:00
" renderer/scripting " ,
2019-12-07 03:48:03 -08:00
" third_party/mikktspace " ,
2023-01-08 15:12:54 -08:00
" third_party/ogre3d_preprocessor " ,
" third_party/vma "
2017-10-30 06:52:05 -07:00
}
extern_libs = {
" sdl " , -- key definitions
" spidermonkey " , -- for graphics/scripting
2020-11-26 13:01:32 -08:00
" boost " ,
" fmt " ,
2021-12-08 14:14:43 -08:00
" freetype " ,
2021-03-12 12:57:33 -08:00
" icu " ,
2025-06-19 15:06:41 -07:00
" libxml2 " ,
" iconv " ,
2017-10-30 06:52:05 -07:00
}
if not _OPTIONS [ " without-nvtt " ] then
table.insert ( extern_libs , " nvtt " )
end
setup_static_lib_project ( " graphics " , source_dirs , extern_libs , { } )
source_dirs = {
" tools/atlas/GameInterface " ,
" tools/atlas/GameInterface/Handlers "
}
extern_libs = {
" boost " ,
" sdl " , -- key definitions
2020-11-26 13:01:32 -08:00
" spidermonkey " ,
" fmt " ,
2025-06-19 15:06:41 -07:00
" libxml2 " ,
" iconv " ,
2017-10-30 06:52:05 -07:00
}
setup_static_lib_project ( " atlas " , source_dirs , extern_libs , { } )
source_dirs = {
" gui " ,
2019-10-02 02:44:00 -07:00
" gui/ObjectTypes " ,
" gui/ObjectBases " ,
" gui/Scripting " ,
" gui/SettingTypes " ,
2017-10-30 06:52:05 -07:00
" i18n "
}
extern_libs = {
" spidermonkey " ,
" sdl " , -- key definitions
" boost " ,
" enet " ,
" tinygettext " ,
" icu " ,
" iconv " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2025-06-19 15:06:41 -07:00
" libxml2 " ,
2017-10-30 06:52:05 -07:00
}
if not _OPTIONS [ " without-audio " ] then
table.insert ( extern_libs , " openal " )
end
setup_static_lib_project ( " gui " , source_dirs , extern_libs , { } )
source_dirs = {
" lib " ,
" lib/adts " ,
" lib/allocators " ,
" lib/external_libraries " ,
" lib/file " ,
" lib/file/archive " ,
" lib/file/common " ,
" lib/file/io " ,
" lib/file/vfs " ,
" lib/pch " ,
" lib/posix " ,
" lib/res " ,
" lib/res/graphics " ,
" lib/sysdep " ,
" lib/tex "
}
extern_libs = {
" boost " ,
" sdl " ,
" openal " ,
" libpng " ,
" zlib " ,
" valgrind " ,
" cxxtest " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2017-10-30 06:52:05 -07:00
}
-- CPU architecture-specific
if arch == " amd64 " then
table.insert ( source_dirs , " lib/sysdep/arch/amd64 " ) ;
table.insert ( source_dirs , " lib/sysdep/arch/x86_x64 " ) ;
elseif arch == " x86 " then
table.insert ( source_dirs , " lib/sysdep/arch/ia32 " ) ;
table.insert ( source_dirs , " lib/sysdep/arch/x86_x64 " ) ;
elseif arch == " arm " then
table.insert ( source_dirs , " lib/sysdep/arch/arm " ) ;
elseif arch == " aarch64 " then
table.insert ( source_dirs , " lib/sysdep/arch/aarch64 " ) ;
2020-12-31 07:52:12 -08:00
elseif arch == " e2k " then
table.insert ( source_dirs , " lib/sysdep/arch/e2k " ) ;
2026-03-05 14:38:44 -08:00
elseif arch == " loong64 " then
table.insert ( source_dirs , " lib/sysdep/arch/loong64 " ) ;
2021-03-03 07:13:47 -08:00
elseif arch == " ppc64 " then
table.insert ( source_dirs , " lib/sysdep/arch/ppc64 " ) ;
2026-03-05 14:38:44 -08:00
elseif arch == " riscv64 " then
table.insert ( source_dirs , " lib/sysdep/arch/riscv64 " ) ;
2017-10-30 06:52:05 -07:00
end
-- OS-specific
sysdep_dirs = {
linux = { " lib/sysdep/os/linux " , " lib/sysdep/os/unix " } ,
-- note: RC file must be added to main_exe project.
-- note: don't add "lib/sysdep/os/win/aken.cpp" because that must be compiled with the DDK.
windows = { " lib/sysdep/os/win " , " lib/sysdep/os/win/wposix " , " lib/sysdep/os/win/whrt " } ,
macosx = { " lib/sysdep/os/osx " , " lib/sysdep/os/unix " } ,
bsd = { " lib/sysdep/os/bsd " , " lib/sysdep/os/unix " , " lib/sysdep/os/unix/x " } ,
}
for i , v in pairs ( sysdep_dirs [ os.target ( ) ] ) do
table.insert ( source_dirs , v ) ;
end
if os.istarget ( " linux " ) then
if _OPTIONS [ " android " ] then
table.insert ( source_dirs , " lib/sysdep/os/android " )
else
table.insert ( source_dirs , " lib/sysdep/os/unix/x " )
end
end
-- On OSX, disable precompiled headers because C++ files and Objective-C++ files are
-- mixed in this project. To fix that, we would need per-file basis configuration which
-- is not yet supported by the gmake action in premake. We should look into using gmake2.
extra_params = { }
if os.istarget ( " macosx " ) then
extra_params = { no_pch = 1 }
end
-- runtime-library-specific
2024-11-02 06:09:34 -07:00
if _ACTION == " vs2022 " then
2017-10-30 06:52:05 -07:00
table.insert ( source_dirs , " lib/sysdep/rtl/msc " ) ;
2017-11-29 14:37:09 -08:00
else
2017-10-30 06:52:05 -07:00
table.insert ( source_dirs , " lib/sysdep/rtl/gcc " ) ;
2017-11-29 14:37:09 -08:00
end
2017-10-30 06:52:05 -07:00
setup_static_lib_project ( " lowlevel " , source_dirs , extern_libs , extra_params )
2022-09-01 13:44:49 -07:00
extern_libs = { " glad " }
if not os.istarget ( " windows " ) and not _OPTIONS [ " android " ] and not os.istarget ( " macosx " ) then
2024-09-08 00:18:45 -07:00
table.insert ( extern_libs , " x11 " )
2023-04-16 10:05:30 -07:00
end
2024-09-08 00:18:45 -07:00
setup_static_lib_project ( " gladwrapper " , { } , extern_libs , { no_pch = 1 } )
-- select files to build for the current platform
glad_path = third_party_source_dir .. " glad/ "
2023-01-08 15:12:54 -08:00
files { glad_path .. " src/vulkan.cpp " }
2021-12-21 14:03:31 -08:00
if _OPTIONS [ " gles " ] then
files { glad_path .. " src/gles2.cpp " }
else
files { glad_path .. " src/gl.cpp " }
if os.istarget ( " windows " ) then
files { glad_path .. " src/wgl.cpp " }
elseif os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
2022-06-09 14:09:32 -07:00
files { glad_path .. " src/egl.cpp " , glad_path .. " src/glx.cpp " }
2021-12-21 14:03:31 -08:00
end
end
2024-09-08 00:26:46 -07:00
-- on Windows, silence a build warning in vulkan.cpp
filter " action:vs* "
buildoptions { " /wd4551 " }
filter { }
2017-10-30 06:52:05 -07:00
end
--------------------------------------------------------------------------------
-- main EXE
--------------------------------------------------------------------------------
-- used for main EXE as well as test
used_extern_libs = {
" sdl " ,
" libpng " ,
" zlib " ,
" spidermonkey " ,
" libxml2 " ,
" boost " ,
2024-10-24 10:58:16 -07:00
" cpp_httplib " ,
2017-10-30 06:52:05 -07:00
" cxxtest " ,
" comsuppw " ,
" enet " ,
" libcurl " ,
" tinygettext " ,
" icu " ,
" iconv " ,
2018-04-08 14:41:31 -07:00
" libsodium " ,
2020-11-26 13:01:32 -08:00
" fmt " ,
2021-12-08 14:14:43 -08:00
" freetype " ,
2017-10-30 06:52:05 -07:00
" valgrind " ,
2025-06-02 10:08:59 -07:00
" oleaut32 " ,
2017-10-30 06:52:05 -07:00
}
if not os.istarget ( " windows " ) and not _OPTIONS [ " android " ] and not os.istarget ( " macosx " ) then
-- X11 should only be linked on *nix
table.insert ( used_extern_libs , " x11 " )
end
if not _OPTIONS [ " without-audio " ] then
table.insert ( used_extern_libs , " openal " )
table.insert ( used_extern_libs , " vorbis " )
end
if not _OPTIONS [ " without-nvtt " ] then
table.insert ( used_extern_libs , " nvtt " )
end
if not _OPTIONS [ " without-lobby " ] then
table.insert ( used_extern_libs , " gloox " )
end
if not _OPTIONS [ " without-miniupnpc " ] then
table.insert ( used_extern_libs , " miniupnpc " )
end
-- Bundles static libs together with main.cpp and builds game executable.
function setup_main_exe ( )
local target_type = get_main_project_target_type ( )
project_create ( " pyrogenesis " , target_type )
filter " system:not macosx "
linkgroups ' On '
filter { }
local extra_params = {
extra_files = { " main.cpp " } ,
no_pch = 1
}
project_add_contents ( source_root , { } , { } , extra_params )
project_add_extern_libs ( used_extern_libs , target_type )
dependson { " Collada " }
2020-11-19 00:36:25 -08:00
rtti " off "
2017-10-30 06:52:05 -07:00
-- Platform Specifics
if os.istarget ( " windows " ) then
files { source_root .. " lib/sysdep/os/win/icon.rc " }
2024-08-26 06:12:12 -07:00
files { source_root .. " lib/sysdep/os/win/pyrogenesis.rc " }
2017-10-30 06:52:05 -07:00
-- from "lowlevel" static lib; must be added here to be linked in
files { source_root .. " lib/sysdep/os/win/error_dialog.rc " }
linkoptions {
-- wraps main thread in a __try block(see wseh.cpp). replace with mainCRTStartup if that's undesired.
" /ENTRY:wseh_EntryPoint " ,
}
2023-06-23 04:55:33 -07:00
links { " delayimp " }
2024-11-25 09:19:36 -08:00
if arch == " x86 " then
-- allow the executable to use more than 2GB of RAM.
2017-10-30 06:52:05 -07:00
linkoptions { " /LARGEADDRESSAWARE " }
end
-- see manifest.cpp
2025-04-26 11:53:09 -07:00
project_add_manifest ( arch )
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2017-10-30 06:52:05 -07:00
elseif os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
if not _OPTIONS [ " android " ] and not ( os.getversion ( ) . description == " OpenBSD " ) then
links { " rt " }
end
if _OPTIONS [ " android " ] then
-- NDK's STANDALONE-TOOLCHAIN.html says this is required
linkoptions { " -Wl,--fix-cortex-a8 " }
links { " log " }
end
2020-06-23 08:06:57 -07:00
if link_execinfo then
links {
" execinfo "
}
end
2017-10-30 06:52:05 -07:00
if os.istarget ( " linux " ) or os.getversion ( ) . description == " GNU/kFreeBSD " then
links {
-- Dynamic libraries (needed for linking for gold)
" dl " ,
}
2026-03-05 14:38:44 -08:00
if arch == " riscv64 " then
-- Needed to resolve __atomic_load_16 et al.
links { " atomic " }
end
2017-10-30 06:52:05 -07:00
end
-- Threading support
buildoptions { " -pthread " }
if not _OPTIONS [ " android " ] then
linkoptions { " -pthread " }
end
-- For debug_resolve_symbol
filter " Debug "
linkoptions { " -rdynamic " }
filter { }
elseif os.istarget ( " macosx " ) then
links { " pthread " }
links { " ApplicationServices.framework " , " Cocoa.framework " , " CoreFoundation.framework " }
2022-01-13 06:42:42 -08:00
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
2019-05-25 01:28:35 -07:00
if _OPTIONS [ " macosx-version-min " ] then
xcodebuildsettings { MACOSX_DEPLOYMENT_TARGET = _OPTIONS [ " macosx-version-min " ] }
end
2017-10-30 06:52:05 -07:00
end
end
--------------------------------------------------------------------------------
-- atlas
--------------------------------------------------------------------------------
-- setup a typical Atlas component project
-- extra_params, rel_source_dirs and rel_include_dirs: as in project_add_contents;
function setup_atlas_project ( project_name , target_type , rel_source_dirs , rel_include_dirs , extern_libs , extra_params )
local source_root = rootdir .. " /source/tools/atlas/ " .. project_name .. " / "
project_create ( project_name , target_type )
-- if not specified, the default for atlas pch files is in the project root.
if not extra_params [ " pch_dir " ] then
extra_params [ " pch_dir " ] = source_root
end
project_add_contents ( source_root , rel_source_dirs , rel_include_dirs , extra_params )
project_add_extern_libs ( extern_libs , target_type )
-- Platform Specifics
if os.istarget ( " windows " ) then
-- Link to required libraries
2020-11-27 01:40:45 -08:00
links { " winmm " , " delayimp " }
2025-04-26 11:53:09 -07:00
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2017-10-30 06:52:05 -07:00
2022-01-13 06:42:42 -08:00
elseif os.istarget ( " macosx " ) then
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
if _OPTIONS [ " macosx-version-min " ] then
xcodebuildsettings { MACOSX_DEPLOYMENT_TARGET = _OPTIONS [ " macosx-version-min " ] }
end
2017-10-30 06:52:05 -07:00
elseif os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
2021-01-19 08:59:53 -08:00
if os.getversion ( ) . description == " FreeBSD " then
buildoptions { " -fPIC " }
linkoptions { " -fPIC " }
else
2024-10-16 10:36:50 -07:00
buildoptions { " -fPIC " }
2021-01-19 08:59:53 -08:00
linkoptions { " -fPIC " , " -rdynamic " }
end
2017-10-30 06:52:05 -07:00
-- warnings triggered by wxWidgets
buildoptions { " -Wno-unused-local-typedefs " }
end
end
-- build all Atlas component projects
function setup_atlas_projects ( )
setup_atlas_project ( " AtlasObject " , " StaticLib " ,
{ -- src
" . " ,
} , { -- include
2025-08-09 12:17:38 -07:00
" ../../../ " ,
2017-10-30 06:52:05 -07:00
} , { -- extern_libs
" boost " ,
" iconv " ,
2025-08-09 12:17:38 -07:00
" libxml2 " ,
" sdl " ,
" spidermonkey " ,
" cxxtest " ,
2017-10-30 06:52:05 -07:00
} , { -- extra_params
no_pch = 1
} )
atlas_src = {
" ActorEditor " ,
" CustomControls/Buttons " ,
" CustomControls/Canvas " ,
" CustomControls/ColorDialog " ,
" CustomControls/DraggableListCtrl " ,
" CustomControls/EditableListCtrl " ,
" CustomControls/FileHistory " ,
" CustomControls/HighResTimer " ,
" CustomControls/MapDialog " ,
2020-07-20 19:08:50 -07:00
" CustomControls/MapResizeDialog " ,
2017-10-30 06:52:05 -07:00
" CustomControls/SnapSplitterWindow " ,
" CustomControls/VirtualDirTreeCtrl " ,
" CustomControls/Windows " ,
" General " ,
" General/VideoRecorder " ,
" Misc " ,
" ScenarioEditor " ,
" ScenarioEditor/Sections/Common " ,
" ScenarioEditor/Sections/Cinema " ,
" ScenarioEditor/Sections/Environment " ,
" ScenarioEditor/Sections/Map " ,
" ScenarioEditor/Sections/Object " ,
" ScenarioEditor/Sections/Player " ,
" ScenarioEditor/Sections/Terrain " ,
" ScenarioEditor/Tools " ,
" ScenarioEditor/Tools/Common " ,
}
atlas_extra_links = {
" AtlasObject "
}
atlas_extern_libs = {
" boost " ,
" comsuppw " ,
" iconv " ,
" libxml2 " ,
" sdl " , -- key definitions
" wxwidgets " ,
" zlib " ,
}
if not os.istarget ( " windows " ) and not os.istarget ( " macosx " ) then
-- X11 should only be linked on *nix
table.insert ( atlas_extern_libs , " x11 " )
end
setup_atlas_project ( " AtlasUI " , " SharedLib " , atlas_src ,
{ -- include
2025-08-08 12:04:43 -07:00
" ../../.. " ,
2017-10-30 06:52:05 -07:00
} ,
atlas_extern_libs ,
{ -- extra_params
pch_dir = rootdir .. " /source/tools/atlas/AtlasUI/Misc/ " ,
no_pch = false ,
extra_links = atlas_extra_links ,
extra_files = { " Misc/atlas.rc " }
} )
end
-- Atlas 'frontend' tool-launching projects
function setup_atlas_frontend_project ( project_name )
local target_type = get_main_project_target_type ( )
project_create ( project_name , target_type )
local source_root = rootdir .. " /source/tools/atlas/AtlasFrontends/ "
files { source_root .. project_name .. " .cpp " }
if os.istarget ( " windows " ) then
files { source_root .. project_name .. " .rc " }
end
includedirs { source_root .. " .. " }
-- Platform Specifics
if os.istarget ( " windows " ) then
-- see manifest.cpp
2025-04-26 11:53:09 -07:00
project_add_manifest ( arch )
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2017-10-30 06:52:05 -07:00
else -- Non-Windows, = Unix
links { " AtlasObject " }
2022-01-13 06:42:42 -08:00
if os.istarget ( " macosx " ) then
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
end
2017-10-30 06:52:05 -07:00
end
links { " AtlasUI " }
end
function setup_atlas_frontends ( )
setup_atlas_frontend_project ( " ActorEditor " )
end
--------------------------------------------------------------------------------
-- collada
--------------------------------------------------------------------------------
function setup_collada_project ( project_name , target_type , rel_source_dirs , rel_include_dirs , extern_libs , extra_params )
project_create ( project_name , target_type )
local source_root = source_root .. " collada/ "
extra_params [ " pch_dir " ] = source_root
project_add_contents ( source_root , rel_source_dirs , rel_include_dirs , extra_params )
project_add_extern_libs ( extern_libs , target_type )
-- Platform Specifics
2017-11-29 12:14:22 -08:00
if os.istarget ( " windows " ) then
characterset " MBCS "
2025-04-26 11:53:09 -07:00
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2017-11-29 12:14:22 -08:00
elseif os.istarget ( " linux " ) then
2017-10-30 06:52:05 -07:00
defines { " LINUX " }
links {
" dl " ,
}
-- FCollada is not aliasing-safe, so disallow dangerous optimisations
-- (TODO: It'd be nice to fix FCollada, but that looks hard)
buildoptions { " -fno-strict-aliasing " }
2021-01-19 08:59:53 -08:00
if os.getversion ( ) . description ~= " FreeBSD " then
linkoptions { " -rdynamic " }
end
2017-10-30 06:52:05 -07:00
elseif os.istarget ( " bsd " ) then
if os.getversion ( ) . description == " OpenBSD " then
links { " c " , }
end
if os.getversion ( ) . description == " GNU/kFreeBSD " then
links {
" dl " ,
}
end
buildoptions { " -fno-strict-aliasing " }
linkoptions { " -rdynamic " }
elseif os.istarget ( " macosx " ) then
-- define MACOS-something?
buildoptions { " -fno-strict-aliasing " }
-- On OSX, fcollada uses a few utility functions from coreservices
links { " CoreServices.framework " }
2022-01-13 06:42:42 -08:00
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
2017-10-30 06:52:05 -07:00
end
end
-- build all Collada component projects
function setup_collada_projects ( )
setup_collada_project ( " Collada " , " SharedLib " ,
{ -- src
" . "
} , { -- include
} , { -- extern_libs
" fcollada " ,
2025-04-26 11:53:20 -07:00
" iconv " ,
2017-10-30 06:52:05 -07:00
" libxml2 "
} , { -- extra_params
} )
end
--------------------------------------------------------------------------------
-- tests
--------------------------------------------------------------------------------
2017-12-10 03:17:43 -08:00
function setup_tests ( )
2017-10-30 06:52:05 -07:00
2017-12-10 03:17:43 -08:00
local cxxtest = require " cxxtest "
2017-10-30 06:52:05 -07:00
2017-12-10 03:17:43 -08:00
if os.istarget ( " windows " ) then
cxxtest.setpath ( rootdir .. " /build/bin/cxxtestgen.exe " )
2017-10-30 06:52:05 -07:00
else
2024-09-18 10:49:16 -07:00
if _OPTIONS [ " with-system-cxxtest " ] then
local handle = io.popen ( " command -v cxxtestgen " )
local cxxtestgen = handle : read ( " *a " ) : gsub ( " \n " , " " )
handle : close ( )
cxxtest.setpath ( cxxtestgen )
else
cxxtest.setpath ( rootdir .. " /libraries/source/cxxtest-4.4/bin/cxxtestgen " )
end
2017-10-30 06:52:05 -07:00
end
2023-07-18 13:21:59 -07:00
local include_files = {
2017-12-10 03:17:43 -08:00
-- Precompiled headers - the header is added to all generated .cpp files
-- note that the header isn't actually precompiled here, only #included
-- so that the build stage can use it as a precompiled header.
" precompiled.h " ,
}
2023-07-18 13:21:59 -07:00
local test_root_include_files = {
" precompiled.h " ,
}
if os.istarget ( " windows " ) then
-- This is required to build against SDL 2.0.12 (starting from 2.0.4) on Windows.
-- Refs #3138
table.insert ( test_root_include_files , " lib/external_libraries/libsdl.h " )
end
2017-12-10 03:17:43 -08:00
2025-10-07 10:26:56 -07:00
cxxtest.init ( true , true , nil , include_files , test_root_include_files )
2017-12-10 03:17:43 -08:00
local target_type = get_main_project_target_type ( )
project_create ( " test " , target_type )
2017-10-30 06:52:05 -07:00
-- Find header files in 'test' subdirectories
local all_files = os.matchfiles ( source_root .. " **/tests/*.h " )
local test_files = { }
for i , v in pairs ( all_files ) do
-- Don't include sysdep tests on the wrong sys
-- Don't include Atlas tests unless Atlas is being built
if not ( string.find ( v , " /sysdep/os/win/ " ) and not os.istarget ( " windows " ) ) and
2024-12-13 23:00:14 -08:00
not ( string.find ( v , " /tools/atlas/ " ) and _OPTIONS [ " without-atlas " ] ) and
2017-10-30 06:52:05 -07:00
not ( string.find ( v , " /sysdep/arch/x86_x64/ " ) and ( ( arch ~= " amd64 " ) or ( arch ~= " x86 " ) ) )
then
table.insert ( test_files , v )
end
end
2017-12-10 03:17:43 -08:00
cxxtest.configure_project ( test_files )
2017-10-30 06:52:05 -07:00
filter " system:not macosx "
linkgroups ' On '
filter { }
links { static_lib_names }
filter " Debug "
links { static_lib_names_debug }
filter " Release "
links { static_lib_names_release }
filter { }
2024-12-13 23:00:14 -08:00
if not _OPTIONS [ " without-atlas " ] then
2017-10-30 06:52:05 -07:00
links { " AtlasObject " }
end
extra_params = {
extra_files = { " test_setup.cpp " } ,
}
project_add_contents ( source_root , { } , { } , extra_params )
project_add_extern_libs ( used_extern_libs , target_type )
dependson { " Collada " }
2020-11-19 00:36:25 -08:00
rtti " off "
2017-10-30 06:52:05 -07:00
-- TODO: should fix the duplication between this OS-specific linking
-- code, and the similar version in setup_main_exe
if os.istarget ( " windows " ) then
-- from "lowlevel" static lib; must be added here to be linked in
files { source_root .. " lib/sysdep/os/win/error_dialog.rc " }
-- Enables console for the TEST project on Windows
linkoptions { " /SUBSYSTEM:CONSOLE " }
2023-07-05 13:31:56 -07:00
links { " delayimp " }
2025-04-26 11:53:09 -07:00
project_add_manifest ( arch )
if arch == " amd64 " then
architecture ( " x86_64 " )
end
2017-10-30 06:52:05 -07:00
elseif os.istarget ( " linux " ) or os.istarget ( " bsd " ) then
2020-06-23 08:06:57 -07:00
if link_execinfo then
links {
" execinfo "
}
end
2017-10-30 06:52:05 -07:00
if not _OPTIONS [ " android " ] and not ( os.getversion ( ) . description == " OpenBSD " ) then
links { " rt " }
end
if _OPTIONS [ " android " ] then
-- NDK's STANDALONE-TOOLCHAIN.html says this is required
linkoptions { " -Wl,--fix-cortex-a8 " }
end
if os.istarget ( " linux " ) or os.getversion ( ) . description == " GNU/kFreeBSD " then
links {
-- Dynamic libraries (needed for linking for gold)
" dl " ,
}
2026-03-05 14:38:44 -08:00
if arch == " riscv64 " then
-- Needed to resolve __atomic_load_16 et al.
links { " atomic " }
end
2017-10-30 06:52:05 -07:00
end
-- Threading support
buildoptions { " -pthread " }
if not _OPTIONS [ " android " ] then
linkoptions { " -pthread " }
end
-- For debug_resolve_symbol
filter " Debug "
linkoptions { " -rdynamic " }
filter { }
includedirs { source_root .. " pch/test/ " }
2019-05-25 01:28:35 -07:00
2022-01-13 06:42:42 -08:00
elseif os.istarget ( " macosx " ) then
architecture ( macos_arch )
buildoptions { " -arch " .. macos_arch }
linkoptions { " -arch " .. macos_arch }
xcodebuildsettings { ARCHS = macos_arch }
if _OPTIONS [ " macosx-version-min " ] then
xcodebuildsettings { MACOSX_DEPLOYMENT_TARGET = _OPTIONS [ " macosx-version-min " ] }
end
2017-10-30 06:52:05 -07:00
end
end
-- must come first, so that VC sets it as the default project and therefore
-- allows running via F5 without the "where is the EXE" dialog.
setup_main_exe ( )
setup_all_libs ( )
-- add the static libs to the main EXE project. only now (after
-- setup_all_libs has run) are the lib names known. cannot move
-- setup_main_exe to run after setup_all_libs (see comment above).
-- we also don't want to hardcode the names - that would require more
-- work when changing the static lib breakdown.
project ( " pyrogenesis " ) -- Set the main project active
links { static_lib_names }
filter " Debug "
links { static_lib_names_debug }
filter " Release "
links { static_lib_names_release }
filter { }
2024-12-13 23:00:14 -08:00
if not _OPTIONS [ " without-atlas " ] then
2017-10-30 06:52:05 -07:00
setup_atlas_projects ( )
setup_atlas_frontends ( )
end
setup_collada_projects ( )
if not _OPTIONS [ " without-tests " ] then
setup_tests ( )
end