config("default") { if (is_android) { defines = [ "OS_ANDROID" ] } else if (is_ios) { defines = [ "OS_IOS" ] } else if (is_linux) { defines = [ "OS_LINUX" ] } else if (is_mac) { defines = [ "OS_MAC" ] } else if (is_win) { defines = [ "OS_WIN" ] } if (is_ios || is_mac) { defines += [ "OS_APPLE" ] } cflags_cc = [] if (is_win) { cflags_cc += [ "/std:c++20" ] } else { cflags_cc += [ "-std=c++20" ] } cflags = [] if (is_win) { cflags += [ "/permissive-", # Don't enable nonconforming code to compile. "/EHsc", # Use C++ exception handling. "/Gd", # __cdecl calling convention. "/utf-8", # Set Source and Executable character set. ] defines += [ # Windows headers from MS and third party expects these to be set. "_WINDOWS", "_UNICODE", "UNICODE", # Don't want MS specific extensions for C stdlib functions. "_CRT_SECURE_NO_WARNINGS", # Clean up the Windows headers. "WIN32_LEAN_AND_MEAN", "NOMINMAX", ] } else { # cflags += [ # "-fstrict-aliasing", # Optimizations allowed for type aliasing. # "-fvisibility=hidden", # Only let symbols be visible inside it's own # # library. # ] # cflags_cc += [ # "-fvisibility-inlines-hidden", # Inline methods may not generate symbols. # # "-stdlib=libc++", # ] if (is_linux) { # cflags += [ # "-fPIC", # Emit position-independent code suitable for dynamic linking. # ] libs = [ "pthread", # Use the POSIX thread library. ] } else if (is_mac) { asmflags = [ "-target", "arm64-apple-macos11", ] cflags += [ # "-fPIC", # Emit position-independent code suitable for dynamic linking. "-target", "arm64-apple-macos11", ] ldflags = [ "-target", "arm64-apple-macos11", ] } } # Avoid relative paths everywhere. include_dirs = [ # "//", "//src", ] } config("debug") { defines = [ "_DEBUG" ] if (is_win) { cflags = [ "/GS", # Buffer security checks (buffer overruns). "/sdl", # Enable additional security features and warnings. "/RTC1", # Enable fast run-time checks. "/Od", # Disable optimizations. "/fp:precise", # Floating points are predictable. "/MDd", # Link with multithread debug DLL run-time libraries. "/Z7", # Produce obj files that contain full symbolic debugging # information. ] ldflags = [ "/DEBUG:FASTLINK" ] # Reference the debug symbols in the obj # files instead of a PDB file. } else { cflags = [ "-g", # Debug symbols. # TODO: This makes it hard to step through code on Linux. # "-Og", # Optimizations that works well with debugger. ] if (is_unix) { defines += [ "_GLIBCXX_DEBUG=1", # Enable asserts in stl headers. ] } } } config("release") { defines = [ "NDEBUG" ] if (is_win) { cflags = [ "/GL", # Link-time code generation / Whole program optimization. "/Gy", # Allows converting inline functions to separate functions. "/O2", # Optimize for maximum speed. "/Oi", # Enable intrinsics. "/fp:fast", # Floating points are fast. "/MD", # Link with multithread release DLL run-time libraries. # "/arch:AVX2", # Minimum CPU architecture. ] ldflags = [ "/LTCG", # Link time code generation. "/OPT:ICF", # COMDAT (common data) folding, e.g. vtables and big inline # functions that can't be inlined, but also if identical code # happens to be generated though common math operations or # similar. "/OPT:REF", # Eliminate unreferenced code and data. ] } else { cflags = [ "-Ofast", # Full optimization and disregard strict standard compliance. "-fno-math-errno", # Do not check or set errno for invalid input to sqrt # and other math functions. ] # cflags += [ # # Generate machine code for the current developer computer. # # TODO: This needs to be set properly before release. # "-march=native", # ] if (is_apple) { ldflags = [ "-dead-strip" ] } else { # Place both data and functions in it's their own sections. # Linker optimization that allows for smaller binaries. cflags += [ "-fdata-sections", "-ffunction-sections", ] ldflags = [ "-Wl,--gc-sections" ] } } } config("warnings") { if (is_win) { cflags = [ "/WX", # Treat warnings as errors. "/Wall", # Enable all warnings. # Disable the following warnings: "/wd4061", # enumerator in switch with a default case not explicitly # handled by a case label. "/wd4100", # unreferenced format parameter. "/wd4324", # structure was padded due to alignment specifier "/wd4371", # layout of class may have changed from a previous version of # the compiler due to better packing of member "/wd4514", # unreferenced inline function has been removed. "/wd4710", # function not inlined "/wd4711", # function selected for automatic inline expansion "/wd4820", # padding added after data member. "/wd5045", # compiler will insert Spectre mitigation for memory load if # switch specified. # TODO: Not sure how I feel about these conversion warnings. "/wd4244", # conversion, possible loss of data. 'int' to 'float' "/wd4267", # conversion, possible loss of data. "/wd4305", # truncation from 'double' to 'float'. "/wd4365", # conversion, signed/unsigned mismatch. "/wd5219", # conversion, possible loss of data. 'int' to 'float' # Possible compiler bug? Needs investigation. "/wd4668", # '__STDC_WANT_SECURE_LIB__' is not defined as a preprocessor # macro, replacing with '0' for '#if/#elif' # TODO: "/wd4263", # member function does not override any base class virtual # member function "/wd4264", # no override available for virtual member function, function # is hidden "/wd4266", # no override available for virtual member function from base, # function is hidden "/wd4355", # 'this' used in base member initializer list "/wd4457", # declaration hides function parameter "/wd4464", # relative include path contains '..'. "/wd4625", # copy constructor was implicitly defined as deleted "/wd4626", # assignment operator was implicitly defined as deleted "/wd4706", # assignment withing conditional expression. "/wd4774", # format string expected in argument X is not a string literal "/wd4828", # The file contains a character that is illegal in the current # source character set "/wd4946", # reinterpret_cast used between related "/wd5026", # move constructor was implicitly defined as deleted "/wd5027", # move assignment operator was implicitly defined as deleted "/wd5039", # pointer or reference to potentially throwing function passed # to 'extern "C"' function under -EHc. Undefined behavior may # occur if this function throws an exception. # TODO: I don't understand these or how to fix them: "/wd4458", # declaration hides class member # [ GameObject::rtti ] "/wd4582", # constructor is not implicitly called # [ intersection.h Contact ] "/wd4623", # default constructor was implicitly defined as deleted # [ intersection.h Contact ] "/wd5243", # using incomplete class can cause potential one definition # rule violation due to ABI limitation ] defines = [ "_CRT_NONSTDC_NO_DEPRECATE", "_SILENCE_CXX17_STRSTREAM_DEPRECATION_WARNING", ] } else if (is_mac) { cflags = [ "-Wno-deprecated-declarations", "-Wno-inconsistent-missing-override", "-Wno-pointer-sign", ] } else { cflags = [ # Enable as much warnings as possible. "-Werror", # Make all warnings into errors. "-Wall", # Enable (almost) all warnings. "-Wextra", # Enable even more warnings. # "-Wpedantic", # Issue warnings demanded by strict ISO C/C++ and reject # forbidden extensions. "-Wvla", # Warn if variable-length array is used in code. # Disable the following warnings: "-Wno-unused-parameter", ] } } config("executable") { if (is_android) { ldflags = [ "-pie", "-rdynamic", ] } else if (is_linux) { # ldflags = [ # "-rdynamic", # Tell linker to expose all symbols, not only used ones. # # Needed for some uses of dlopen and for backtraces within # # the program. # "-Wl,-rpath,\$ORIGIN", # Add directory to runtime library search path. # ] } else if (is_mac) { ldflags = [ "-Wl,-rpath,@loader_path/." ] } else if (is_win) { ldflags = [ "/DYNAMICBASE", # Use address space layout randomization. "/INCREMENTAL:NO", # Incremental linking interferes with both ninja and # release optimizations. # Leave the target architecture to environment settings. # "/MACHINE:X64", ] } } # TODO: This needs some more investigation. # Is it possible to avoid setting it and rely on defaults? # Some tools will be console apps while games will be gui apps. # GLFW seems to be using console in debug mode and gui in release mode. if (is_win) { config("win_gui") { ldflags = [ "/SUBSYSTEM:WINDOWS" ] } config("win_console") { ldflags = [ "/SUBSYSTEM:CONSOLE" ] } }