Index: ps/trunk/build/premake/premake5.lua =================================================================== --- ps/trunk/build/premake/premake5.lua (revision 27082) +++ ps/trunk/build/premake/premake5.lua (revision 27083) @@ -1,1545 +1,1550 @@ newoption { trigger = "android", description = "Use non-working Android cross-compiling mode" } newoption { trigger = "atlas", description = "Include Atlas scenario editor projects" } newoption { trigger = "coverage", description = "Enable code coverage data collection (GCC only)" } newoption { trigger = "gles", description = "Use non-working OpenGL ES 2.0 mode" } newoption { trigger = "icc", description = "Use Intel C++ Compiler (Linux only; should use either \"--cc icc\" or --without-pch too, and then set CXX=icpc before calling make)" } newoption { trigger = "jenkins-tests", description = "Configure CxxTest to use the XmlPrinter runner which produces Jenkins-compatible output" } newoption { trigger = "minimal-flags", description = "Only set compiler/linker flags that are really needed. Has no effect on Windows builds" } newoption { trigger = "outpath", description = "Location for generated project files" } newoption { trigger = "with-system-mozjs", description = "Search standard paths for libmozjs60, instead of using bundled copy" } newoption { trigger = "with-system-nvtt", description = "Search standard paths for nvidia-texture-tools library, instead of using bundled copy" } newoption { trigger = "with-valgrind", description = "Enable Valgrind support (non-Windows only)" } newoption { trigger = "without-audio", description = "Disable use of OpenAL/Ogg/Vorbis APIs" } newoption { trigger = "without-lobby", description = "Disable the use of gloox and the multiplayer lobby" } newoption { trigger = "without-miniupnpc", description = "Disable use of miniupnpc for port forwarding" } newoption { trigger = "without-nvtt", description = "Disable use of NVTT" } newoption { trigger = "without-pch", description = "Disable generation and usage of precompiled headers" } newoption { trigger = "without-tests", description = "Disable generation of test projects" } -- Linux/BSD specific options newoption { trigger = "prefer-local-libs", description = "Prefer locally built libs. Any local libraries used must also be listed within a file within /etc/ld.so.conf.d so the dynamic linker can find them at runtime." } -- OS X specific options newoption { 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 { trigger = "sysroot", description = "Set compiler system root path, used for building against a non-system SDK. For example /usr/local becomes SYSROOT/user/local" } -- Windows specific options newoption { trigger = "build-shared-glooxwrapper", description = "Rebuild glooxwrapper DLL for Windows. Requires the same compiler version that gloox was built with" } newoption { trigger = "use-shared-glooxwrapper", description = "Use prebuilt glooxwrapper DLL for Windows" } newoption { trigger = "large-address-aware", description = "Make the executable large address aware. Do not use for development, in order to spot memory issues easily" } -- Install options newoption { trigger = "bindir", description = "Directory for executables (typically '/usr/games'); default is to be relocatable" } newoption { trigger = "datadir", description = "Directory for data files (typically '/usr/share/games/0ad'); default is ../data/ relative to executable" } newoption { trigger = "libdir", description = "Directory for libraries (typically '/usr/lib/games/0ad'); default is ./ relative to executable" } -- Root directory of project checkout relative to this .lua file rootdir = "../.." dofile("extern_libs5.lua") -- detect compiler for non-Windows if os.istarget("macosx") then cc = "clang" elseif os.istarget("linux") and _OPTIONS["icc"] then cc = "icc" elseif os.istarget("bsd") and os.getversion().description == "FreeBSD" then cc = "clang" elseif not os.istarget("windows") then cc = os.getenv("CC") if cc == nil or cc == "" then local hasgcc = os.execute("which gcc > .gccpath") local f = io.open(".gccpath", "r") local gccpath = f:read("*line") f:close() os.execute("rm .gccpath") if gccpath == nil then cc = "clang" else cc = "gcc" end end end -- detect CPU architecture (simplistic) -- The user can target an architecture with HOSTTYPE, but the game still selects some know value. arch = "x86" macos_arch = "x86_64" if _OPTIONS["android"] then arch = "arm" elseif os.istarget("windows") then if os.getenv("HOSTTYPE") then arch = os.getenv("HOSTTYPE") elseif os.getenv("PROCESSOR_ARCHITECTURE") == "amd64" or os.getenv("PROCESSOR_ARCHITEW6432") == "amd64" then arch = "amd64" end else 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 -- Special handling on mac os where xcode needs special flags. if os.istarget("macosx") then if string.find(machine, "arm64") then arch = "aarch64" macos_arch = "arm64" else arch = "amd64" macos_arch = "x86_64" end 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" elseif string.find(machine, "ppc64") == 1 or string.find(machine, "powerpc64") == 1 then arch = "ppc64" else print("WARNING: Cannot determine architecture from GCC, assuming x86") end end -- 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 -- Set up the Workspace workspace "pyrogenesis" targetdir(rootdir.."/binaries/system") libdirs(rootdir.."/binaries/system") if not _OPTIONS["outpath"] then error("You must specify the 'outpath' parameter") end location(_OPTIONS["outpath"]) configurations { "Release", "Debug" } 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" if not _OPTIONS["minimal-flags"] then symbols "On" end if cc ~= "icc" and (os.istarget("windows") or not _OPTIONS["minimal-flags"]) then -- adds the -Wall compiler flag warnings "Extra" -- this causes far too many warnings/remarks on ICC end -- 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 filter "Debug" defines { "DEBUG" } filter "Release" if os.istarget("windows") or not _OPTIONS["minimal-flags"] then optimize "Speed" end defines { "NDEBUG", "CONFIG_FINAL=1" } filter { } 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 -- Enable C++17 standard. filter "action:vs*" buildoptions { "/std:c++17" } filter "action:not vs*" buildoptions { "-std=c++17" } filter {} -- various platform-specific build flags if os.istarget("windows") then flags { "MultiProcessorCompile" } -- 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" -- use native wchar_t type (not typedef to unsigned short) nativewchar "on" else -- *nix -- TODO, FIXME: This check is incorrect because it means that some additional flags will be added inside the "else" branch if the -- compiler is ICC and minimal-flags is specified (ticket: #2994) if cc == "icc" and not _OPTIONS["minimal-flags"] then buildoptions { "-w1", -- "-Wabi", -- "-Wp64", -- complains about OBJECT_TO_JSVAL which is annoying "-Wpointer-arith", "-Wreturn-type", -- "-Wshadow", "-Wuninitialized", "-Wunknown-pragmas", "-Wunused-function", "-wd1292" -- avoid lots of 'attribute "__nonnull__" ignored' } filter "Debug" buildoptions { "-O0" } -- ICC defaults to -O2 filter { } if os.istarget("macosx") then linkoptions { "-multiply_defined","suppress" } end else -- exclude most non-essential build options for minimal-flags if not _OPTIONS["minimal-flags"] then buildoptions { -- enable most of the standard warnings "-Wno-switch", -- enumeration value not handled in switch (this is sometimes useful, but results in lots of noise) "-Wno-reorder", -- order of initialization list in constructors (lots of noise) "-Wno-invalid-offsetof", -- offsetof on non-POD types (see comment in renderer/PatchRData.cpp) "-Wextra", "-Wno-missing-field-initializers", -- (this is common in external headers we can't fix) -- 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) -- enable security features (stack checking etc) that shouldn't have -- a significant effect on performance and can catch bugs "-fstack-protector-all", "-U_FORTIFY_SOURCE", -- (avoid redefinition warning if already defined) "-D_FORTIFY_SOURCE=2", -- 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" } 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" } end if os.istarget("linux") or os.istarget("bsd") then buildoptions { "-fPIC" } linkoptions { "-Wl,--no-undefined", "-Wl,--as-needed", "-Wl,-z,relro" } end 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" } end end 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" } end end if _OPTIONS["coverage"] then buildoptions { "-fprofile-arcs", "-ftest-coverage" } links { "gcov" } end -- 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++" } end 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 if _OPTIONS["prefer-local-libs"] then libdirs { "/usr/local/lib" } end -- 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 if _ACTION == "gmake" then 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++" kind(target_type) filter "action:vs2017" toolset "v141_xp" filter {} filter "action:vs*" buildoptions "/utf-8" filter {} 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 -- /pch//. -- * 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") defines { "CONFIG_ENABLE_PCH=1" } files { pch_dir.."precompiled.h", pch_dir.."precompiled.cpp" } else defines { "CONFIG_ENABLE_PCH=0" } 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 -- (See lib/sysdep/os/win/manifest.cpp) function project_add_manifest() linkoptions { "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df'\"" } 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 -- 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" if 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 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" } 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 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 = { "spidermonkey", "enet", "sdl", "boost", -- dragged in via server->simulation.h->random and NetSession.h->lockfree "fmt", } if not _OPTIONS["without-miniupnpc"] then table.insert(extern_libs, "miniupnpc") end setup_static_lib_project("network", source_dirs, extern_libs, {}) source_dirs = { "rlinterface", } extern_libs = { "boost", -- dragged in via simulation.h and scriptinterface.h "fmt", "spidermonkey", } setup_static_lib_project("rlinterface", source_dirs, extern_libs, { no_pch = 1 }) source_dirs = { "third_party/tinygettext/src", } extern_libs = { "iconv", "boost", "fmt", } 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 filter "action:vs*" buildoptions { "/wd4127", "/wd4309", "/wd4800", "/wd4100", "/wd4996", "/wd4099", "/wd4503" } filter {} if not _OPTIONS["without-lobby"] then source_dirs = { "lobby", "lobby/scripting", "i18n", "third_party/encryption" } extern_libs = { "spidermonkey", "boost", "enet", "gloox", "icu", "iconv", "libsodium", "tinygettext", "fmt", } setup_static_lib_project("lobby", source_dirs, extern_libs, {}) if _OPTIONS["use-shared-glooxwrapper"] and not _OPTIONS["build-shared-glooxwrapper"] then table.insert(static_lib_names_debug, "glooxwrapper_dbg") table.insert(static_lib_names_release, "glooxwrapper") else source_dirs = { "lobby/glooxwrapper", } extern_libs = { "boost", "gloox", "fmt", } if _OPTIONS["build-shared-glooxwrapper"] then setup_shared_lib_project("glooxwrapper", source_dirs, extern_libs, {}) else setup_static_lib_project("glooxwrapper", source_dirs, extern_libs, {}) end end else source_dirs = { "lobby/scripting", "third_party/encryption" } extern_libs = { "spidermonkey", "boost", "libsodium", "fmt", } 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", "fmt", } setup_static_lib_project("simulation2", source_dirs, extern_libs, {}) source_dirs = { "scriptinterface", "scriptinterface/third_party" } extern_libs = { "boost", "spidermonkey", "valgrind", "sdl", "fmt", } setup_static_lib_project("scriptinterface", source_dirs, extern_libs, {}) source_dirs = { "ps", "ps/scripting", "network/scripting", "ps/GameSetup", "ps/XMB", "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", "libsodium", "fmt", "freetype", } 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", "renderer/backend", "renderer/backend/dummy", "renderer/backend/gl", "renderer/backend/vulkan", "renderer/scripting", "third_party/mikktspace", "third_party/ogre3d_preprocessor" } extern_libs = { "sdl", -- key definitions "spidermonkey", -- for graphics/scripting "boost", "fmt", "freetype", "icu", } 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 "spidermonkey", "fmt", } setup_static_lib_project("atlas", source_dirs, extern_libs, {}) source_dirs = { "gui", "gui/ObjectTypes", "gui/ObjectBases", "gui/Scripting", "gui/SettingTypes", "i18n" } extern_libs = { "spidermonkey", "sdl", -- key definitions "boost", "enet", "tinygettext", "icu", "iconv", "fmt", } 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", "fmt", } -- 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"); elseif arch == "e2k" then table.insert(source_dirs, "lib/sysdep/arch/e2k"); elseif arch == "ppc64" then table.insert(source_dirs, "lib/sysdep/arch/ppc64"); 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 if _ACTION == "vs2017" then table.insert(source_dirs, "lib/sysdep/rtl/msc"); else table.insert(source_dirs, "lib/sysdep/rtl/gcc"); end setup_static_lib_project("lowlevel", source_dirs, extern_libs, extra_params) - setup_static_lib_project("gladwrapper", {}, { "glad" }, { no_pch = 1 }) + extern_libs = { "glad" } + 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 + setup_static_lib_project("gladwrapper", {}, used_extern_libs, { no_pch = 1 }) glad_path = libraries_source_dir.."glad/" sysincludedirs { glad_path.."include" } 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 files { glad_path.."src/egl.cpp", glad_path.."src/glx.cpp" } end end -- Third-party libraries that are built as part of the main project, -- not built externally and then linked source_dirs = { "third_party/mongoose", } extern_libs = { } setup_static_lib_project("mongoose", source_dirs, extern_libs, { no_pch = 1 }) -- CxxTest mock function support extern_libs = { "boost", "cxxtest", } -- 'real' implementations, to be linked against the main executable -- (files are added manually and not with setup_static_lib_project -- because not all files in the directory are included) setup_static_lib_project("mocks_real", {}, extern_libs, { no_default_link = 1, no_pch = 1 }) files { "mocks/*.h", source_root.."mocks/*_real.cpp" } -- 'test' implementations, to be linked against the test executable setup_static_lib_project("mocks_test", {}, extern_libs, { no_default_link = 1, no_pch = 1 }) files { source_root.."mocks/*.h", source_root.."mocks/*_test.cpp" } end -------------------------------------------------------------------------------- -- main EXE -------------------------------------------------------------------------------- -- used for main EXE as well as test used_extern_libs = { "sdl", "libpng", "zlib", "spidermonkey", "libxml2", "boost", "cxxtest", "comsuppw", "enet", "libcurl", "tinygettext", "icu", "iconv", "libsodium", "fmt", "freetype", "valgrind", } 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 {} links { "mocks_real" } 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" } rtti "off" -- Platform Specifics if os.istarget("windows") then files { source_root.."lib/sysdep/os/win/icon.rc" } -- 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", -- see wstartup.h "/INCLUDE:_wstartup_InitAndRegisterShutdown", -- allow manual unload of delay-loaded DLLs "/DELAY:UNLOAD", } -- allow the executable to use more than 2GB of RAM. -- this should not be enabled during development, so that memory issues are easily spotted. if _OPTIONS["large-address-aware"] then linkoptions { "/LARGEADDRESSAWARE" } end -- see manifest.cpp project_add_manifest() 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 if link_execinfo then links { "execinfo" } end if os.istarget("linux") or os.getversion().description == "GNU/kFreeBSD" then links { -- Dynamic libraries (needed for linking for gold) "dl", } 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" } 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 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 links { "winmm", "delayimp" } 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 elseif os.istarget("linux") or os.istarget("bsd") then if os.getversion().description == "FreeBSD" then buildoptions { "-fPIC" } linkoptions { "-fPIC" } else buildoptions { "-rdynamic", "-fPIC" } linkoptions { "-fPIC", "-rdynamic" } end -- 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 ".", "../../../third_party/jsonspirit" },{ -- include "../../../third_party/jsonspirit" },{ -- extern_libs "boost", "iconv", "libxml2" },{ -- extra_params no_pch = 1 }) atlas_src = { "ActorEditor", "CustomControls/Buttons", "CustomControls/Canvas", "CustomControls/ColorDialog", "CustomControls/DraggableListCtrl", "CustomControls/EditableListCtrl", "CustomControls/FileHistory", "CustomControls/HighResTimer", "CustomControls/MapDialog", "CustomControls/MapResizeDialog", "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 "..", "CustomControls", "Misc", "../../../third_party/jsonspirit" }, 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 project_add_manifest() else -- Non-Windows, = Unix links { "AtlasObject" } if os.istarget("macosx") then architecture(macos_arch) buildoptions { "-arch " .. macos_arch } linkoptions { "-arch " .. macos_arch } xcodebuildsettings { ARCHS = macos_arch } end 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 if os.istarget("windows") then characterset "MBCS" elseif os.istarget("linux") then 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" } if os.getversion().description ~= "FreeBSD" then buildoptions { "-rdynamic" } linkoptions { "-rdynamic" } end 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" } buildoptions { "-rdynamic" } 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" } architecture(macos_arch) buildoptions { "-arch " .. macos_arch } linkoptions { "-arch " .. macos_arch } xcodebuildsettings { ARCHS = macos_arch } end end -- build all Collada component projects function setup_collada_projects() setup_collada_project("Collada", "SharedLib", { -- src "." },{ -- include },{ -- extern_libs "fcollada", "iconv", "libxml2" },{ -- extra_params }) end -------------------------------------------------------------------------------- -- tests -------------------------------------------------------------------------------- function setup_tests() local cxxtest = require "cxxtest" if os.istarget("windows") then cxxtest.setpath(rootdir.."/build/bin/cxxtestgen.exe") else cxxtest.setpath(rootdir.."/libraries/source/cxxtest-4.4/bin/cxxtestgen") end local runner = "ErrorPrinter" if _OPTIONS["jenkins-tests"] then runner = "XmlPrinter" end local includefiles = { -- 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", -- This is required to build against SDL 2.0.4 on Windows. "lib/external_libraries/libsdl.h", } cxxtest.init(source_root, true, runner, includefiles) local target_type = get_main_project_target_type() project_create("test", target_type) -- 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 not (string.find(v, "/tools/atlas/") and not _OPTIONS["atlas"]) and not (string.find(v, "/sysdep/arch/x86_x64/") and ((arch ~= "amd64") or (arch ~= "x86"))) then table.insert(test_files, v) end end cxxtest.configure_project(test_files) 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 { } links { "mocks_test" } if _OPTIONS["atlas"] then 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" } rtti "off" -- 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" } -- see wstartup.h linkoptions { "/INCLUDE:_wstartup_InitAndRegisterShutdown" } -- Enables console for the TEST project on Windows linkoptions { "/SUBSYSTEM:CONSOLE" } project_add_manifest() elseif os.istarget("linux") or os.istarget("bsd") then if link_execinfo then links { "execinfo" } end 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", } 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/" } 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 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 { } if _OPTIONS["atlas"] then setup_atlas_projects() setup_atlas_frontends() end setup_collada_projects() if not _OPTIONS["without-tests"] then setup_tests() end