Skip to content

Commit 7792731

Browse files
committed
[libc++] Handle Newlib and picolibc using options
Previously, we relied on _NEWLIB_VERSION being defined to detect if we are building with Newlib or its derivative picolibc. This is somewhat unreliable, because whether or not _NEWLIB_VERSION is defined depends on if any headers from the C library have been included or not. This could lead to inconsistent definitions, for example as observed in bug #152763. The code contained a workaround that detected picolibc by looking for its header file, with a TODO to replace this logic with a different mechanism. This change addresses that TODO by handling Newlib and picolibc similarly to how we handle musl: by providing a LIBCXX_HAS_*LIBC option and a corresponding _LIBCPP_HAS_* macro to be used in code. Specifically: - For Newlibc, we provide LIBCXX_HAS_NEWLIB_LIBC and _LIBCPP_HAS_NEWLIB_LIBC. - For picolibc, we provide LIBCXX_HAS_PICOLIBC and _LIBCPP_HAS_PICOLIBC. Existing code has been rewritten so that instead of checking for defined(_NEWLIB_VERSION) it checks for _LIBCPP_HAS_NEWLIB_LIBC || _LIBCPP_HAS_PICOLIBC.
1 parent e92b7e9 commit 7792731

File tree

19 files changed

+31
-36
lines changed

19 files changed

+31
-36
lines changed

libcxx/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ endif()
285285

286286
# Feature options -------------------------------------------------------------
287287
option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
288+
option(LIBCXX_HAS_NEWLIB_LIBC "Build libc++ with support for the Newlib C library" OFF)
289+
option(LIBCXX_HAS_PICOLIBC "Build libc++ with support for the picolibc C library" OFF)
288290
option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
289291
option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
290292
option(LIBCXX_HAS_EXTERNAL_THREAD_API
@@ -742,6 +744,8 @@ config_define(${LIBCXX_HAS_PTHREAD_API} _LIBCPP_HAS_THREAD_API_PTHREAD)
742744
config_define(${LIBCXX_HAS_EXTERNAL_THREAD_API} _LIBCPP_HAS_THREAD_API_EXTERNAL)
743745
config_define(${LIBCXX_HAS_WIN32_THREAD_API} _LIBCPP_HAS_THREAD_API_WIN32)
744746
config_define(${LIBCXX_HAS_MUSL_LIBC} _LIBCPP_HAS_MUSL_LIBC)
747+
config_define(${LIBCXX_HAS_NEWLIB_LIBC} _LIBCPP_HAS_NEWLIB_LIBC)
748+
config_define(${LIBCXX_HAS_PICOLIBC} _LIBCPP_HAS_PICOLIBC)
745749
config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
746750
config_define(${LIBCXX_ENABLE_FILESYSTEM} _LIBCPP_HAS_FILESYSTEM)
747751
config_define(${LIBCXX_ENABLE_RANDOM_DEVICE} _LIBCPP_HAS_RANDOM_DEVICE)

libcxx/include/__configuration/platform.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,6 @@
4242
# endif
4343
#endif
4444

45-
// This is required in order for _NEWLIB_VERSION to be defined in places where we use it.
46-
// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid
47-
// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
48-
#if __has_include(<picolibc.h>)
49-
# include <picolibc.h>
50-
#endif
51-
5245
#ifndef __BYTE_ORDER__
5346
# error \
5447
"Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform"

libcxx/include/__cxx03/__fwd/ios.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>;
3131
template <class _CharT, class _Traits>
3232
class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
3333

34-
#if defined(_NEWLIB_VERSION)
34+
#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
3535
// On newlib, off_t is 'long int'
3636
using streamoff = long int; // for char_traits in <string>
3737
#else

libcxx/include/__cxx03/__locale

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ public:
384384
static const mask xdigit = _ISXDIGIT;
385385
static const mask blank = _ISBLANK;
386386
static const mask __regex_word = 0x8000;
387-
#elif defined(_NEWLIB_VERSION)
387+
#elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
388388
// Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
389389
typedef char mask;
390390
// In case char is signed, static_cast is needed to avoid warning on

libcxx/include/__cxx03/__locale_dir/locale_base_api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# include <__cxx03/__locale_dir/locale_base_api/android.h>
1818
#elif defined(__sun__)
1919
# include <__cxx03/__locale_dir/locale_base_api/solaris.h>
20-
#elif defined(_NEWLIB_VERSION)
20+
#elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
2121
# include <__cxx03/__locale_dir/locale_base_api/newlib.h>
2222
#elif defined(__OpenBSD__)
2323
# include <__cxx03/__locale_dir/locale_base_api/openbsd.h>

libcxx/include/__cxx03/fstream

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ typedef basic_fstream<wchar_t> wfstream;
209209
_LIBCPP_PUSH_MACROS
210210
#include <__cxx03/__undef_macros>
211211

212-
#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
212+
#if defined(_LIBCPP_MSVCRT) || _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
213213
# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
214214
#endif
215215

libcxx/include/__cxx03/locale

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ template <class charT> class messages_byname;
220220

221221
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
222222
// Most unix variants have catopen. These are the specific ones that don't.
223-
# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
223+
# if !defined(__BIONIC__) && !_LIBCPP_HAS_NEWLIB_LIBC && !_LIBCPP_HAS_PICOLIBC && !defined(__EMSCRIPTEN__)
224224
# define _LIBCPP_HAS_CATOPEN 1
225225
# include <nl_types.h>
226226
# endif

libcxx/include/__cxx03/regex

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ public:
984984
typedef _CharT char_type;
985985
typedef basic_string<char_type> string_type;
986986
typedef locale locale_type;
987-
#if defined(__BIONIC__) || defined(_NEWLIB_VERSION)
987+
#if defined(__BIONIC__) || _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
988988
// Originally bionic's ctype_base used its own ctype masks because the
989989
// builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
990990
// was only 8 bits wide and already saturated, so it used a wider type here
@@ -993,11 +993,10 @@ public:
993993
// implementation, but this was not updated to match. Since then Android has
994994
// needed to maintain a stable libc++ ABI, and this can't be changed without
995995
// an ABI break.
996-
// We also need this workaround for newlib since _NEWLIB_VERSION is not
997-
// defined yet inside __config, so we can't set the
998-
// _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is
999-
// often used for space constrained environments, so it makes sense not to
1000-
// duplicate the ctype table.
996+
//
997+
// We also use this logic for Newlib and picolibc. These are often used
998+
// for space constrained environments, so it makes sense no to duplicate
999+
// the ctype table.
10011000
typedef uint16_t char_class_type;
10021001
#else
10031002
typedef ctype_base::mask char_class_type;

libcxx/include/__fwd/ios.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>;
3131
template <class _CharT, class _Traits>
3232
class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
3333

34-
#if defined(_NEWLIB_VERSION)
34+
#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
3535
// On newlib, off_t is 'long int'
3636
using streamoff = long int; // for char_traits in <string>
3737
#else

libcxx/include/__locale

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public:
389389
static const mask xdigit = _ISXDIGIT;
390390
static const mask blank = _ISBLANK;
391391
static const mask __regex_word = 0x8000;
392-
# elif defined(_NEWLIB_VERSION)
392+
# elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC
393393
// Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
394394
typedef char mask;
395395
// In case char is signed, static_cast is needed to avoid warning on

0 commit comments

Comments
 (0)