authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-27 12:38:52-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-27 12:38:52-04:00
logf407109070be2a187c71cc2350ac6d9b7d64a3d0
tree5e9c9130e0f14d20ea80f20911d05d1c64b7727b
parentdb17c0d88c44183b3060993d85657e7637b43d68
signaturelock-open Commit is signed but in an unrecognized format.

zig c++: get it working with musl and mingw-w64


15 files changed, 199 insertions(+), 327 deletions(-)

lib/libc/mingw/misc/_create_locale.c created+33
......@@ -0,0 +1,33 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <windows.h>
8#include <locale.h>
9#include <msvcrt.h>
10
11static _locale_t __cdecl init_func(int category, const char *locale);
12_locale_t (__cdecl *__MINGW_IMP_SYMBOL(_create_locale))(int, const char *) = init_func;
13
14static _locale_t __cdecl null_func(int category, const char *locale)
15{
16 (void)category;
17 (void)locale;
18 return NULL;
19}
20
21static _locale_t __cdecl init_func(int category, const char *locale)
22{
23 HMODULE msvcrt = __mingw_get_msvcrt_handle();
24 _locale_t (__cdecl *func)(int, const char *) = NULL;
25
26 if (msvcrt)
27 func = (void*)GetProcAddress(msvcrt, "_create_locale");
28
29 if (!func)
30 func = null_func;
31
32 return (__MINGW_IMP_SYMBOL(_create_locale) = func)(category, locale);
33}
lib/libc/mingw/misc/_free_locale.c created+31
......@@ -0,0 +1,31 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <windows.h>
8#include <locale.h>
9#include <msvcrt.h>
10
11static void __cdecl init_func(_locale_t locale);
12void (__cdecl *__MINGW_IMP_SYMBOL(_free_locale))(_locale_t) = init_func;
13
14static void __cdecl stub_func(_locale_t locale)
15{
16 (void)locale;
17}
18
19static void __cdecl init_func(_locale_t locale)
20{
21 HMODULE msvcrt = __mingw_get_msvcrt_handle();
22 void (__cdecl *func)(_locale_t) = NULL;
23
24 if (msvcrt)
25 func = (void*)GetProcAddress(msvcrt, "_free_locale");
26
27 if (!func)
28 func = stub_func;
29
30 (__MINGW_IMP_SYMBOL(_free_locale) = func)(locale);
31}
lib/libcxx/src/filesystem/int128_builtins.cpp deleted-54
......@@ -1,54 +0,0 @@
1/*===-- int128_builtins.cpp - Implement __muloti4 --------------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 * ===----------------------------------------------------------------------===
8 *
9 * This file implements __muloti4, and is stolen from the compiler_rt library.
10 *
11 * FIXME: we steal and re-compile it into filesystem, which uses __int128_t,
12 * and requires this builtin when sanitized. See llvm.org/PR30643
13 *
14 * ===----------------------------------------------------------------------===
15 */
16#include "__config"
17#include "climits"
18
19#if !defined(_LIBCPP_HAS_NO_INT128)
20
21extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS
22__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) {
23 const int N = (int)(sizeof(__int128_t) * CHAR_BIT);
24 const __int128_t MIN = (__int128_t)1 << (N - 1);
25 const __int128_t MAX = ~MIN;
26 *overflow = 0;
27 __int128_t result = a * b;
28 if (a == MIN) {
29 if (b != 0 && b != 1)
30 *overflow = 1;
31 return result;
32 }
33 if (b == MIN) {
34 if (a != 0 && a != 1)
35 *overflow = 1;
36 return result;
37 }
38 __int128_t sa = a >> (N - 1);
39 __int128_t abs_a = (a ^ sa) - sa;
40 __int128_t sb = b >> (N - 1);
41 __int128_t abs_b = (b ^ sb) - sb;
42 if (abs_a < 2 || abs_b < 2)
43 return result;
44 if (sa == sb) {
45 if (abs_a > MAX / abs_b)
46 *overflow = 1;
47 } else {
48 if (abs_a > MIN / -abs_b)
49 *overflow = 1;
50 }
51 return result;
52}
53
54#endif
lib/libcxxabi/src/stdlib_new_delete.cpp deleted-262
......@@ -1,262 +0,0 @@
1//===--------------------- stdlib_new_delete.cpp --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8// This file implements the new and delete operators.
9//===----------------------------------------------------------------------===//
10
11#define _LIBCPP_BUILDING_LIBRARY
12#include "__cxxabi_config.h"
13#include <new>
14#include <cstdlib>
15
16#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) || !defined(_LIBCXXABI_WEAK)
17#error The _THROW_BAD_ALLOC, _NOEXCEPT, and _LIBCXXABI_WEAK libc++ macros must \
18 already be defined by libc++.
19#endif
20// Implement all new and delete operators as weak definitions
21// in this shared library, so that they can be overridden by programs
22// that define non-weak copies of the functions.
23
24_LIBCXXABI_WEAK
25void *
26operator new(std::size_t size) _THROW_BAD_ALLOC
27{
28 if (size == 0)
29 size = 1;
30 void* p;
31 while ((p = ::malloc(size)) == 0)
32 {
33 // If malloc fails and there is a new_handler,
34 // call it to try free up memory.
35 std::new_handler nh = std::get_new_handler();
36 if (nh)
37 nh();
38 else
39#ifndef _LIBCXXABI_NO_EXCEPTIONS
40 throw std::bad_alloc();
41#else
42 break;
43#endif
44 }
45 return p;
46}
47
48_LIBCXXABI_WEAK
49void*
50operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
51{
52 void* p = 0;
53#ifndef _LIBCXXABI_NO_EXCEPTIONS
54 try
55 {
56#endif // _LIBCXXABI_NO_EXCEPTIONS
57 p = ::operator new(size);
58#ifndef _LIBCXXABI_NO_EXCEPTIONS
59 }
60 catch (...)
61 {
62 }
63#endif // _LIBCXXABI_NO_EXCEPTIONS
64 return p;
65}
66
67_LIBCXXABI_WEAK
68void*
69operator new[](size_t size) _THROW_BAD_ALLOC
70{
71 return ::operator new(size);
72}
73
74_LIBCXXABI_WEAK
75void*
76operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
77{
78 void* p = 0;
79#ifndef _LIBCXXABI_NO_EXCEPTIONS
80 try
81 {
82#endif // _LIBCXXABI_NO_EXCEPTIONS
83 p = ::operator new[](size);
84#ifndef _LIBCXXABI_NO_EXCEPTIONS
85 }
86 catch (...)
87 {
88 }
89#endif // _LIBCXXABI_NO_EXCEPTIONS
90 return p;
91}
92
93_LIBCXXABI_WEAK
94void
95operator delete(void* ptr) _NOEXCEPT
96{
97 if (ptr)
98 ::free(ptr);
99}
100
101_LIBCXXABI_WEAK
102void
103operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
104{
105 ::operator delete(ptr);
106}
107
108_LIBCXXABI_WEAK
109void
110operator delete(void* ptr, size_t) _NOEXCEPT
111{
112 ::operator delete(ptr);
113}
114
115_LIBCXXABI_WEAK
116void
117operator delete[] (void* ptr) _NOEXCEPT
118{
119 ::operator delete(ptr);
120}
121
122_LIBCXXABI_WEAK
123void
124operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
125{
126 ::operator delete[](ptr);
127}
128
129_LIBCXXABI_WEAK
130void
131operator delete[] (void* ptr, size_t) _NOEXCEPT
132{
133 ::operator delete[](ptr);
134}
135
136#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
137
138_LIBCXXABI_WEAK
139void *
140operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
141{
142 if (size == 0)
143 size = 1;
144 if (static_cast<size_t>(alignment) < sizeof(void*))
145 alignment = std::align_val_t(sizeof(void*));
146 void* p;
147#if defined(_LIBCPP_WIN32API)
148 while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
149#else
150 while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
151#endif
152 {
153 // If posix_memalign fails and there is a new_handler,
154 // call it to try free up memory.
155 std::new_handler nh = std::get_new_handler();
156 if (nh)
157 nh();
158 else {
159#ifndef _LIBCXXABI_NO_EXCEPTIONS
160 throw std::bad_alloc();
161#else
162 p = nullptr; // posix_memalign doesn't initialize 'p' on failure
163 break;
164#endif
165 }
166 }
167 return p;
168}
169
170_LIBCXXABI_WEAK
171void*
172operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
173{
174 void* p = 0;
175#ifndef _LIBCXXABI_NO_EXCEPTIONS
176 try
177 {
178#endif // _LIBCXXABI_NO_EXCEPTIONS
179 p = ::operator new(size, alignment);
180#ifndef _LIBCXXABI_NO_EXCEPTIONS
181 }
182 catch (...)
183 {
184 }
185#endif // _LIBCXXABI_NO_EXCEPTIONS
186 return p;
187}
188
189_LIBCXXABI_WEAK
190void*
191operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
192{
193 return ::operator new(size, alignment);
194}
195
196_LIBCXXABI_WEAK
197void*
198operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
199{
200 void* p = 0;
201#ifndef _LIBCXXABI_NO_EXCEPTIONS
202 try
203 {
204#endif // _LIBCXXABI_NO_EXCEPTIONS
205 p = ::operator new[](size, alignment);
206#ifndef _LIBCXXABI_NO_EXCEPTIONS
207 }
208 catch (...)
209 {
210 }
211#endif // _LIBCXXABI_NO_EXCEPTIONS
212 return p;
213}
214
215_LIBCXXABI_WEAK
216void
217operator delete(void* ptr, std::align_val_t) _NOEXCEPT
218{
219 if (ptr)
220#if defined(_LIBCPP_WIN32API)
221 ::_aligned_free(ptr);
222#else
223 ::free(ptr);
224#endif
225}
226
227_LIBCXXABI_WEAK
228void
229operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
230{
231 ::operator delete(ptr, alignment);
232}
233
234_LIBCXXABI_WEAK
235void
236operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
237{
238 ::operator delete(ptr, alignment);
239}
240
241_LIBCXXABI_WEAK
242void
243operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
244{
245 ::operator delete(ptr, alignment);
246}
247
248_LIBCXXABI_WEAK
249void
250operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
251{
252 ::operator delete[](ptr, alignment);
253}
254
255_LIBCXXABI_WEAK
256void
257operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
258{
259 ::operator delete[](ptr, alignment);
260}
261
262#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
src-self-hosted/stage2.zig+4
......@@ -1283,6 +1283,10 @@ pub const ClangArgIterator = extern struct {
12831283 sanitize,
12841284 linker_script,
12851285 verbose_cmds,
1286 exceptions,
1287 no_exceptions,
1288 rtti,
1289 no_rtti,
12861290 };
12871291
12881292 fn init(argv: []const [*:0]const u8) ClangArgIterator {
src/all_types.hpp+2
......@@ -2262,6 +2262,8 @@ struct CodeGen {
22622262 bool emit_asm;
22632263 bool emit_llvm_ir;
22642264 bool test_is_evented;
2265 bool cpp_rtti;
2266 bool cpp_exceptions;
22652267 CodeModel code_model;
22662268
22672269 Buf *root_out_name;
src/analyze.hpp+1
......@@ -260,6 +260,7 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
260260enum CSourceKind {
261261 CSourceKindAsm,
262262 CSourceKindC,
263 CSourceKindCpp,
263264};
264265
265266void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c,
src/codegen.cpp+26-1
......@@ -8448,6 +8448,8 @@ static bool detect_dynamic_link(CodeGen *g) {
84488448 LinkLib *link_lib = g->link_libs_list.at(i);
84498449 if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name)))
84508450 continue;
8451 if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name)))
8452 continue;
84518453 return true;
84528454 }
84538455 return false;
......@@ -8782,6 +8784,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
87828784 cache_bool(&cache_hash, g->is_test_build);
87838785 cache_bool(&cache_hash, g->is_single_threaded);
87848786 cache_bool(&cache_hash, g->test_is_evented);
8787 cache_bool(&cache_hash, g->cpp_rtti);
8788 cache_bool(&cache_hash, g->cpp_exceptions);
87858789 cache_int(&cache_hash, g->code_model);
87868790 cache_int(&cache_hash, g->zig_target->is_native_os);
87878791 cache_int(&cache_hash, g->zig_target->is_native_cpu);
......@@ -9181,7 +9185,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
91819185 }
91829186
91839187 if (translate_c) {
9184 if (source_kind == CSourceKindC) {
9188 if (source_kind != CSourceKindAsm) {
91859189 // this gives us access to preprocessing entities, presumably at
91869190 // the cost of performance
91879191 args.append("-Xclang");
......@@ -9213,6 +9217,12 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92139217
92149218 args.append("-isystem");
92159219 args.append(libcxx_include_path);
9220
9221 if (target_abi_is_musl(g->zig_target->abi)) {
9222 args.append("-D_LIBCPP_HAS_MUSL_LIBC");
9223 }
9224 args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
9225 args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
92169226 }
92179227
92189228 // According to Rich Felker libc headers are supposed to go before C language headers.
......@@ -9232,6 +9242,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92329242
92339243 switch (source_kind) {
92349244 case CSourceKindC:
9245 case CSourceKindCpp:
92359246 if (g->zig_target->llvm_cpu_name != nullptr) {
92369247 args.append("-Xclang");
92379248 args.append("-target-cpu");
......@@ -9248,6 +9259,14 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92489259 case CSourceKindAsm:
92499260 break;
92509261 }
9262 if (source_kind == CSourceKindCpp) {
9263 if (!g->cpp_rtti) {
9264 args.append("-fno-rtti");
9265 }
9266 if (!g->cpp_exceptions) {
9267 args.append("-fno-exceptions");
9268 }
9269 }
92519270 for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) {
92529271 args.append(g->zig_target->llvm_cpu_features_asm_ptr[i]);
92539272 }
......@@ -9695,6 +9714,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
96959714 cache_bool(cache_hash, g->have_sanitize_c);
96969715 cache_bool(cache_hash, want_valgrind_support(g));
96979716 cache_bool(cache_hash, g->function_sections);
9717 cache_bool(cache_hash, g->cpp_rtti);
9718 cache_bool(cache_hash, g->cpp_exceptions);
96989719 cache_int(cache_hash, g->code_model);
96999720
97009721 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
......@@ -10529,6 +10550,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1052910550 cache_bool(ch, g->emit_bin);
1053010551 cache_bool(ch, g->emit_llvm_ir);
1053110552 cache_bool(ch, g->emit_asm);
10553 cache_bool(ch, g->cpp_rtti);
10554 cache_bool(ch, g->cpp_exceptions);
1053210555 cache_usize(ch, g->version_major);
1053310556 cache_usize(ch, g->version_minor);
1053410557 cache_usize(ch, g->version_patch);
......@@ -10833,6 +10856,8 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
1083310856 parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_global_cache_dir(), false, child_progress_node);
1083410857 child_gen->root_out_name = buf_create_from_str(name);
1083510858 child_gen->disable_gen_h = true;
10859 child_gen->cpp_rtti = parent_gen->cpp_rtti;
10860 child_gen->cpp_exceptions = parent_gen->cpp_exceptions;
1083610861 child_gen->want_stack_check = WantStackCheckDisabled;
1083710862 child_gen->want_sanitize_c = WantCSanitizeDisabled;
1083810863 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
src/install_files.h-2
......@@ -1859,7 +1859,6 @@ static const char *ZIG_LIBCXXABI_FILES[] = {
18591859"src/fallback_malloc.cpp",
18601860"src/private_typeinfo.cpp",
18611861"src/stdlib_exception.cpp",
1862"src/stdlib_new_delete.cpp",
18631862"src/stdlib_stdexcept.cpp",
18641863"src/stdlib_typeinfo.cpp",
18651864};
......@@ -1875,7 +1874,6 @@ static const char *ZIG_LIBCXX_FILES[] = {
18751874"src/exception.cpp",
18761875"src/experimental/memory_resource.cpp",
18771876"src/filesystem/directory_iterator.cpp",
1878"src/filesystem/int128_builtins.cpp",
18791877"src/filesystem/operations.cpp",
18801878"src/functional.cpp",
18811879"src/future.cpp",
src/link.cpp+56-8
......@@ -14,6 +14,8 @@
1414#include "glibc.hpp"
1515
1616static const char *msvcrt_common_src[] = {
17 "misc" OS_SEP "_create_locale.c",
18 "misc" OS_SEP "_free_locale.c",
1719 "misc" OS_SEP "onexit_table.c",
1820 "misc" OS_SEP "register_tls_atexit.c",
1921 "stdio" OS_SEP "acrt_iob_func.c",
......@@ -632,12 +634,17 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
632634 }
633635 c_file->args.append("-I");
634636 c_file->args.append(path_from_libunwind(parent, "include"));
635 c_file->args.append("-fPIC");
637 if (target_supports_fpic(parent->zig_target)) {
638 c_file->args.append("-fPIC");
639 }
636640 c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
637641 c_file->args.append("-Wa,--noexecstack");
638 if (parent->zig_target->is_native_os && parent->zig_target->is_native_cpu) {
639 c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
640 }
642
643 // This is intentionally always defined because the macro definition means, should it only
644 // build for the target specified by compiler defines. Since we pass -target the compiler
645 // defines will be correct.
646 c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
647
641648 if (parent->build_mode == BuildModeDebug) {
642649 c_file->args.append("-D_DEBUG");
643650 }
......@@ -1129,6 +1136,12 @@ static const char *build_libcxxabi(CodeGen *parent, Stage2ProgressNode *progress
11291136 c_file->args.append("-D_LIBCPP_DISABLE_EXTERN_TEMPLATE");
11301137 c_file->args.append("-D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS");
11311138 c_file->args.append("-D_LIBCXXABI_BUILDING_LIBRARY");
1139 c_file->args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
1140 c_file->args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
1141
1142 if (target_abi_is_musl(parent->zig_target->abi)) {
1143 c_file->args.append("-D_LIBCPP_HAS_MUSL_LIBC");
1144 }
11321145
11331146 c_file->args.append("-I");
11341147 c_file->args.append(cxxabi_include_path);
......@@ -1138,7 +1151,9 @@ static const char *build_libcxxabi(CodeGen *parent, Stage2ProgressNode *progress
11381151
11391152 c_file->args.append("-O3");
11401153 c_file->args.append("-DNDEBUG");
1141 c_file->args.append("-fPIC");
1154 if (target_supports_fpic(parent->zig_target)) {
1155 c_file->args.append("-fPIC");
1156 }
11421157 c_file->args.append("-nostdinc++");
11431158 c_file->args.append("-fstrict-aliasing");
11441159 c_file->args.append("-funwind-tables");
......@@ -1170,8 +1185,15 @@ static const char *build_libcxx(CodeGen *parent, Stage2ProgressNode *progress_no
11701185 const char *rel_src_path = ZIG_LIBCXX_FILES[i];
11711186
11721187 Buf *src_path_buf = buf_create_from_str(rel_src_path);
1173 if (buf_starts_with_str(src_path_buf, "src/support/win32") && parent->zig_target->os != OsWindows) {
1174 continue;
1188 if (parent->zig_target->os == OsWindows) {
1189 // filesystem stuff isn't supported on Windows
1190 if (buf_starts_with_str(src_path_buf, "src/filesystem/")) {
1191 continue;
1192 }
1193 } else {
1194 if (buf_starts_with_str(src_path_buf, "src/support/win32/")) {
1195 continue;
1196 }
11751197 }
11761198
11771199 CFile *c_file = heap::c_allocator.create<CFile>();
......@@ -1182,6 +1204,12 @@ static const char *build_libcxx(CodeGen *parent, Stage2ProgressNode *progress_no
11821204 c_file->args.append("-D_LIBCPP_BUILDING_LIBRARY");
11831205 c_file->args.append("-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER");
11841206 c_file->args.append("-DLIBCXX_BUILDING_LIBCXXABI");
1207 c_file->args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
1208 c_file->args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
1209
1210 if (target_abi_is_musl(parent->zig_target->abi)) {
1211 c_file->args.append("-D_LIBCPP_HAS_MUSL_LIBC");
1212 }
11851213
11861214 c_file->args.append("-I");
11871215 c_file->args.append(cxx_include_path);
......@@ -1191,7 +1219,9 @@ static const char *build_libcxx(CodeGen *parent, Stage2ProgressNode *progress_no
11911219
11921220 c_file->args.append("-O3");
11931221 c_file->args.append("-DNDEBUG");
1194 c_file->args.append("-fPIC");
1222 if (target_supports_fpic(parent->zig_target)) {
1223 c_file->args.append("-fPIC");
1224 }
11951225 c_file->args.append("-nostdinc++");
11961226 c_file->args.append("-fvisibility-inlines-hidden");
11971227 c_file->args.append("-std=c++14");
......@@ -1923,6 +1953,8 @@ static void construct_linker_job_elf(LinkJob *lj) {
19231953 lj->args.append(build_libunwind(g, lj->build_dep_prog_node));
19241954 }
19251955 lj->args.append(build_musl(g, lj->build_dep_prog_node));
1956 } else if (g->libcpp_link_lib != nullptr) {
1957 lj->args.append(build_libunwind(g, lj->build_dep_prog_node));
19261958 } else {
19271959 zig_unreachable();
19281960 }
......@@ -2411,6 +2443,13 @@ static void construct_linker_job_coff(LinkJob *lj) {
24112443 break;
24122444 }
24132445
2446 // libc++ dep
2447 if (g->libcpp_link_lib != nullptr && g->out_type != OutTypeObj) {
2448 lj->args.append(build_libcxxabi(g, lj->build_dep_prog_node));
2449 lj->args.append(build_libcxx(g, lj->build_dep_prog_node));
2450 lj->args.append(build_libunwind(g, lj->build_dep_prog_node));
2451 }
2452
24142453 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
24152454 if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
24162455 Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node);
......@@ -2427,6 +2466,9 @@ static void construct_linker_job_coff(LinkJob *lj) {
24272466 if (buf_eql_str(link_lib->name, "c")) {
24282467 continue;
24292468 }
2469 if (buf_eql_str(link_lib->name, "c++") || buf_eql_str(link_lib->name, "c++abi")) {
2470 continue;
2471 }
24302472 bool is_sys_lib = is_mingw_link_lib(link_lib->name);
24312473 if (have_windows_dll_import_libs && is_sys_lib) {
24322474 continue;
......@@ -2562,6 +2604,12 @@ static void construct_linker_job_macho(LinkJob *lj) {
25622604 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
25632605 }
25642606
2607 // libc++ dep
2608 if (g->libcpp_link_lib != nullptr && g->out_type != OutTypeObj) {
2609 lj->args.append(build_libcxxabi(g, lj->build_dep_prog_node));
2610 lj->args.append(build_libcxx(g, lj->build_dep_prog_node));
2611 }
2612
25652613 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
25662614 if (g->out_type == OutTypeExe || is_dyn_lib) {
25672615 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node);
src/main.cpp+18
......@@ -458,6 +458,8 @@ static int main0(int argc, char **argv) {
458458 bool only_preprocess = false;
459459 bool ensure_libc_on_non_freestanding = false;
460460 bool ensure_libcpp_on_non_freestanding = false;
461 bool cpp_rtti = true;
462 bool cpp_exceptions = true;
461463
462464 ZigList<const char *> llvm_argv = {0};
463465 llvm_argv.append("zig (LLVM option parsing)");
......@@ -720,6 +722,18 @@ static int main0(int argc, char **argv) {
720722 verbose_cc = true;
721723 verbose_link = true;
722724 break;
725 case Stage2ClangArgExceptions:
726 cpp_exceptions = true;
727 break;
728 case Stage2ClangArgNoExceptions:
729 cpp_exceptions = false;
730 break;
731 case Stage2ClangArgRtti:
732 cpp_rtti = true;
733 break;
734 case Stage2ClangArgNoRtti:
735 cpp_rtti = false;
736 break;
723737 }
724738 }
725739 // Parse linker args
......@@ -1303,6 +1317,8 @@ static int main0(int argc, char **argv) {
13031317 LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));
13041318 link_lib->provided_explicitly = true;
13051319 }
1320 g->cpp_rtti = cpp_rtti;
1321 g->cpp_exceptions = cpp_exceptions;
13061322 g->subsystem = subsystem;
13071323 g->valgrind_support = valgrind_support;
13081324 g->want_pic = want_pic;
......@@ -1449,6 +1465,8 @@ static int main0(int argc, char **argv) {
14491465 }
14501466 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
14511467 override_lib_dir, libc, cache_dir_buf, cmd == CmdTest, root_progress_node);
1468 g->cpp_rtti = cpp_rtti;
1469 g->cpp_exceptions = cpp_exceptions;
14521470 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
14531471 g->valgrind_support = valgrind_support;
14541472 g->link_eh_frame_hdr = link_eh_frame_hdr;
src/stage2.h+4
......@@ -344,6 +344,10 @@ enum Stage2ClangArg {
344344 Stage2ClangArgSanitize,
345345 Stage2ClangArgLinkerScript,
346346 Stage2ClangArgVerboseCmds,
347 Stage2ClangArgExceptions,
348 Stage2ClangArgNoExceptions,
349 Stage2ClangArgRtti,
350 Stage2ClangArgNoRtti,
347351};
348352
349353// ABI warning
src/target.cpp+7
......@@ -1229,6 +1229,13 @@ bool target_is_libc_lib_name(const ZigTarget *target, const char *name) {
12291229 return false;
12301230}
12311231
1232bool target_is_libcpp_lib_name(const ZigTarget *target, const char *name) {
1233 if (strcmp(name, "c++") == 0 || strcmp(name, "c++abi") == 0)
1234 return true;
1235
1236 return false;
1237}
1238
12321239size_t target_libc_count(void) {
12331240 return array_length(libcs_available);
12341241}
src/target.hpp+1
......@@ -102,6 +102,7 @@ bool target_os_requires_libc(Os os);
102102bool target_can_build_libc(const ZigTarget *target);
103103const char *target_libc_generic_name(const ZigTarget *target);
104104bool target_is_libc_lib_name(const ZigTarget *target, const char *name);
105bool target_is_libcpp_lib_name(const ZigTarget *target, const char *name);
105106bool target_supports_fpic(const ZigTarget *target);
106107bool target_supports_clang_march_native(const ZigTarget *target);
107108bool target_requires_pic(const ZigTarget *target, bool linking_libc);
tools/update_clang_options.zig+16
......@@ -158,6 +158,22 @@ const known_options = [_]KnownOpt{
158158 .name = "###",
159159 .ident = "verbose_cmds",
160160 },
161 .{
162 .name = "fexceptions",
163 .ident = "exceptions",
164 },
165 .{
166 .name = "fno-exceptions",
167 .ident = "no_exceptions",
168 },
169 .{
170 .name = "frtti",
171 .ident = "rtti",
172 },
173 .{
174 .name = "fno-rtti",
175 .ident = "no_rtti",
176 },
161177};
162178
163179const blacklisted_options = [_][]const u8{};