Skip to content

[libc++] How to override a single setting in __availability? #87012

Closed
@aheejin

Description

@aheejin

WebAssembly's emscripten toolchain (https://github.com/emscripten-core/emscripten) has been using _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT not to pay for the increased code size of __libcpp_verbose_abort so far. But after #71002, that macro does not exist. We don't provide our own vendor annotation, and defining _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT as 0 is overridden by this line:

# define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 1

I read the discussions in that PR that it is recommended to create our own availability markup like Apple:

#elif defined(__APPLE__)

But to do that it looks we have to copy the whole list of macros here

// These macros control the availability of std::bad_optional_access and
// other exception types. These were put in the shared library to prevent
// code bloat from every user program defining the vtable for these exception
// types.
//
// Note that when exceptions are disabled, the methods that normally throw
// these exceptions can be used even on older deployment targets, but those
// methods will abort instead of throwing.
# define _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS 1
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS 1
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
# define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST 1
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
// These macros control the availability of all parts of <filesystem> that
// depend on something in the dylib.
# define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1
# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
// This controls the availability of the C++20 synchronization library,
// which requires shared library support for various operations
// (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
// <semaphore>, and notification functions on std::atomic.
# define _LIBCPP_AVAILABILITY_HAS_SYNC 1
# define _LIBCPP_AVAILABILITY_SYNC
// Enable additional explicit instantiations of iostreams components. This
// reduces the number of weak definitions generated in programs that use
// iostreams by providing a single strong definition in the shared library.
//
// TODO: Enable additional explicit instantiations on GCC once it supports exclude_from_explicit_instantiation,
// or once libc++ doesn't use the attribute anymore.
// TODO: Enable them on Windows once https://llvm.org/PR41018 has been fixed.
# if !defined(_LIBCPP_COMPILER_GCC) && !defined(_WIN32)
# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 1
# else
# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 0
# endif
// This controls the availability of floating-point std::to_chars functions.
// These overloads were added later than the integer overloads.
# define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
// This controls whether the library claims to provide a default verbose
// termination function, and consequently whether the headers will try
// to use it when the mechanism isn't overriden at compile-time.
# define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 1
# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT
// This controls the availability of the C++17 std::pmr library,
// which is implemented in large part in the built library.
# define _LIBCPP_AVAILABILITY_HAS_PMR 1
# define _LIBCPP_AVAILABILITY_PMR
// These macros controls the availability of __cxa_init_primary_exception
// in the built library, which std::make_exception_ptr might use
// (see libcxx/include/__exception/exception_ptr.h).
# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 1
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
// This controls the availability of C++23 <print>, which
// has a dependency on the built library (it needs access to
// the underlying buffer types of std::cout, std::cerr, and std::clog.
# define _LIBCPP_AVAILABILITY_HAS_PRINT 1
# define _LIBCPP_AVAILABILITY_PRINT
// This controls the availability of the C++20 time zone database.
// The parser code is built in the library.
# define _LIBCPP_AVAILABILITY_HAS_TZDB 1
# define _LIBCPP_AVAILABILITY_TZDB

and copy-paste them to our section in order to just change the one line (_LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT). Is this the recommended way of changing one setting? Is there a way we can control this elsewhere?

This doesn't necessarily have to be about _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT, but it can be more general question about what is the recommended way of toggling one setting without copy-pasting dozens of settings to add another ifdef (__SOMEPLATFORM__) in __availability.

A similar concern was posted in #71002 (comment) by @wang-bin.

cc @philnik777 @ldionne

Activity

added
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
on Mar 28, 2024
ldionne

ldionne commented on Apr 2, 2024

@ldionne
Member

These settings are not intended to be "customizable" in the general sense. Specifically, these settings represent features that are only disabled when the deployment target is too old to support them, such as trying to use <filesystem> on an old OS where the required support had not landed in the shared library yet. In a case like that, it's not a matter of taste or preference: these settings basically prevent the ABI from being broken.

These settings are inherently temporal: whenever we don't support any platform that requires the old behavior, we remove the setting and unconditionally use the new behavior. Hence, we don't want to start allowing for individual settings to be toggled based on preference, since that's not their goal. Many other settings are toggle-able individually and we document them at https://libcxx.llvm.org/UsingLibcxx.html#libc-configuration-macros, but something like _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT doesn't fall in that category.

If you want __libcpp_verbose_abort to be toggle-able individually for code-size reason, I believe what you actually want is something slightly different that gives you a "minimal code size" version of the library. I believe this could make sense, but we'd want to include a lot more than just removing __libcpp_verbose_abort in such a mode. If you want us to investigate this idea, please detail your code size requirements and what kind of things are problematic in libc++ in an issue so we can think about it. This could make sense as part of freestanding support or on its own. For example, we'd definitely want to disable some of the recent vectorization optimizations in algorithms which increase performance but result in more code. That's just one example.

added
questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!
on Apr 2, 2024
added a commit that references this issue on Apr 3, 2024
aheejin

aheejin commented on Apr 9, 2024

@aheejin
MemberAuthor

Thanks for the reply. We don't have a concrete requirement for now, but will post an issue later if we get to work on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ldionne@aheejin@EugeneZelenko

        Issue actions

          [libc++] How to override a single setting in __availability? · Issue #87012 · llvm/llvm-project