build as C++ the normal way
Instead of building with $cc and linking a C++ standard library
where needed, build with $cxx, which takes care of that for us.
This lets us use threadsafe statics to check for Haswell support
once, rather than the platform-specific versions we use today.
(Threadsafe statics tend to need helpers from the library.)
Change-Id: If71eb4b6223b36ac6b9c6e587e1614020de5f291
Reviewed-on: https://skia-review.googlesource.com/139541
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/build/android b/build/android
index fb780cb..273f692 100644
--- a/build/android
+++ b/build/android
@@ -3,7 +3,9 @@
arch = arch-arm64
ndk_api = 24
-cc = $ndk/toolchains/llvm/prebuilt/*/bin/clang -target $target
+cc = $ndk/toolchains/llvm/prebuilt/*/bin/clang -target $target
+cxx = $ndk/toolchains/llvm/prebuilt/*/bin/clang++ -target $target
+
cflags = -fcolor-diagnostics -Weverything $
--sysroot $ndk/sysroot $
-I $ndk/sysroot/usr/include/$target
diff --git a/build/android-arm b/build/android-arm
index e04beb5..d43d14c 100644
--- a/build/android-arm
+++ b/build/android-arm
@@ -3,7 +3,9 @@
arch = arch-arm
ndk_api = 24
-cc = $ndk/toolchains/llvm/prebuilt/*/bin/clang -target $target
+cc = $ndk/toolchains/llvm/prebuilt/*/bin/clang -target $target
+cxx = $ndk/toolchains/llvm/prebuilt/*/bin/clang++ -target $target
+
cflags = -fcolor-diagnostics -Weverything $
-march=armv7-a -mthumb $
--sysroot $ndk/sysroot $
diff --git a/build/android-arm-gcc b/build/android-arm-gcc
index 1b1c452..fbf3fd2 100644
--- a/build/android-arm-gcc
+++ b/build/android-arm-gcc
@@ -4,6 +4,8 @@
ndk_api = 24
cc = $ndk/toolchains/${target}-4.9/prebuilt/*/bin/${target}-gcc
+cxx = $ndk/toolchains/${target}-4.9/prebuilt/*/bin/${target}-g++
+
cflags = -fdiagnostics-color -Wall -Wextra $
-march=armv7-a -mfpu=neon -mthumb -mfloat-abi=softfp $
--sysroot $ndk/sysroot $
diff --git a/build/android.fp16 b/build/android.fp16
index aec757f..9ec3191 100644
--- a/build/android.fp16
+++ b/build/android.fp16
@@ -4,4 +4,5 @@
# The Clang in NDK ≤r17 is not new enough to support -march=armv8.2a+fp16 in any interesting way,
# so we use your generic `clang` instead, which is hopefully newer.
-cc = clang -target $target
+cc = clang -target $target
+cxx = clang++ -target $target
diff --git a/build/clang b/build/clang
index c588705..27bad60 100644
--- a/build/clang
+++ b/build/clang
@@ -1,4 +1,5 @@
cc = clang
+cxx = clang++
cflags = -fcolor-diagnostics -Weverything
out = out/clang$mode
diff --git a/build/clang.xsan b/build/clang.xsan
index e28fb3a..014fec4 100644
--- a/build/clang.xsan
+++ b/build/clang.xsan
@@ -1,4 +1,4 @@
mode = .xsan
extra_cflags = -fsanitize=address,integer,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,integer,undefined -lc++
+extra_ldflags = -fsanitize=address,integer,undefined
include build/clang
diff --git a/build/common b/build/common
index 87a6c9f..a961577 100644
--- a/build/common
+++ b/build/common
@@ -25,14 +25,14 @@
description = compile $out
rule compile_cc
- command = $disabled && touch $out || $cc -std=c++11 -g -Os $warnings_cc $cflags $extra_cflags $
+ command = $disabled && touch $out || $cxx -std=c++11 -g -Os $warnings_cc $cflags $extra_cflags $
-MD -MF $out.d -c $in -o $out
depfile = $out.d
deps = gcc
description = compile $out
rule link
- command = $disabled && touch $out || $cc $ldflags $extra_ldflags $in -ldl -pthread -o $out
+ command = $disabled && touch $out || $cxx $ldflags $extra_ldflags $in -ldl -o $out
description = link $out
include build/targets
diff --git a/build/gcc b/build/gcc
index 2b6e1f9..ee9f8e4 100644
--- a/build/gcc
+++ b/build/gcc
@@ -1,4 +1,5 @@
cc = gcc
+cxx = g++
cflags = -fdiagnostics-color -Wall -Wextra -ffp-contract=off -fstack-usage
out = out/gcc$mode
diff --git a/build/gcc.xsan b/build/gcc.xsan
index a53f6ec..150ce07 100644
--- a/build/gcc.xsan
+++ b/build/gcc.xsan
@@ -1,4 +1,4 @@
mode = .xsan
extra_cflags = -fsanitize=address,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,undefined -lstdc++
+extra_ldflags = -fsanitize=address,undefined
include build/gcc
diff --git a/build/ios b/build/ios
index 638ea31..3667b11 100644
--- a/build/ios
+++ b/build/ios
@@ -1,4 +1,5 @@
-cc = clang -arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path`
+cc = clang -arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path`
+cxx = clang++ -arch arm64 -isysroot `xcrun --sdk iphoneos --show-sdk-path`
cflags = -fcolor-diagnostics -Weverything
out = out/ios$mode
diff --git a/infra/bots/bot.py b/infra/bots/bot.py
index 19688cf..a6c937d 100644
--- a/infra/bots/bot.py
+++ b/infra/bots/bot.py
@@ -28,10 +28,13 @@
elif 'linux' in sys.platform:
# Point to clang in our clang_linux package.
clang_linux = os.path.realpath(sys.argv[3])
- append('skcms/build/clang', 'cc = {}/bin/clang'.format(clang_linux))
+ append('skcms/build/clang', 'cc = {}/bin/clang '.format(clang_linux))
+ append('skcms/build/clang', 'cxx = {}/bin/clang++'.format(clang_linux))
# TODO(mtklein): once the NDK is new enough (r18?) we can use its Clang again
append('skcms/build/android.fp16',
- 'cc = {}/bin/clang -target $target'.format(clang_linux))
+ 'cc = {}/bin/clang -target $target'.format(clang_linux))
+ append('skcms/build/android.fp16',
+ 'cxx = {}/bin/clang++ -target $target'.format(clang_linux))
call('{ninja}/ninja -C skcms -k 0'.format(ninja=ninja))
diff --git a/skcms.cc b/skcms.cc
index 41a67ff..e81f949 100644
--- a/skcms.cc
+++ b/skcms.cc
@@ -1977,70 +1977,46 @@
#define TEST_FOR_HSW
- static bool hsw_ok_ = false;
- static void check_hsw_ok() {
- // See http://www.sandpile.org/x86/cpuid.htm
+ static bool hsw_ok() {
+ static const bool ok = []{
+ // See http://www.sandpile.org/x86/cpuid.htm
- // First, a basic cpuid(1).
- uint32_t eax, ebx, ecx, edx;
- __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
- : "0"(1), "2"(0));
+ // First, a basic cpuid(1).
+ uint32_t eax, ebx, ecx, edx;
+ __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "0"(1), "2"(0));
- // Sanity check for prerequisites.
- if ((edx & (1<<25)) != (1<<25)) { return; } // SSE
- if ((edx & (1<<26)) != (1<<26)) { return; } // SSE2
- if ((ecx & (1<< 0)) != (1<< 0)) { return; } // SSE3
- if ((ecx & (1<< 9)) != (1<< 9)) { return; } // SSSE3
- if ((ecx & (1<<19)) != (1<<19)) { return; } // SSE4.1
- if ((ecx & (1<<20)) != (1<<20)) { return; } // SSE4.2
+ // Sanity check for prerequisites.
+ if ((edx & (1<<25)) != (1<<25)) { return false; } // SSE
+ if ((edx & (1<<26)) != (1<<26)) { return false; } // SSE2
+ if ((ecx & (1<< 0)) != (1<< 0)) { return false; } // SSE3
+ if ((ecx & (1<< 9)) != (1<< 9)) { return false; } // SSSE3
+ if ((ecx & (1<<19)) != (1<<19)) { return false; } // SSE4.1
+ if ((ecx & (1<<20)) != (1<<20)) { return false; } // SSE4.2
- if ((ecx & (3<<26)) != (3<<26)) { return; } // XSAVE + OSXSAVE
+ if ((ecx & (3<<26)) != (3<<26)) { return false; } // XSAVE + OSXSAVE
- {
- uint32_t eax_xgetbv, edx_xgetbv;
- __asm__ __volatile__("xgetbv" : "=a"(eax_xgetbv), "=d"(edx_xgetbv) : "c"(0));
- if ((eax_xgetbv & (3<<1)) != (3<<1)) { return; } // XMM+YMM state saved?
- }
+ {
+ uint32_t eax_xgetbv, edx_xgetbv;
+ __asm__ __volatile__("xgetbv" : "=a"(eax_xgetbv), "=d"(edx_xgetbv) : "c"(0));
+ if ((eax_xgetbv & (3<<1)) != (3<<1)) { return false; } // XMM+YMM state saved?
+ }
- if ((ecx & (1<<28)) != (1<<28)) { return; } // AVX
- if ((ecx & (1<<29)) != (1<<29)) { return; } // F16C
- if ((ecx & (1<<12)) != (1<<12)) { return; } // FMA (TODO: not currently used)
+ if ((ecx & (1<<28)) != (1<<28)) { return false; } // AVX
+ if ((ecx & (1<<29)) != (1<<29)) { return false; } // F16C
+ if ((ecx & (1<<12)) != (1<<12)) { return false; } // FMA (TODO: not currently used)
- // Call cpuid(7) to check for our final AVX2 feature bit!
- __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
- : "0"(7), "2"(0));
- if ((ebx & (1<< 5)) != (1<< 5)) { return; } // AVX2
+ // Call cpuid(7) to check for our final AVX2 feature bit!
+ __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "0"(7), "2"(0));
+ if ((ebx & (1<< 5)) != (1<< 5)) { return false; } // AVX2
- hsw_ok_ = true;
+ return true;
+ }();
+
+ return ok;
}
- #if defined(_MSC_VER)
- #include <Windows.h>
- INIT_ONCE check_hsw_ok_once = INIT_ONCE_STATIC_INIT;
-
- static BOOL check_hsw_ok_InitOnce_wrapper(INIT_ONCE* once, void* param, void** ctx) {
- (void)once;
- (void)param;
- (void)ctx;
- check_hsw_ok();
- return TRUE;
- }
-
- static bool hsw_ok() {
- InitOnceExecuteOnce(&check_hsw_ok_once, check_hsw_ok_InitOnce_wrapper,
- nullptr, nullptr);
- return hsw_ok_;
- }
- #else
- #include <pthread.h>
- static pthread_once_t check_hsw_ok_once = PTHREAD_ONCE_INIT;
-
- static bool hsw_ok() {
- pthread_once(&check_hsw_ok_once, check_hsw_ok);
- return hsw_ok_;
- }
- #endif
-
#endif
static bool is_identity_tf(const skcms_TransferFunction* tf) {