diff --git a/arm-software/embedded/arm-runtimes/CMakeLists.txt b/arm-software/embedded/arm-runtimes/CMakeLists.txt index 26322e941d5d..2559fcb03543 100644 --- a/arm-software/embedded/arm-runtimes/CMakeLists.txt +++ b/arm-software/embedded/arm-runtimes/CMakeLists.txt @@ -729,6 +729,7 @@ if(ENABLE_CXX_LIBS) -DLIBCXXABI_ENABLE_STATIC_UNWINDER=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_EXCEPTIONS=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_RTTI=${ENABLE_RTTI} + -DLIBCXX_LIBC=picolibc ) if(ENABLE_LIBCXX_TESTS) set(cxxlibs_lit_args "${LLVM_LIT_ARGS} --xunit-xml-output=results.junit.xml") @@ -759,6 +760,7 @@ if(ENABLE_CXX_LIBS) -DLIBCXXABI_ENABLE_STATIC_UNWINDER=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_EXCEPTIONS=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_RTTI=${ENABLE_RTTI} + # -DLIBCXX_LIBC=llvm-libc # this breaks libcxxabi build below by adding -nostdlibinc in HandleLibC.cmake - needs a refactoring to enable ) set(lib_compile_flags "${lib_compile_flags} -D_LIBCPP_PRINT=1") elseif(C_LIBRARY MATCHES "^newlib") @@ -772,6 +774,7 @@ if(ENABLE_CXX_LIBS) -DLIBCXXABI_ENABLE_STATIC_UNWINDER=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_EXCEPTIONS=${ENABLE_EXCEPTIONS} -DLIBCXX_ENABLE_RTTI=${ENABLE_RTTI} + -DLIBCXX_LIBC=newlib ) if(C_LIBRARY STREQUAL newlib-nano) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index dffdd7a3c70a..2c311a74f3c8 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -227,7 +227,7 @@ option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) # C Library options ----------------------------------------------------------- -set(LIBCXX_SUPPORTED_C_LIBRARIES system llvm-libc) +set(LIBCXX_SUPPORTED_C_LIBRARIES system llvm-libc picolibc newlib) set(LIBCXX_LIBC "system" CACHE STRING "Specify C library to use. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.") if (NOT "${LIBCXX_LIBC}" IN_LIST LIBCXX_SUPPORTED_C_LIBRARIES) message(FATAL_ERROR "Unsupported C library: '${LIBCXX_LIBC}'. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.") diff --git a/libcxx/cmake/Modules/HandleLibC.cmake b/libcxx/cmake/Modules/HandleLibC.cmake index 1b0564ae6fcc..656c5dc2427e 100644 --- a/libcxx/cmake/Modules/HandleLibC.cmake +++ b/libcxx/cmake/Modules/HandleLibC.cmake @@ -17,6 +17,7 @@ if (LIBCXX_LIBC STREQUAL "system") # Link against the in-tree LLVM libc elseif (LIBCXX_LIBC STREQUAL "llvm-libc") + set(LIBCXX_LIBC_LLVMLIBC 1) add_library(libcxx-libc-headers INTERFACE) target_link_libraries(libcxx-libc-headers INTERFACE libc-headers) if(CXX_SUPPORTS_NOSTDLIBINC_FLAG) @@ -36,4 +37,13 @@ elseif (LIBCXX_LIBC STREQUAL "llvm-libc") # TODO: There's no support for building LLVM libc as a shared library yet. add_library(libcxx-libc-shared INTERFACE) +elseif (LIBCXX_LIBC STREQUAL "picolibc") + set(LIBCXX_LIBC_PICOLIBC 1) + # picolibc is derived from newlib and behaves the same in regards to libc++ + # so setting both here: + # * LIBCXX_LIBC_NEWLIB is used now + # * LIBCXX_LIBC_PICOLIBC can be used for further customizations later + set(LIBCXX_LIBC_NEWLIB 1) +elseif (LIBCXX_LIBC STREQUAL "newlib") + set(LIBCXX_LIBC_NEWLIB 1) endif() diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in index fc01aaf2d874..f01400bd351e 100644 --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -42,6 +42,11 @@ // Hardening. #cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@ +// C libraries +#cmakedefine LIBCXX_LIBC_LLVMLIBC +#cmakedefine LIBCXX_LIBC_PICOLIBC +#cmakedefine LIBCXX_LIBC_NEWLIB + // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ # pragma clang diagnostic push diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h index 0b9afb2c397f..8d0f8f63f521 100644 --- a/libcxx/include/__configuration/platform.h +++ b/libcxx/include/__configuration/platform.h @@ -42,18 +42,6 @@ # endif #endif -// This is required in order for _NEWLIB_VERSION to be defined in places where we use it. -// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid -// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism. -#if __has_include() -# include -#endif - -// Downstream issue: 378 (Include newlib.h to define _NEWLIB_VERSION) -#if __has_include() -# include -#endif - #ifndef __BYTE_ORDER__ # error \ "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform" diff --git a/libcxx/include/__cxx03/__fwd/ios.h b/libcxx/include/__cxx03/__fwd/ios.h index dc03e8c6bab2..5776ad90ea62 100644 --- a/libcxx/include/__cxx03/__fwd/ios.h +++ b/libcxx/include/__cxx03/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios; template class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if defined(LIBCXX_LIBC_NEWLIB) // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in #else diff --git a/libcxx/include/__cxx03/__locale b/libcxx/include/__cxx03/__locale index d5faa89b99fc..d32ac05d2818 100644 --- a/libcxx/include/__cxx03/__locale +++ b/libcxx/include/__cxx03/__locale @@ -384,7 +384,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -#elif defined(_NEWLIB_VERSION) +#elif defined(LIBCXX_LIBC_NEWLIB) // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h index a20f0952f52c..ccb8201e8ab1 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h @@ -17,7 +17,7 @@ # include <__cxx03/__locale_dir/locale_base_api/android.h> #elif defined(__sun__) # include <__cxx03/__locale_dir/locale_base_api/solaris.h> -#elif defined(_NEWLIB_VERSION) +#elif defined(LIBCXX_LIBC_NEWLIB) # include <__cxx03/__locale_dir/locale_base_api/newlib.h> #elif defined(__OpenBSD__) # include <__cxx03/__locale_dir/locale_base_api/openbsd.h> diff --git a/libcxx/include/__cxx03/fstream b/libcxx/include/__cxx03/fstream index 44bdabc4602b..f7290878bbc0 100644 --- a/libcxx/include/__cxx03/fstream +++ b/libcxx/include/__cxx03/fstream @@ -209,7 +209,7 @@ typedef basic_fstream wfstream; _LIBCPP_PUSH_MACROS #include <__cxx03/__undef_macros> -#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_MSVCRT) || defined(LIBCXX_LIBC_NEWLIB) # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS #endif diff --git a/libcxx/include/__cxx03/locale b/libcxx/include/__cxx03/locale index 64162f5a4ff2..0de138060185 100644 --- a/libcxx/include/__cxx03/locale +++ b/libcxx/include/__cxx03/locale @@ -220,7 +220,7 @@ template class messages_byname; # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !defined(LIBCXX_LIBC_NEWLIB) && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include # endif diff --git a/libcxx/include/__cxx03/regex b/libcxx/include/__cxx03/regex index b96d59d3a252..7b3aaf52dc9f 100644 --- a/libcxx/include/__cxx03/regex +++ b/libcxx/include/__cxx03/regex @@ -984,7 +984,7 @@ public: typedef _CharT char_type; typedef basic_string string_type; typedef locale locale_type; -#if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +#if defined(__BIONIC__) || defined(LIBCXX_LIBC_NEWLIB) // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -993,9 +993,7 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is + // We also need this workaround for newlib since, newlib is // often used for space constrained environments, so it makes sense not to // duplicate the ctype table. typedef uint16_t char_class_type; diff --git a/libcxx/include/__fwd/ios.h b/libcxx/include/__fwd/ios.h index 831624f4b1c5..4db2c5da3861 100644 --- a/libcxx/include/__fwd/ios.h +++ b/libcxx/include/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios; template class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if defined(LIBCXX_LIBC_NEWLIB) // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in #else diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 92e45e2531c2..b0c7e4ca5814 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -389,7 +389,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -# elif defined(_NEWLIB_VERSION) +# elif defined(LIBCXX_LIBC_NEWLIB) // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__locale_dir/messages.h b/libcxx/include/__locale_dir/messages.h index c04bf04025ff..4ebedc9de6d4 100644 --- a/libcxx/include/__locale_dir/messages.h +++ b/libcxx/include/__locale_dir/messages.h @@ -22,7 +22,7 @@ # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !defined(LIBCXX_LIBC_NEWLIB) && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include # else diff --git a/libcxx/include/fstream b/libcxx/include/fstream index a62c085db23d..44715dc5b775 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -192,7 +192,7 @@ typedef basic_fstream wfstream; # include <__config> // Downstream issue: #375 (Enable fstream independently of filesystem) -# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION || defined(_NEWLIB_VERSION) +# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION || defined(LIBCXX_LIBC_NEWLIB) # include <__algorithm/max.h> # include <__assert> @@ -965,7 +965,7 @@ template int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) { # if defined(_LIBCPP_MSVCRT_LIKE) return _fseeki64(__file, __offset, __whence); -# elif defined(_NEWLIB_VERSION) +# elif defined(LIBCXX_LIBC_NEWLIB) return fseek(__file, __offset, __whence); # else return ::fseeko(__file, __offset, __whence); @@ -976,7 +976,7 @@ template typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) { # if defined(_LIBCPP_MSVCRT_LIKE) return _ftelli64(__file); -# elif defined(_NEWLIB_VERSION) +# elif defined(LIBCXX_LIBC_NEWLIB) return ftell(__file); # else return ftello(__file); diff --git a/libcxx/include/regex b/libcxx/include/regex index bbc21e244dd1..29ba9f6a0672 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -1004,7 +1004,7 @@ public: typedef _CharT char_type; typedef basic_string string_type; typedef locale locale_type; -# if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +# if defined(__BIONIC__) || defined(LIBCXX_LIBC_NEWLIB) // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -1013,9 +1013,7 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is + // We also need this workaround for newlib since newlib is // often used for space constrained environments, so it makes sense not to // duplicate the ctype table. typedef uint16_t char_class_type; diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index 7edff2d9375d..388286e41330 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -23,7 +23,7 @@ # define _LIBCPP_ELAST ELAST #elif defined(__LLVM_LIBC__) // No _LIBCPP_ELAST needed for LLVM libc -#elif defined(_NEWLIB_VERSION) +#elif defined(LIBCXX_LIBC_NEWLIB) # define _LIBCPP_ELAST __ELASTERROR #elif defined(__NuttX__) // No _LIBCPP_ELAST needed on NuttX diff --git a/libcxx/src/ios.instantiations.cpp b/libcxx/src/ios.instantiations.cpp index 24106d0a225e..542a6387609a 100644 --- a/libcxx/src/ios.instantiations.cpp +++ b/libcxx/src/ios.instantiations.cpp @@ -38,7 +38,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream; // Downstream issue: #375 (Enable fstream independently of filesystem) -#if _LIBCPP_HAS_FILESYSTEM || defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_FILESYSTEM || defined(LIBCXX_LIBC_NEWLIB) template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf; diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index 30a7a54e1c01..0481d3bb1da1 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -988,7 +988,7 @@ const ctype::mask* ctype::classic_table() noexcept { return __pctype_func(); # elif defined(__EMSCRIPTEN__) return *__ctype_b_loc(); -# elif defined(_NEWLIB_VERSION) +# elif defined(LIBCXX_LIBC_NEWLIB) // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. return _ctype_ + 1; # elif defined(_AIX) diff --git a/libcxx/src/ostream.cpp b/libcxx/src/ostream.cpp index 1cec2db0c45e..a323e38dea0c 100644 --- a/libcxx/src/ostream.cpp +++ b/libcxx/src/ostream.cpp @@ -9,7 +9,7 @@ #include <__config> // Downstream issue: #375 (Enable fstream independently of filesystem) -#if _LIBCPP_HAS_FILESYSTEM || defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_FILESYSTEM || defined(LIBCXX_LIBC_NEWLIB) # include #endif #include diff --git a/libcxx/test/libcxx/system_reserved_names.gen.py b/libcxx/test/libcxx/system_reserved_names.gen.py index a4f2928eda33..5e4809d20fd8 100644 --- a/libcxx/test/libcxx/system_reserved_names.gen.py +++ b/libcxx/test/libcxx/system_reserved_names.gen.py @@ -78,7 +78,7 @@ // Test that libc++ doesn't use names that collide with FreeBSD system macros. // newlib and picolibc also define these macros -#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION) +#if !defined(__FreeBSD__) && !defined(LIBCXX_LIBC_NEWLIB) # define __null_sentinel SYSTEM_RESERVED_NAME # define __generic SYSTEM_RESERVED_NAME #endif @@ -117,7 +117,7 @@ #endif // Newlib & picolibc use __input as a parameter name of a64l & l64a -#ifndef _NEWLIB_VERSION +#ifndef LIBCXX_LIBC_NEWLIB # define __input SYSTEM_RESERVED_NAME #endif #define __output SYSTEM_RESERVED_NAME diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp index 542520330401..b4fa377b7f10 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp @@ -48,7 +48,7 @@ int main(int, char**) // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if defined(LIBCXX_LIBC_NEWLIB) const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index 255cbe75e2fa..b888a9a447e6 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -59,7 +59,7 @@ int main(int, char**) { // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if definedLIBCXX_LIBC_NEWLIB) const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h index 031c434053b8..13fff18b59c9 100644 --- a/libcxx/test/support/platform_support.h +++ b/libcxx/test/support/platform_support.h @@ -41,7 +41,7 @@ # include // _O_EXCL, ... # include // _S_IREAD, ... // Downstream issue: #375 (Enable fstream independently of filesystem) -#elif defined(_NEWLIB_VERSION) +#elif defined(LIBCXX_LIBC_NEWLIB) // No need to include extra headers for the get_temp_file_name() implementation // below: tmpnam() is defined in #elif __has_include() @@ -52,7 +52,7 @@ # include // strverscmp #endif -#if defined(_NEWLIB_VERSION) && defined(__STRICT_ANSI__) +#if defined(LIBCXX_LIBC_NEWLIB) && defined(__STRICT_ANSI__) // Newlib provides this, but in the header it's under __STRICT_ANSI__ extern "C" { int mkstemp(char*); @@ -75,7 +75,7 @@ inline std::string get_temp_file_name() { abort(); } // Downstream issue: #375 (Enable fstream independently of filesystem) -#elif defined(_NEWLIB_VERSION) +#elif defined(LIBCXX_LIBC_NEWLIB) char tmp_name[L_tmpnam]; char *ret = tmpnam(tmp_name); if (ret == NULL) {