diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-05-10 23:38:44 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-10 23:38:44 -0400 |
| commit | f5edf78eea403c14635a05e1729672cfb50aca89 (patch) | |
| tree | 1661a15b3ee4427ce6a4286f4c972be49e9f572c | |
| parent | 458943e324e81762a9a2aa839d2fa3c851068e6f (diff) | |
| parent | 45415093c655d30ec226172695248fbf28941667 (diff) | |
| download | zig-f5edf78eea403c14635a05e1729672cfb50aca89.tar.gz zig-f5edf78eea403c14635a05e1729672cfb50aca89.zip | |
Merge pull request #10143 from nuald/single-threaded-cpp1
Normalized C++ compilation options for single-threaded targets
| -rw-r--r-- | src/Compilation.zig | 13 | ||||
| -rw-r--r-- | src/libcxx.zig | 24 | ||||
| -rw-r--r-- | test/standalone/c_compiler/build.zig | 2 | ||||
| -rw-r--r-- | test/standalone/c_compiler/test.c | 23 | ||||
| -rw-r--r-- | test/standalone/c_compiler/test.cpp | 76 |
5 files changed, 106 insertions, 32 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 9126289804..5e4ab0ec12 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1180,6 +1180,15 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { if (must_single_thread and !single_threaded) { return error.TargetRequiresSingleThreaded; } + if (!single_threaded and options.link_libcpp) { + if (options.target.cpu.arch.isARM()) { + log.warn( + \\libc++ does not work on multi-threaded ARM yet. + \\For more details: https://github.com/ziglang/zig/issues/6573 + , .{}); + return error.TargetRequiresSingleThreaded; + } + } const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: { var buf = std.ArrayList(u8).init(arena); @@ -3803,6 +3812,10 @@ pub fn addCCArgs( try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); + + if (comp.bin_file.options.single_threaded) { + try argv.append("-D_LIBCPP_HAS_NO_THREADS"); + } } if (comp.bin_file.options.link_libunwind) { diff --git a/src/libcxx.zig b/src/libcxx.zig index b2974e24c9..a5ab242339 100644 --- a/src/libcxx.zig +++ b/src/libcxx.zig @@ -128,6 +128,12 @@ pub fn buildLibCXX(comp: *Compilation) !void { continue; if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos) continue; + if (comp.bin_file.options.single_threaded) { + if (std.mem.startsWith(u8, cxx_src, "src/support/win32/thread_win32.cpp")) { + continue; + } + try cflags.append("-D_LIBCPP_HAS_NO_THREADS"); + } try cflags.append("-DNDEBUG"); try cflags.append("-D_LIBCPP_BUILDING_LIBRARY"); @@ -145,8 +151,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { } if (target.os.tag == .wasi) { - // WASI doesn't support thread and exception yet. - try cflags.append("-D_LIBCPP_HAS_NO_THREADS"); + // WASI doesn't support exceptions yet. try cflags.append("-fno-exceptions"); } @@ -264,13 +269,20 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { var cflags = std.ArrayList([]const u8).init(arena); if (target.os.tag == .wasi) { - // WASI doesn't support thread and exception yet. - if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_thread_atexit.cpp") or - std.mem.startsWith(u8, cxxabi_src, "src/cxa_exception.cpp") or + // WASI doesn't support exceptions yet. + if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_exception.cpp") or std.mem.startsWith(u8, cxxabi_src, "src/cxa_personality.cpp")) continue; - try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS"); try cflags.append("-fno-exceptions"); + } + + // WASM targets are single threaded. + if (comp.bin_file.options.single_threaded) { + if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_thread_atexit.cpp")) { + continue; + } + try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS"); + try cflags.append("-D_LIBCPP_HAS_NO_THREADS"); } else { try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL"); } diff --git a/test/standalone/c_compiler/build.zig b/test/standalone/c_compiler/build.zig index ad500c3eb3..240d535182 100644 --- a/test/standalone/c_compiler/build.zig +++ b/test/standalone/c_compiler/build.zig @@ -29,7 +29,7 @@ pub fn build(b: *Builder) void { exe_cpp.addCSourceFile("test.cpp", &[0][]const u8{}); exe_cpp.setBuildMode(mode); exe_cpp.setTarget(target); - exe_cpp.linkSystemLibrary("c++"); + exe_cpp.linkLibCpp(); switch (target.getOsTag()) { .windows => { diff --git a/test/standalone/c_compiler/test.c b/test/standalone/c_compiler/test.c index 842a63fc67..da0a137798 100644 --- a/test/standalone/c_compiler/test.c +++ b/test/standalone/c_compiler/test.c @@ -1,25 +1,28 @@ #include <assert.h> #include <stdio.h> +#include <stdlib.h> -typedef struct { - int val; +typedef struct { + int val; } STest; int getVal(STest* data) { return data->val; } int main (int argc, char *argv[]) { - STest* data = (STest*)malloc(sizeof(STest)); - data->val = 123; + STest* data = (STest*)malloc(sizeof(STest)); + data->val = 123; - assert(getVal(data) != 456); - int ok = (getVal(data) == 123); + assert(getVal(data) != 456); + int ok = (getVal(data) == 123); - if (argc>1) fprintf(stdout, "val=%d\n", data->val); + if (argc > 1) { + fprintf(stdout, "val=%d\n", data->val); + } - free(data); + free(data); - if (!ok) abort(); + if (!ok) abort(); - return 0; + return EXIT_SUCCESS; } diff --git a/test/standalone/c_compiler/test.cpp b/test/standalone/c_compiler/test.cpp index 8c533d02cc..1f3fe173d2 100644 --- a/test/standalone/c_compiler/test.cpp +++ b/test/standalone/c_compiler/test.cpp @@ -1,33 +1,79 @@ -#include <iostream> #include <cassert> +#include <iostream> + +#ifndef _LIBCPP_HAS_NO_THREADS +#include <future> +#endif + +thread_local unsigned int tls_counter = 1; + +// a non-optimized way of checking for prime numbers: +bool is_prime(int x) { + for (int i = 2; i <x ; ++i) { + if (x % i == 0) { + return false; + } + } + return true; +} class CTest { public: - CTest(int val) : m_val(val) {}; - virtual ~CTest() {} + CTest(int val) : m_val(val) { + tls_counter++; + }; + virtual ~CTest() {} - virtual int getVal() const { return m_val; } - virtual void printVal() { std::cout << "val=" << m_val << std::endl; } + virtual int getVal() const { return m_val; } + virtual void printVal() { std::cout << "val=" << m_val << std::endl; } private: - int m_val; + int m_val; +}; + +class GlobalConstructorTest { +public: + GlobalConstructorTest(int val) : m_val(val) {}; + virtual ~GlobalConstructorTest() {} + + virtual int getVal() const { return m_val; } + virtual void printVal() { std::cout << "val=" << m_val << std::endl; } +private: + int m_val; }; volatile int runtime_val = 456; -CTest global(runtime_val); // test if global initializers are called. +GlobalConstructorTest global(runtime_val); // test if global initializers are called. int main (int argc, char *argv[]) { - assert(global.getVal() == 456); + assert(global.getVal() == 456); + + auto t = std::make_unique<CTest>(123); + assert(t->getVal() != 456); + assert(tls_counter == 2); + if (argc > 1) { + t->printVal(); + } + bool ok = t->getVal() == 123; - auto* t = new CTest(123); - assert(t->getVal()!=456); + if (!ok) abort(); - if (argc>1) t->printVal(); - bool ok = t->getVal() == 123; - delete t; +#ifndef _LIBCPP_HAS_NO_THREADS + std::future<bool> fut = std::async(is_prime, 313); + bool ret = fut.get(); + assert(ret); +#endif - if (!ok) abort(); +#if !defined(__wasm__) && !defined(__APPLE__) + // WASM and macOS are not passing this yet. + // TODO file an issue for this and link it here. + try { + throw 20; + } catch (int e) { + assert(e == 20); + } +#endif - return 0; + return EXIT_SUCCESS; } |
