Generate Android builds directly from premake
Adds a global "setup_compiler.lua" file that configures premake to build for Android. Since premake doesn't support specifying a custom compiler, we hack this using "gccprefix".
Also moves a bunch of duplicated windows setup logic into "setup_compiler.lua".
Diffs=
040a27c1c Generate Android builds directly from premake (#4871)
diff --git a/.rive_head b/.rive_head
index 5bc4085..c2ac205 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-12285f625ff69c6b21528d93b3b665d9b0b9f8be
+040a27c1c53dfb53ffce3a8b2503124fe1a2f068
diff --git a/build/premake5.lua b/build/premake5.lua
index 52390b9..a3a3061 100644
--- a/build/premake5.lua
+++ b/build/premake5.lua
@@ -1,5 +1,8 @@
workspace 'rive'
configurations {'debug', 'release'}
+
+require 'setup_compiler'
+
filter {'options:with_rive_tools'}
do
defines {'WITH_RIVE_TOOLS'}
@@ -8,40 +11,16 @@
do
defines {'WITH_RIVE_TEXT'}
end
+filter {}
dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_harfbuzz.lua'))
dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_sheenbidi.lua'))
-WINDOWS_CLANG_CL_SUPPRESSED_WARNINGS = {
- '-Wno-c++98-compat',
- '-Wno-c++98-compat-pedantic',
- '-Wno-deprecated-copy-with-user-provided-dtor',
- '-Wno-documentation',
- '-Wno-documentation-pedantic',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-exit-time-destructors',
- '-Wno-float-equal',
- '-Wno-global-constructors',
- '-Wno-implicit-float-conversion',
- '-Wno-newline-eof',
- '-Wno-old-style-cast',
- '-Wno-reserved-identifier',
- '-Wno-shadow',
- '-Wno-sign-compare',
- '-Wno-sign-conversion',
- '-Wno-unused-macros',
- '-Wno-unused-parameter',
- '-Wno-switch-enum',
- '-Wno-missing-field-initializers'
-}
-
project 'rive'
do
kind 'StaticLib'
language 'C++'
cppdialect 'C++11'
- toolset 'clang'
targetdir '%{cfg.system}/bin/%{cfg.buildcfg}'
objdir '%{cfg.system}/obj/%{cfg.buildcfg}'
includedirs {
@@ -81,9 +60,6 @@
architecture 'x64'
defines {'_USE_MATH_DEFINES'}
flags {'FatalCompileWarnings'}
- buildoptions {WINDOWS_CLANG_CL_SUPPRESSED_WARNINGS}
- staticruntime 'on' -- Match Skia's /MT flag for link compatibility
- runtime 'Release' -- Use /MT even in debug (/MTd is incompatible with Skia)
removebuildoptions {
'-fno-exceptions',
'-fno-rtti'
@@ -158,18 +134,6 @@
}
newoption {
- trigger = 'arch',
- value = 'ABI',
- description = 'The ABI with the right toolchain for this build, generally with Android',
- allowed = {
- {'x86'},
- {'x64'},
- {'arm'},
- {'arm64'}
- }
-}
-
-newoption {
trigger = 'with_rive_tools',
description = 'Enables tools usually not necessary for runtime.'
}
diff --git a/build/setup_compiler.lua b/build/setup_compiler.lua
new file mode 100644
index 0000000..d16b4dc
--- /dev/null
+++ b/build/setup_compiler.lua
@@ -0,0 +1,203 @@
+toolset (_OPTIONS["toolset"] or "clang")
+
+filter 'system:windows'
+do
+ staticruntime "on" -- Match Skia's /MT flag for link compatibility
+ runtime "Release" -- Use /MT even in debug (/MTd is incompatible with Skia)
+end
+
+filter {'system:windows', 'options:toolset=clang'}
+do
+ buildoptions {
+ '-Wno-c++98-compat',
+ '-Wno-c++20-compat',
+ '-Wno-c++98-compat-pedantic',
+ '-Wno-c99-extensions',
+ '-Wno-ctad-maybe-unsupported',
+ '-Wno-deprecated-copy-with-user-provided-dtor',
+ '-Wno-deprecated-declarations',
+ '-Wno-documentation',
+ '-Wno-documentation-pedantic',
+ '-Wno-documentation-unknown-command',
+ '-Wno-double-promotion',
+ '-Wno-exit-time-destructors',
+ '-Wno-float-equal',
+ '-Wno-global-constructors',
+ '-Wno-implicit-float-conversion',
+ '-Wno-newline-eof',
+ '-Wno-old-style-cast',
+ '-Wno-reserved-identifier',
+ '-Wno-shadow',
+ '-Wno-sign-compare',
+ '-Wno-sign-conversion',
+ '-Wno-unused-macros',
+ '-Wno-unused-parameter',
+ '-Wno-four-char-constants',
+ '-Wno-unreachable-code',
+ '-Wno-switch-enum',
+ '-Wno-missing-field-initializers'
+ }
+end
+
+filter {'system:windows', 'options:toolset=msc'}
+do
+ -- We currently suppress several warnings for the MSVC build, some serious. Once this build
+ -- is fully integrated into GitHub actions, we will definitely want to address these.
+ disablewarnings {
+ "4061", -- enumerator 'identifier' in switch of enum 'enumeration' is not explicitly
+ -- handled by a case label
+ "4100", -- 'identifier': unreferenced formal parameter
+ "4201", -- nonstandard extension used: nameless struct/union
+ "4244", -- 'conversion_type': conversion from 'type1' to 'type2', possible loss of data
+ "4245", -- 'conversion_type': conversion from 'type1' to 'type2', signed/unsigned
+ -- mismatch
+ "4267", -- 'variable': conversion from 'size_t' to 'type', possible loss of data
+ "4355", -- 'this': used in base member initializer list
+ "4365", -- 'expression': conversion from 'type1' to 'type2', signed/unsigned mismatch
+ "4388", -- 'expression': signed/unsigned mismatch
+ "4389", -- 'operator': signed/unsigned mismatch
+ "4458", -- declaration of 'identifier' hides class member
+ "4514", -- 'function': unreferenced inline function has been removed
+ "4583", -- 'Catch::clara::detail::ResultValueBase<T>::m_value': destructor is not
+ -- implicitly called
+ "4623", -- 'Catch::AssertionInfo': default constructor was implicitly defined as deleted
+ "4625", -- 'derived class': copy constructor was implicitly defined as deleted because a
+ -- base class copy constructor is inaccessible or deleted
+ "4626", -- 'derived class': assignment operator was implicitly defined as deleted
+ -- because a base class assignment operator is inaccessible or deleted
+ "4820", -- 'bytes' bytes padding added after construct 'member_name'
+ "4868", -- (catch.hpp) compiler may not enforce left-to-right evaluation order in braced
+ -- initializer list
+ "5026", -- 'type': move constructor was implicitly defined as deleted
+ "5027", -- 'type': move assignment operator was implicitly defined as deleted
+ "5039", -- (catch.hpp) 'AddVectoredExceptionHandler': pointer or reference to
+ -- potentially throwing function passed to 'extern "C"' function under -EHc.
+ -- Undefined behavior may occur if this function throws an exception.
+ "5045", -- Compiler will insert Spectre mitigation for memory load if /Qspectre switch
+ -- specified
+ "5204", -- 'Catch::Matchers::Impl::MatcherMethod<T>': class has virtual functions, but
+ -- its trivial destructor is not virtual; instances of objects derived from this
+ -- class may not be destructed correctly
+ "5219", -- implicit conversion from 'type-1' to 'type-2', possible loss of data
+ "5262", -- MSVC\14.34.31933\include\atomic(917,9): implicit fall-through occurs here;
+ -- are you missing a break statement?
+ "5264", -- 'rive::math::PI': 'const' variable is not used
+ }
+end
+
+filter{}
+
+-- Don't use filter() here because we don't want to generate the "ndk-redirect-*" files if not
+-- building for android.
+if _OPTIONS["os"] == "android"
+then
+ local ndk = os.getenv("NDK_PATH")
+ if not ndk or ndk == "" then
+ error("export $NDK_PATH")
+ end
+
+ local ndk_toolchain = ndk .. "/toolchains/llvm/prebuilt"
+ if os.host() == 'windows' then
+ ndk_toolchain = ndk_toolchain .. "/windows-x86_64"
+ elseif os.host() == 'macosx' then
+ ndk_toolchain = ndk_toolchain .. "/darwin-x86_64"
+ else
+ ndk_toolchain = ndk_toolchain .. "/linux-x86_64"
+ end
+
+ -- Using "gcc" allows us to redirect the compiler to the (clang) NDK.
+ toolset "gcc"
+ gccprefix (_WORKING_DIR .. "/ndk-redirect-")
+
+ -- Masquerade the clang NDK as a "gcc" cross-compiler.
+ file = io.open(_WORKING_DIR .. "/ndk-redirect-g++", "w")
+ file:write("#!/bin/bash\n")
+ file:write(ndk_toolchain .. "/bin/clang++ $@")
+ file:close()
+ os.execute("chmod +x " .. _WORKING_DIR .. "/ndk-redirect-g++")
+
+ file = io.open(_WORKING_DIR .. "/ndk-redirect-gcc", "w")
+ file:write("#!/bin/bash\n")
+ file:write(ndk_toolchain .. "/bin/clang $@")
+ file:close()
+ os.execute("chmod +x " .. _WORKING_DIR .. "/ndk-redirect-gcc")
+
+ file = io.open(_WORKING_DIR .. "/ndk-redirect-ar", "w")
+ file:write("#!/bin/bash\n")
+ file:write(ndk_toolchain .. "/bin/llvm-ar $@")
+ file:close()
+ os.execute("chmod +x " .. _WORKING_DIR .. "/ndk-redirect-ar")
+
+ pic "on" -- Position-independent code is required for NDK libraries.
+ filter "options:arch=x86"
+ do
+ architecture "x86"
+ buildoptions {"--target=i686-none-linux-android23"}
+ linkoptions {"--target=i686-none-linux-android23"}
+ end
+ filter "options:arch=x64"
+ do
+ architecture "x64"
+ buildoptions {"--target=x86_64-none-linux-android23"}
+ linkoptions {"--target=x86_64-none-linux-android23"}
+ end
+ filter "options:arch=arm"
+ do
+ architecture "arm"
+ buildoptions {"--target=armv7a-none-linux-android23"}
+ linkoptions {"--target=armv7a-none-linux-android23"}
+ end
+ filter "options:arch=arm64"
+ do
+ architecture "arm64"
+ buildoptions {"--target=aarch64-none-linux-android23"}
+ linkoptions {"--target=aarch64-none-linux-android23"}
+ end
+ filter {}
+
+ buildoptions {
+ "--sysroot=" .. ndk_toolchain .. "/sysroot",
+ "-fdata-sections",
+ "-ffunction-sections",
+ "-funwind-tables",
+ "-fstack-protector-strong",
+ "-no-canonical-prefixes",
+ }
+
+ linkoptions {
+ "--sysroot=" .. ndk_toolchain .. "/sysroot",
+ "-fdata-sections",
+ "-ffunction-sections",
+ "-funwind-tables",
+ "-fstack-protector-strong",
+ "-no-canonical-prefixes",
+ "-Wl,--fatal-warnings",
+ "-Wl,--gc-sections",
+ "-Wl,--no-rosegment",
+ "-Wl,--no-undefined",
+ "-static-libstdc++",
+ }
+end
+
+newoption {
+ trigger = 'toolset',
+ value = 'type',
+ description = 'Choose which toolchain to build with',
+ allowed = {
+ {'clang', 'Build with Clang'},
+ {'msc', 'Build with the Microsoft C/C++ compiler'}
+ },
+ default = 'clang'
+}
+
+newoption {
+ trigger = 'arch',
+ value = 'ABI',
+ description = 'The ABI with the right toolchain for this build, generally with Android',
+ allowed = {
+ {'x86'},
+ {'x64'},
+ {'arm'},
+ {'arm64'}
+ }
+}
diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua
index 3fefe81..5c883bc 100644
--- a/dependencies/premake5_harfbuzz.lua
+++ b/dependencies/premake5_harfbuzz.lua
@@ -1,3 +1,4 @@
+require 'setup_compiler'
local dependency = require 'dependency'
harfbuzz = dependency.github('harfbuzz/harfbuzz', '858570b1d9912a1b746ab39fbe62a646c4f7a5b1')
@@ -9,7 +10,6 @@
kind 'StaticLib'
language 'C++'
cppdialect 'C++17'
- toolset 'clang'
targetdir '%{cfg.system}/cache/bin/%{cfg.buildcfg}/'
objdir '%{cfg.system}/cache/obj/%{cfg.buildcfg}/'
@@ -222,14 +222,8 @@
harfbuzz .. '/src/hb.hh'
}
- buildoptions {
- '-Wall',
- '-fno-exceptions',
- '-fno-rtti',
- '-Werror=format',
- '-Wimplicit-int-conversion',
- '-Werror=vla'
- }
+ exceptionhandling 'off'
+ rtti 'off'
defines {
'HAVE_OT',
@@ -237,6 +231,16 @@
'HB_NO_WIN1256'
}
+ filter 'toolset:clang'
+ do
+ flags {'FatalWarnings'}
+ buildoptions {
+ '-Werror=format',
+ '-Wimplicit-int-conversion',
+ '-Werror=vla'
+ }
+ end
+
filter 'configurations:debug'
do
defines {'DEBUG'}
@@ -252,46 +256,6 @@
filter 'system:windows'
do
- removebuildoptions {
- -- vs clang doesn't recognize these on windows
- '-fno-exceptions',
- '-fno-rtti'
- }
architecture 'x64'
- buildoptions {
- '-Wno-c++98-compat',
- '-Wno-c++98-compat-pedantic',
- '-Wno-c99-extensions',
- '-Wno-ctad-maybe-unsupported',
- '-Wno-deprecated-copy-with-user-provided-dtor',
- '-Wno-deprecated-declarations',
- '-Wno-documentation',
- '-Wno-documentation-pedantic',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-exit-time-destructors',
- '-Wno-float-equal',
- '-Wno-global-constructors',
- '-Wno-implicit-float-conversion',
- '-Wno-newline-eof',
- '-Wno-old-style-cast',
- '-Wno-reserved-identifier',
- '-Wno-shadow',
- '-Wno-sign-compare',
- '-Wno-sign-conversion',
- '-Wno-unused-macros',
- '-Wno-unused-parameter',
- '-Wno-used-but-marked-unused',
- '-Wno-cast-qual',
- '-Wno-unused-template',
- '-Wno-zero-as-null-pointer-constant',
- '-Wno-extra-semi',
- '-Wno-undef',
- '-Wno-comma',
- '-Wno-nonportable-system-include-path',
- '-Wno-covered-switch-default',
- '-Wno-microsoft-enum-value',
- '-Wno-deprecated-declarations'
- }
end
end
diff --git a/dependencies/premake5_libpng.lua b/dependencies/premake5_libpng.lua
index a9a78a5..77f8d2c 100644
--- a/dependencies/premake5_libpng.lua
+++ b/dependencies/premake5_libpng.lua
@@ -1,3 +1,4 @@
+require 'setup_compiler'
local dependency = require 'dependency'
libpng = dependency.github('glennrp/libpng', 'libpng16')
zlib = dependency.github('madler/zlib', '04f42ceca40f73e2978b50e93806c2a18c1281fc')
@@ -7,7 +8,6 @@
kind 'StaticLib'
language 'C++'
cppdialect 'C++17'
- toolset 'clang'
targetdir '%{cfg.system}/cache/bin/%{cfg.buildcfg}/'
objdir '%{cfg.system}/cache/obj/%{cfg.buildcfg}/'
rtti "Off"
@@ -47,8 +47,6 @@
filter 'system:windows'
do
architecture 'x64'
- staticruntime "on" -- Match Skia's /MT flag for link compatibility
- runtime "Release" -- Use /MT even in debug (/MTd is incompatible with Skia)
end
end
@@ -57,7 +55,6 @@
kind 'StaticLib'
language 'C++'
cppdialect 'C++17'
- toolset 'clang'
targetdir '%{cfg.system}/cache/bin/%{cfg.buildcfg}/'
objdir '%{cfg.system}/cache/obj/%{cfg.buildcfg}/'
rtti "Off"
@@ -87,8 +84,6 @@
filter 'system:windows'
do
architecture 'x64'
- staticruntime "on" -- Match Skia's /MT flag for link compatibility
- runtime "Release" -- Use /MT even in debug (/MTd is incompatible with Skia)
end
filter 'system:not windows'
diff --git a/dependencies/premake5_sheenbidi.lua b/dependencies/premake5_sheenbidi.lua
index bebb582..9fd4e22 100644
--- a/dependencies/premake5_sheenbidi.lua
+++ b/dependencies/premake5_sheenbidi.lua
@@ -8,7 +8,6 @@
do
kind 'StaticLib'
language 'C'
- toolset 'clang'
targetdir '%{cfg.system}/cache/bin/%{cfg.buildcfg}/'
objdir '%{cfg.system}/cache/obj/%{cfg.buildcfg}/'
@@ -57,7 +56,6 @@
filter 'configurations:debug'
do
- buildoptions {'-g', '-O0'}
defines {'DEBUG'}
symbols 'On'
end
@@ -71,46 +69,6 @@
filter 'system:windows'
do
- removebuildoptions {
- -- vs clang doesn't recognize these on windows
- '-fno-exceptions',
- '-fno-rtti'
- }
architecture 'x64'
- buildoptions {
- '-Wno-c++98-compat',
- '-Wno-c++98-compat-pedantic',
- '-Wno-c99-extensions',
- '-Wno-ctad-maybe-unsupported',
- '-Wno-deprecated-copy-with-user-provided-dtor',
- '-Wno-deprecated-declarations',
- '-Wno-documentation',
- '-Wno-documentation-pedantic',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-exit-time-destructors',
- '-Wno-float-equal',
- '-Wno-global-constructors',
- '-Wno-implicit-float-conversion',
- '-Wno-newline-eof',
- '-Wno-old-style-cast',
- '-Wno-reserved-identifier',
- '-Wno-shadow',
- '-Wno-sign-compare',
- '-Wno-sign-conversion',
- '-Wno-unused-macros',
- '-Wno-unused-parameter',
- '-Wno-used-but-marked-unused',
- '-Wno-cast-qual',
- '-Wno-unused-template',
- '-Wno-zero-as-null-pointer-constant',
- '-Wno-extra-semi',
- '-Wno-undef',
- '-Wno-comma',
- '-Wno-nonportable-system-include-path',
- '-Wno-covered-switch-default',
- '-Wno-microsoft-enum-value',
- '-Wno-deprecated-declarations'
- }
end
end
diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua
index 7e73360..94d5ba8 100644
--- a/dev/test/premake5.lua
+++ b/dev/test/premake5.lua
@@ -24,7 +24,6 @@
kind 'ConsoleApp'
language 'C++'
cppdialect 'C++11'
- toolset (_OPTIONS["toolset"] or "clang")
targetdir 'build/bin/%{cfg.buildcfg}'
objdir 'build/obj/%{cfg.buildcfg}'
flags {'FatalWarnings'}
@@ -69,94 +68,4 @@
'_CRT_NONSTDC_NO_DEPRECATE'
}
end
-
- filter {'system:windows', 'options:toolset=clang'}
- do
- buildoptions {
- '-Wno-c++98-compat',
- '-Wno-c++20-compat',
- '-Wno-c++98-compat-pedantic',
- '-Wno-c99-extensions',
- '-Wno-ctad-maybe-unsupported',
- '-Wno-deprecated-copy-with-user-provided-dtor',
- '-Wno-deprecated-declarations',
- '-Wno-documentation',
- '-Wno-documentation-pedantic',
- '-Wno-documentation-unknown-command',
- '-Wno-double-promotion',
- '-Wno-exit-time-destructors',
- '-Wno-float-equal',
- '-Wno-global-constructors',
- '-Wno-implicit-float-conversion',
- '-Wno-newline-eof',
- '-Wno-old-style-cast',
- '-Wno-reserved-identifier',
- '-Wno-shadow',
- '-Wno-sign-compare',
- '-Wno-sign-conversion',
- '-Wno-unused-macros',
- '-Wno-unused-parameter',
- '-Wno-four-char-constants',
- '-Wno-unreachable-code',
- '-Wno-switch-enum',
- '-Wno-missing-field-initializers'
- }
- end
-
- filter {'system:windows', 'options:toolset=msc'}
- do
- -- We currently suppress several warnings for the MSVC build, some serious. Once this build
- -- is fully integrated into GitHub actions, we will definitely want to address these.
- disablewarnings {
- "4061", -- enumerator 'identifier' in switch of enum 'enumeration' is not explicitly
- -- handled by a case label
- "4100", -- 'identifier': unreferenced formal parameter
- "4201", -- nonstandard extension used: nameless struct/union
- "4244", -- 'conversion_type': conversion from 'type1' to 'type2', possible loss of data
- "4245", -- 'conversion_type': conversion from 'type1' to 'type2', signed/unsigned
- -- mismatch
- "4267", -- 'variable': conversion from 'size_t' to 'type', possible loss of data
- "4355", -- 'this': used in base member initializer list
- "4365", -- 'expression': conversion from 'type1' to 'type2', signed/unsigned mismatch
- "4388", -- 'expression': signed/unsigned mismatch
- "4389", -- 'operator': signed/unsigned mismatch
- "4458", -- declaration of 'identifier' hides class member
- "4514", -- 'function': unreferenced inline function has been removed
- "4583", -- 'Catch::clara::detail::ResultValueBase<T>::m_value': destructor is not
- -- implicitly called
- "4623", -- 'Catch::AssertionInfo': default constructor was implicitly defined as deleted
- "4625", -- 'derived class': copy constructor was implicitly defined as deleted because a
- -- base class copy constructor is inaccessible or deleted
- "4626", -- 'derived class': assignment operator was implicitly defined as deleted
- -- because a base class assignment operator is inaccessible or deleted
- "4820", -- 'bytes' bytes padding added after construct 'member_name'
- "4868", -- (catch.hpp) compiler may not enforce left-to-right evaluation order in braced
- -- initializer list
- "5026", -- 'type': move constructor was implicitly defined as deleted
- "5027", -- 'type': move assignment operator was implicitly defined as deleted
- "5039", -- (catch.hpp) 'AddVectoredExceptionHandler': pointer or reference to
- -- potentially throwing function passed to 'extern "C"' function under -EHc.
- -- Undefined behavior may occur if this function throws an exception.
- "5045", -- Compiler will insert Spectre mitigation for memory load if /Qspectre switch
- -- specified
- "5204", -- 'Catch::Matchers::Impl::MatcherMethod<T>': class has virtual functions, but
- -- its trivial destructor is not virtual; instances of objects derived from this
- -- class may not be destructed correctly
- "5219", -- implicit conversion from 'type-1' to 'type-2', possible loss of data
- "5262", -- MSVC\14.34.31933\include\atomic(917,9): implicit fall-through occurs here;
- -- are you missing a break statement?
- "5264", -- 'rive::math::PI': 'const' variable is not used
- }
- end
end
-
-newoption {
- trigger = 'toolset',
- value = 'type',
- description = 'Choose which toolchain to build with',
- allowed = {
- {'clang', 'Build with Clang'},
- {'msc', 'Build with the Microsoft C/C++ compiler'}
- },
- default = 'clang'
-}
diff --git a/skia/renderer/build/premake5.lua b/skia/renderer/build/premake5.lua
index 709ea37..2f5184f 100644
--- a/skia/renderer/build/premake5.lua
+++ b/skia/renderer/build/premake5.lua
@@ -1,6 +1,8 @@
workspace 'rive'
configurations {'debug', 'release'}
+require 'setup_compiler'
+
SKIA_DIR = os.getenv('SKIA_DIR')
dependencies = os.getenv('DEPENDENCIES')
@@ -18,7 +20,6 @@
kind 'StaticLib'
language 'C++'
cppdialect 'C++17'
- toolset 'clang'
targetdir '%{cfg.system}/bin/%{cfg.buildcfg}'
objdir '%{cfg.system}/obj/%{cfg.buildcfg}'
includedirs {
@@ -38,8 +39,6 @@
do
architecture 'x64'
defines {'_USE_MATH_DEFINES'}
- staticruntime 'on' -- Match Skia's /MT flag for link compatibility
- runtime 'Release' -- Use /MT even in debug (/MTd is incompatible with Skia)
end
filter {'system:macosx'}