Skip to content

New define SIMDUTF_NO_LIBCXX to build with no libc++ or libc++abi#959

Closed
mitchellh wants to merge 1 commit intosimdutf:masterfrom
mitchellh:nolibcxx
Closed

New define SIMDUTF_NO_LIBCXX to build with no libc++ or libc++abi#959
mitchellh wants to merge 1 commit intosimdutf:masterfrom
mitchellh:nolibcxx

Conversation

@mitchellh
Copy link
Copy Markdown
Collaborator

@mitchellh mitchellh commented Apr 15, 2026

Resolves #158

This adds a new define SIMDUTF_NO_LIBCXX that can be used to build simdutf without libc++ or libc++abi. This is very useful for environments where these dependencies are undesirable. I already have a Ghostty PR verifying this change using a custom amalgam build from my fork.

This is similar to Google Highway's HWY_NO_LIBCXX define that achieves the same thing .

When SIMDUTF_NO_LIBCXX is present, we strive as much as possible to avoid breaking ABI but some is necessary since some of the public ABI relies on libc++ (e.g. returns std::string and such). As such, the presence of the define should be considered a separate ABI for all intents and purposes.

When SIMDUTF_NO_LIBCXX is not present, we strive to change nothing. There is some additional noise in this PR towards that goal (e.g. in implementation.cpp). The idea is that the standard build should remain ABI, functionally, and stylistically as identical as possible.

AI Disclaimer: I did this work alongside Codex. I'm not a C++ expert but I'm a very experienced systems-level programmer. I constantly changed direction and nudged the AI in different directions and also did a final pass on the set of changes.

I'm happy to make adjustments as requested if this is desired and I can understand and explain any part of this diff. This PR description was fully hand-written by me.

Type of change

  • Bug fix
  • Optimization
  • New feature
  • Refactor / cleanup
  • Documentation / tests
  • Other (please describe):

Important

I'm sorry this diff is so big. I know the importance of smaller PRs, but this is one of those things that's hard to break into smaller pieces because it either works or doesn't...

Why?

I'm the author of the Ghostty terminal. Ghostty has used simdutf for many years and it's a critical dependency we're happy with. Recently, we've been pursuing libghostty-vt
(https://libghostty.tip.ghostty.org/), a C library that exposes a rich set of functionality for complete terminal emulation.

One of the beautiful things about libghostty-vt is that if you disable our SIMD features, it has on dependencies at all (not even libc!). It is completely freestanding.

But if you enable SIMD, it requires libc and libc++. The only libc++ requirement is for simdutf. So I'm interested in rectifying that and making it possible to use simdutf in a way that doesn't require libc++ so that libghostty-vt doesn't either.

I ultimately intend to not require libc either, but that's a much bigger lift. In the mean time, we can provide fully static builds of libghostty-vt that have only the libc symbols we use. Much harder for C++. :)

Build

This mode is enabled explicitly by defining SIMDUTF_NO_LIBCXX=1 when building simdutf.

The important detail is that this is an all-or-nothing build contract: every translation unit that compiles simdutf sources or includes simdutf headers must see the same define. In practice, that means passing -DSIMDUTF_NO_LIBCXX=1 consistently to both simdutf itself and any code that includes simdutf.h.

A typical build looks like:

c++ -std=c++17 \
  -DSIMDUTF_NO_LIBCXX=1 \
  -fno-exceptions -fno-rtti \
  -Iinclude -Isrc \
  -c src/simdutf.cpp -o simdutf.o

If the goal is a stricter environment with no C++ standard library in the final artifact, this can also be paired with -nostdinc++ and -nostdlib++, which is what the CI coverage exercises for the single-header build to ensure that there's no access to libc++ at all and that it also can't be linked.

Approach

Type Shims

I try to achieve this in a minimally invasive way. The main idea is to provide a header stl_compat.h that shims the libc++ types in the NO_LIBCXX case. In the standard case (libc++), the types are zero overhead aliases or inline passthroughs. In the NO_LIBCXX case, the types are minimally implemented for only what simdutf directly needs.

Therefore, the diff is very large, but almost all the changes are trivial replacements from e.g. std::pair to
simdutf::internal::pair.

There are some types I didn't want to shim at all, e.g. std::span, but these were necessary for some of the benchmarks (e.g. the base64 ones). That's why that's there.

Reduced Surface Area

This is intentionally a reduced-surface contract rather than an attempt to fully emulate the standard C++ functionality.

Any public API that directly exposes std::* either changes shape or is compiled out in this mode. In practice this means things like implementation::name() and implementation::description() return const char * instead of std::string, and helpers such as to_string(encoding_type) similarly return C strings.

APIs that inherently depend on stdlib facilities are not available at all. That includes std::span convenience overloads, std::text_encoding interop, and the std::atomic_ref-based helpers.

Avoiding C++ Runtime Hooks

Avoiding libc++ headers is only part of the problem. There are also a few compiler-emitted ABI hooks that can sneak in even when the source no longer mentions std::*.

The big one is function-local statics, which can introduce __cxa_guard_* references for thread-safe initialization. In the NO_LIBCXX path I move the implementation singletons and dispatch storage to translation-unit scope so the runtime detection model stays the same without requiring those guard functions.

There is also a weak __cxa_pure_virtual trap shim for the abstract implementation vtable case. Correct dispatch should never hit it, but without it some toolchains still insist on a libc++abi dependency just for that unreachable symbol. It is marked weak so that in compilation units that do pull in libc++abi, the real __cxa_pure_virtual will take precedence.

The C wrapper is also adjusted to bridge through compiler-native char16_t/char32_t forms without assuming the normal C++ stdlib type machinery is available.

Verification

This type of feature can regress easily, so I added explicit verification.

There is now a dedicated script and CI workflow that:

  • compiles the core sources with SIMDUTF_NO_LIBCXX
  • checks their undefined symbols for forbidden C++ ABI/runtime entries such as _cxa_guard*, exception machinery, RTTI, and dynamic-cast support
  • links smoke tests without the C++ standard library and verifies the resulting binaries do not depend on libc++, libc++abi, libstdc++, or libsupc++
  • exercises both the normal runtime-dispatch path and the fallback-only/single-implementation path
  • verifies that the single-header build still works with -nostdinc++ and -nostdlib++

The goal here is not just "make it compile on my machine" but also to make it maintainable.

Performance

I ran paired benchmarks for the standard build and the SIMDUTF_NO_LIBCXX build. The benchmarks included all possible benchmark programs in this repo and all modes.

The conclusion is that performance is broadly unchanged. On the main throughput benchmarks, most realistic-input results move by only low-single-digit percentages, and many are effectively flat. I reran them a few times and they're sometimes faster sometimes slower so I'm going to say its noise.

The important part is there is no real difference.

AI Disclosure: I'm repeating this again at the bottom in case you missed it at the top. I hand-wrote this entire PR description, I manually reviewed every change in this PR and can understand and discuss it intelligently with you, I did use Codex to assist in writing this, though!

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 15, 2026

@mitchellh Running tests.

This looks reasonable to me.

@mitchellh
Copy link
Copy Markdown
Collaborator Author

Replaced my commit to address the CI failures, please try again thank you.

This adds a new define `SIMDUTF_NO_LIBCXX` that can be used to build
simdutf without libc++ or libc++abi. This is very useful for environments
where these dependencies are undesirable.

When SIMDUTF_NO_LIBCXX is present, we strive as much as possible to avoid
breaking ABI but some is necessary since some of the public ABI relies 
on libc++ (e.g. returns `std::string` and such). As such, the presence
of the define should be considered a separate ABI for all intents and
purposes.

> [!IMPORTANT]
>
> **I'm sorry this diff is so big.** I know the importance of smaller
> PRs, but this is one of those things that's hard to break into
> smaller pieces because it either works or doesn't...

## Why?

I'm the author of the Ghostty terminal. Ghostty has used simdutf for
many years and it's a critical dependency we're happy with. Recently,
we've been pursuing `libghostty-vt`
(https://libghostty.tip.ghostty.org/), a C library that exposes a rich
set of functionality for complete terminal emulation.

One of the beautiful things about `libghostty-vt` is that if you disable
our SIMD features, it has on dependencies at all (not even libc!). It is
completely freestanding. 

But if you enable SIMD, it requires libc and libc++. The only libc++ 
requirement is for simdutf. So I'm interested in rectifying that and
making it possible to use simdutf in a way that doesn't require libc++
so that `libghostty-vt` doesn't either.

I ultimately intend to not require libc either, but that's a much bigger
lift. In the mean time, we can provide fully static builds of `libghostty-vt`
that have only the libc symbols we use. Much harder for C++. :) 

## Build

This mode is enabled explicitly by defining `SIMDUTF_NO_LIBCXX=1` when
building simdutf.

The important detail is that this is an all-or-nothing build contract:
every translation unit that compiles simdutf sources or includes simdutf
headers must see the same define. In practice, that means passing
`-DSIMDUTF_NO_LIBCXX=1` consistently to both simdutf itself and any code
that includes `simdutf.h`.

A typical build looks like:

```
c++ -std=c++17 \
  -DSIMDUTF_NO_LIBCXX=1 \
  -fno-exceptions -fno-rtti \
  -Iinclude -Isrc \
  -c src/simdutf.cpp -o simdutf.o
```

If the goal is a stricter environment with no C++ standard library in the
final artifact, this can also be paired with `-nostdinc++` and
`-nostdlib++`, which is what the CI coverage exercises for the
single-header build to ensure that there's no access to libc++ at all
and that it also can't be linked.

## Approach

### Type Shims

I try to achieve this in a minimally invasive way. The main idea is
to provide a header `stl_compat.h` that shims the libc++ types in 
the NO_LIBCXX case. In the standard case (libc++), the types are zero
overhead aliases or inline passthroughs. In the NO_LIBCXX case, the
types are minimally implemented for only what simdutf directly needs.

Therefore, the **diff is very large, but almost all the changes are
trivial replacements from e.g. `std::pair` to
`simdutf::internal::pair`.**

There are some types I didn't want to shim at all, e.g. `std::span`, but
these were necessary for some of the benchmarks (e.g. the base64 ones).
That's why that's there.

### Reduced Surface Area

This is intentionally a reduced-surface contract rather than an attempt
to fully emulate the standard C++ functionality.

Any public API that directly exposes `std::*` either changes shape or is
compiled out in this mode. In practice this means things like
`implementation::name()` and `implementation::description()` return
`const char *` instead of `std::string`, and helpers such as
`to_string(encoding_type)` similarly return C strings.

APIs that inherently depend on stdlib facilities are not
available at all. That includes `std::span` convenience
overloads, `std::text_encoding` interop, and the `std::atomic_ref`-based
helpers. 

### Avoiding C++ Runtime Hooks

Avoiding libc++ headers is only part of the problem. There are also a few
compiler-emitted ABI hooks that can sneak in even when the source no
longer mentions `std::*`.

The big one is function-local statics, which can introduce
`__cxa_guard_*` references for thread-safe initialization. In the
NO_LIBCXX path I move the implementation singletons and dispatch storage
to translation-unit scope so the runtime detection model stays the same
without requiring those guard functions.

There is also a weak `__cxa_pure_virtual` trap shim for the abstract
implementation vtable case. Correct dispatch should never hit it, but
without it some toolchains still insist on a `libc++abi` dependency just
for that unreachable symbol. It is marked weak so that in compilation
units that do pull in libc++abi, the real `__cxa_pure_virtual` will take
precedence.

The C wrapper is also adjusted to bridge through compiler-native
char16_t/char32_t forms without assuming the normal C++ stdlib type
machinery is available.

## Verification

This type of feature can regress easily, so I added explicit verification.

There is now a dedicated script and CI workflow that:

- compiles the core sources with SIMDUTF_NO_LIBCXX
- checks their undefined symbols for forbidden C++ ABI/runtime entries
such as __cxa_guard_*, exception machinery, RTTI, and dynamic-cast
support
- links smoke tests without the C++ standard library and verifies the
resulting binaries do not depend on libc++, libc++abi,
libstdc++, or libsupc++
- exercises both the normal runtime-dispatch path and the
fallback-only/single-implementation path
- verifies that the single-header build still works with
`-nostdinc++` and `-nostdlib++`

The goal here is not just "make it compile on my machine" but also
to make it maintainable.

## Performance

I ran paired benchmarks for the standard build and the
`SIMDUTF_NO_LIBCXX` build. The benchmarks included all possible
benchmark programs in this repo and all modes.

The conclusion is that performance is broadly unchanged. On the main
throughput benchmarks, most realistic-input results move by only
low-single-digit percentages, and many are effectively flat. I reran
them a few times and they're sometimes faster sometimes slower so I'm
going to say its noise.

The important part is there is no real difference.

## AI Disclaimer

I did this work alongside Codex. I'm not a C++ expert but I'm a very 
experienced systems-level programmer. I constantly changed direction and
nudged the AI in different directions and also did a final pass on the
set of changes.

I'm happy to make adjustments as requested if this is desired and I can
understand and explain any part of this diff.
@mitchellh
Copy link
Copy Markdown
Collaborator Author

CI is green. 🥳

@pauldreik
Copy link
Copy Markdown
Collaborator

I see this as a niche use case and those are fine, but not at any cost.

  • Not using standard C++ types is painful and makes the code harder to read and maintain.
  • We already have nested macros check, increasing this further is not the direction I want to see.

From my point of view, there needs to be a lot more justification for this. Is there any other user than ghostty that would benefit from this?

Can you also please elaborate on the "environments where these dependencies are undesirable."?

@mitchellh
Copy link
Copy Markdown
Collaborator Author

mitchellh commented Apr 15, 2026

Not using standard C++ types is painful and makes the code harder to read and maintain.

Agreed, that's why in all places I tried to keep it syntactically the same but with a namespace shift. I was hoping that'd be good enough where actual code change wasn't really necessary, maybe some muscle memory. 😄

On the maintenance side, I also added the CI check so that maintainers can be confident in continuing to work and merge PRs without breaking the NO_LIBCXX contract. This should make it easy to find places where we mess that up, too.

We already have nested macros check, increasing this further is not the direction I want to see.

Also don't love it, but I think this is only really in implementation.cpp and one of the portability checks, or am I mistaken? Otherwise, I reused macros to prevent multiple macros, e.g. SIMDUTF_NO_LIBCXX redefines SIMDUTF_NO_THREADS so we can reuse macros rather than add additional conditions.

Is there any other user than ghostty that would benefit from this?

I can only speak for myself, though I hope others would speak up. The existence of the prior issue (#158) and some of the responses about this on X (https://x.com/SheriefFYI/status/2044501603244511479) seem to imply this helps others.

Can you also please elaborate on the "environments where these dependencies are undesirable."?

I'll just speak to Ghostty and why It hink generally that's also useful. Ghostty itself is embedding simdutf within a library, not an app (libghostty: https://libghostty.tip.ghostty.org/). Library consumption particularly in bindings is a WHOLE lot easier with less dependencies, ideally none then it can fully statically link.

As an example, the Go bindings are simplified from this since cgo automatically links libc but not libc++, so it forced us to have pkg-config compatibility stuff for libc++. As another example, the Rust bindings libghostty-rs have been having trouble with their own linking of libc++ (again, libc being easy). I can't speak to the specifics but maintainers and users of both encouraged me to prioritize this.

Additionally, libghostty is built to run in Wasm and does so freestanding (no libc either so no emscripten and so on needed. MUCH easier to run and much lower cost). We can't support SIMD there yet but Wasm does support SIMD and from what I can tell it should work well, at least better than scalar.

As a next step, I plan on pursuing a WebAssembly backend for simdutf (#212) with an initial emscripten requirement due to libc, but I also ultimately plan to produce a no-libc version (via providing bindings) so we can use simdutf in the browser without emscripten. That may be a step far for upstream but just so you know to what ends and why I'm pursuing this.

@mitchellh
Copy link
Copy Markdown
Collaborator Author

Sorry I should also add that ultimately I respect whatever outcome this PR has. If the maintainers decide that this isn't desirable then I understand and I'm confident in my ability to maintain a downstream fork for myself and Ghostty will continue to use the fork, since no-libc/c++ is a hard goal of our project.

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 15, 2026

@pauldreik I'll wait to see whether you put your approval before commenting further.

Some thoughts.

  1. This is a pre-existing issue Optionally link against c++ std library #158 dating back to 2022. I gave up on it because removing the standard headers is not sufficient. And I did not see much demand for it, but the issue was initiated by someone else. This PR goes further and actually checks that the dependency on the std lib is gone (in CI).
  2. It does make the lib more complicated and it will increase the maintenance burden. I am less clear on the exact cost.
  3. Much of the additional code and complexity is in one file (stl_compat). So, even though it was done by AI, the design looks quite sound to me.
  4. This PR, by its design, should not affect the performance since when the C++ lib is used (normal case), we go straight to the standard function. This belief should be checked (bugs are possible).
  5. Many of the changes are not bad. Like using internal::pair seems fine.
  6. The precedent being invoked is https://github.com/google/highway which has HWY_NO_LIBCXX. It is not very popular. But it has been around.
  7. It might be possible that this could speed up our command-line utility a tiny amount as it saves linking against the C++ library. To be verified.

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 15, 2026

So I started from this program...

#include <stdio.h>

#include "simdutf.cpp"
#include "simdutf.h"

int main(int, char *[]) {
  const char *source = "1234";
  // 4 == strlen(source)
  bool validutf8 = simdutf::validate_utf8(source, 4);
  if (validutf8) {
    puts("valid UTF-8");
  } else {
    puts("invalid UTF-8");
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

And I build it in two different ways (using this PR):

c++ -O3 -DSIMDUTF_NO_LIBCXX=1 -nostdlib++ -fno-rtti amalgamation_demo.cpp  -fno-exceptions -o nostd
c++ -O3  amalgamation_demo.cpp  -o std

I get...

$ perf stat ./nostd
valid UTF-8

 Performance counter stats for './nostd':

              0.49 msec task-clock:u                     #    0.391 CPUs utilized
                 0      context-switches:u               #    0.000 /sec
                 0      cpu-migrations:u                 #    0.000 /sec
                66      page-faults:u                    #  133.964 K/sec
           176,396      instructions:u                   #    0.47  insn per cycle
           376,269      cycles:u                         #    0.764 GHz
            37,657      branches:u                       #   76.434 M/sec
             2,780      branch-misses:u                  #    7.38% of all branches
                        TopdownL1                 #     32.8 %  tma_backend_bound
                                                  #     14.7 %  tma_bad_speculation
                                                  #     41.9 %  tma_frontend_bound
                                                  #     10.5 %  tma_retiring
                        TopdownL2                 #     14.5 %  tma_branch_mispredicts
                                                  #     14.8 %  tma_core_bound
                                                  #      9.4 %  tma_fetch_bandwidth
                                                  #     32.6 %  tma_fetch_latency
                                                  #      3.9 %  tma_heavy_operations
                                                  #      6.6 %  tma_light_operations
                                                  #      0.2 %  tma_machine_clears
                                                  #     18.0 %  tma_memory_bound

       0.001261206 seconds time elapsed

       0.000000000 seconds user
       0.001376000 seconds sys
$ perf stat ./std
valid UTF-8

 Performance counter stats for './std':

              1.04 msec task-clock:u                     #    0.745 CPUs utilized
                 0      context-switches:u               #    0.000 /sec
                 0      cpu-migrations:u                 #    0.000 /sec
               128      page-faults:u                    #  122.748 K/sec
         2,546,623      instructions:u                   #    1.78  insn per cycle
         1,431,154      cycles:u                         #    1.372 GHz
           455,381      branches:u                       #  436.696 M/sec
            13,270      branch-misses:u                  #    2.91% of all branches
                        TopdownL1                 #     24.1 %  tma_backend_bound
                                                  #     26.8 %  tma_bad_speculation
                                                  #     21.5 %  tma_frontend_bound
                                                  #     27.6 %  tma_retiring
                        TopdownL2                 #     26.1 %  tma_branch_mispredicts
                                                  #     14.0 %  tma_core_bound
                                                  #      7.4 %  tma_fetch_bandwidth
                                                  #     14.1 %  tma_fetch_latency
                                                  #      1.9 %  tma_heavy_operations
                                                  #     25.7 %  tma_light_operations
                                                  #      0.7 %  tma_machine_clears
                                                  #     10.1 %  tma_memory_bound

       0.001400191 seconds time elapsed

       0.000765000 seconds user
       0.000767000 seconds sys

You save about half a millisecond by building without the C++ standard library.

So there is that.

Interestingly, you need all these flags...

-nostdlib++ -fno-rtti -fno-exceptions 

That's what I did not know how to do back in 2022. And it depressed me a bit.

@mitchellh
Copy link
Copy Markdown
Collaborator Author

mitchellh commented Apr 16, 2026

Interestingly, you need all these flags... -nostdlib++ -fno-rtti -fno-exceptions

Yep! That disables RTTI (not used by simdutf so zero issue) and exceptions (aborts programs if any leak through) which are a risk but shouldn't happen in the public ABI codepaths if I recall (they should be handled before then). So it also shouldn't be a problem. But that eliminates a ton of symbols showing up for the ABI use case.

So, even though it was done by AI, the design looks quite sound to me.

And btw, not sure its fair to say it was done by AI. As I noted in my disclosure, I did use assistance, but I came up with the shape of the solution, hand-wrote the initial stl_compat.h, hand-coverted an initial subset of arm64 (since I'm on a Mac), and then basically had Codex "draw the rest of the owl." I also utilized it to help diagnose some other issues and sanity check some of my design choices as a rubber duck.

But in any case, its not like I was driving blind here. 😄

@andrewrk
Copy link
Copy Markdown

Is there any other user than ghostty that would benefit from this?

I hope this doesn't come across as rude, but if I were evaluating simdutf to be a dependency of an application or library, the libc++ dependency would be an immediate disqualification. Parsing text does not fundamentally depend on C++ (nor does it depend on C, but that's a separate conversation).

I think it's safe to say that a large number of potential users would consider this library viable if it were written only with C rather than C++. Given that the API does not really benefit from C++, arguably delivering the functionality via C would be strictly an improvement from users' point of view.

Anecdotally, I have a music player application that I work on, and I recently ported chromaprint away from C++ so that my music player could eliminate the last libc++ dependency. Maybe it's hard to see from the end users' perspective but the libc++ dependency really is burdensome.

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 17, 2026

@mitchellh

Yep! That disables (...) exceptions

For reference, the simdutf library is used in systems where exceptions are disabled such as Chromium V8.

Disabling exceptions is common in C++.

@pauldreik
Copy link
Copy Markdown
Collaborator

so if I try to summarize the benefits:

  • being able to support consumer projects that do not want to link with the standard library
  • being able to support consumer projects that can't link with the standard library (emscripten?)
  • slightly faster start

and the downsides:

  • more macros
  • provide own implementation of std::decay_t, std::min, std::is_same, std::array, std::tuple. I think there is a lot of subtile changes to miss here. for instance, min takes values by copy instead of const ref. is this important? maybe not. but now it has to be considered.
  • redirects of std::memcpy, std::ptrdiff_t. not a big thing, but it increases the burden of understanding the code. seeing std::X means it is already known and familiar, now one has to investigate the implementation to see what differs.
  • makes migration to later C++ standards or features harder. things not already in the stl_compat.h have to be duplicated.
  • this "forks" the implementation. are we sure all variations we compile with still work with the new mode? essentially, a lot of ci would need to be duplicated with this new mode enabled.
  • the api changes depending on mode, for instance what returned a string_view now returns a const char*. it would be better to provide it under another function name or namespace.

There is a concept of freestanding implementation: https://en.cppreference.com/w/cpp/freestanding.html which I only heard of but I have no experience working with it. How would that fit in to the desired usecase for this?

Even if I sympathize with projects wanting to be able to do this, I don't like this change.

@pauldreik pauldreik mentioned this pull request Apr 17, 2026
@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 17, 2026

Ok. So give @pauldreik's concerns, we cannot merge this PR as-is.

But it does not mean we can do NOTHING. Let me see.

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 17, 2026

@mitchellh @pauldreik

I think we can achieve the same result with minimal changes, just picking up the essential parts.

See #962

@lemire
Copy link
Copy Markdown
Member

lemire commented Apr 20, 2026

I am closing this PR, because I really like the follow up PR at #962

It uses the same ideas, and building blocks, but it should make the maintenance much easier... which is something we have to worry about in such a complex library.

@lemire lemire closed this Apr 20, 2026
@pauldreik
Copy link
Copy Markdown
Collaborator

@mitchellh I would like to thank you for your very well written PR and the constructive interaction here. I very much appreciate your effort of writing the description by hand such that it was easy to understand your motivation and changes.

@mitchellh
Copy link
Copy Markdown
Collaborator Author

Thanks @pauldreik. Thanks for the review too and completely respect your opinions. Glad we could all find a way to get this through in some form.

@mitchellh mitchellh deleted the nolibcxx branch April 24, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optionally link against c++ std library

5 participants