mirror of
https://github.com/ziglang/zig.git
synced 2026-02-01 12:13:44 +00:00
Merge pull request #10143 from nuald/single-threaded-cpp1
Normalized C++ compilation options for single-threaded targets
This commit is contained in:
commit
f5edf78eea
@ -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) {
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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 => {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 = new CTest(123);
|
||||
assert(t->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;
|
||||
|
||||
if (argc>1) t->printVal();
|
||||
bool ok = t->getVal() == 123;
|
||||
delete t;
|
||||
if (!ok) abort();
|
||||
|
||||
if (!ok) abort();
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
std::future<bool> fut = std::async(is_prime, 313);
|
||||
bool ret = fut.get();
|
||||
assert(ret);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#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 EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user