Skip to content

Commit f7291f0

Browse files
authored
Add SWIFT_STDLIB_HAS_LOCALE CMake to build stdlib without locale.h and locale based float parsing (#40405)
1 parent df6b279 commit f7291f0

File tree

9 files changed

+98
-31
lines changed

9 files changed

+98
-31
lines changed

cmake/modules/StandaloneOverlay.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ set(SWIFT_DARWIN_MODULE_ARCHS "" CACHE STRING
9292
targets on Darwin platforms. These targets are in addition to the full \
9393
library targets.")
9494

95+
option(SWIFT_STDLIB_HAS_LOCALE
96+
"Build stdlib assuming the platform has locale support."
97+
TRUE)
98+
9599
# -----------------------------------------------------------------------------
96100
# Constants
97101

stdlib/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ else()
6262
set(SWIFT_STDLIB_SUPPORTS_BACKTRACE_REPORTING_default TRUE)
6363
endif()
6464

65+
if("${SWIFT_HOST_VARIANT_SDK}" MATCHES "CYGWIN")
66+
set(SWIFT_STDLIB_HAS_LOCALE_default FALSE)
67+
elseif("${SWIFT_HOST_VARIANT_SDK}" MATCHES "HAIKU")
68+
set(SWIFT_STDLIB_HAS_LOCALE_default FALSE)
69+
else()
70+
set(SWIFT_STDLIB_HAS_LOCALE_default TRUE)
71+
endif()
72+
6573
if("${SWIFT_HOST_VARIANT_SDK}" IN_LIST SWIFT_DARWIN_PLATFORMS)
6674
set(SWIFT_STDLIB_HAS_ASL_default TRUE)
6775
else()
@@ -122,6 +130,10 @@ option(SWIFT_STDLIB_HAS_ENVIRON
122130
"Build stdlib assuming the platform supports environment variables."
123131
TRUE)
124132

133+
option(SWIFT_STDLIB_HAS_LOCALE
134+
"Build stdlib assuming the platform has locale support."
135+
"${SWIFT_STDLIB_HAS_LOCALE_default}")
136+
125137
option(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
126138
"Build the standard libraries assuming that they will be used in an environment with only a single thread."
127139
FALSE)

stdlib/cmake/modules/AddSwiftStdlib.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ function(_add_target_variant_c_compile_flags)
344344
list(APPEND result "-DSWIFT_STDLIB_HAS_ENVIRON")
345345
endif()
346346

347+
if(SWIFT_STDLIB_HAS_LOCALE)
348+
list(APPEND result "-DSWIFT_STDLIB_HAS_LOCALE")
349+
endif()
350+
347351
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
348352
list(APPEND result "-DSWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
349353
endif()

stdlib/public/stubs/Stubs.cpp

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@
2525
// Avoid defining macro max(), min() which conflict with std::max(), std::min()
2626
#define NOMINMAX
2727
#include <windows.h>
28-
#else
29-
#if !defined(__HAIKU__) && !defined(__wasi__)
28+
#else // defined(_WIN32)
29+
#if __has_include(<sys/errno.h>)
3030
#include <sys/errno.h>
3131
#else
3232
#include <errno.h>
3333
#endif
34+
#if __has_include(<sys/resource.h>)
3435
#include <sys/resource.h>
3536
#endif
37+
#endif // else defined(_WIN32)
38+
3639
#include <climits>
37-
#include <clocale>
3840
#include <cmath>
3941
#include <cstdarg>
4042
#include <cstdint>
@@ -44,14 +46,17 @@
4446
#if defined(__CYGWIN__) || defined(__HAIKU__)
4547
#include <sstream>
4648
#endif
47-
#if defined(__OpenBSD__) || defined(__ANDROID__) || defined(__linux__) || defined(__wasi__) || defined(_WIN32)
48-
#include <locale.h>
49+
50+
#if SWIFT_STDLIB_HAS_LOCALE
51+
#include <clocale>
52+
#if __has_include(<xlocale.h>)
53+
#include <xlocale.h>
54+
#endif
4955
#if defined(_WIN32)
5056
#define locale_t _locale_t
5157
#endif
52-
#else
53-
#include <xlocale.h>
54-
#endif
58+
#endif // SWIFT_STDLIB_HAS_LOCALE
59+
5560
#include <limits>
5661
#include <thread>
5762

@@ -138,14 +143,13 @@ uint64_t swift_uint64ToString(char *Buffer, intptr_t BufferLength,
138143
/*Negative=*/false);
139144
}
140145

146+
#if SWIFT_STDLIB_HAS_LOCALE
141147
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__ANDROID__)
142148
static inline locale_t getCLocale() {
143149
// On these platforms convenience functions from xlocale.h interpret nullptr
144150
// as C locale.
145151
return nullptr;
146152
}
147-
#elif defined(__CYGWIN__) || defined(__HAIKU__)
148-
// In Cygwin, getCLocale() is not used.
149153
#elif defined(_WIN32)
150154
static _locale_t makeCLocale() {
151155
_locale_t CLocale = _create_locale(LC_ALL, "C");
@@ -171,6 +175,7 @@ static locale_t getCLocale() {
171175
return SWIFT_LAZY_CONSTANT(makeCLocale());
172176
}
173177
#endif
178+
#endif // SWIFT_STDLIB_HAS_LOCALE
174179

175180
// TODO: replace this with a float16 implementation instead of calling _float.
176181
// Argument type will have to stay float, though; only the formatting changes.
@@ -312,6 +317,8 @@ T _swift_strto(const char *nptr, char **endptr) {
312317
}
313318
#endif
314319

320+
#if SWIFT_STDLIB_HAS_LOCALE
321+
315322
#if defined(__OpenBSD__) || defined(_WIN32) || defined(__CYGWIN__) || defined(__HAIKU__)
316323
#define NEED_SWIFT_STRTOD_L
317324
#define strtod_l swift_strtod_l
@@ -333,6 +340,8 @@ T _swift_strto(const char *nptr, char **endptr) {
333340
#endif
334341
#endif
335342

343+
#endif // SWIFT_STDLIB_HAS_LOCALE
344+
336345
#if defined(NEED_SWIFT_STRTOD_L)
337346
static double swift_strtod_l(const char *nptr, char **endptr, locale_t loc) {
338347
#if defined(_WIN32)
@@ -387,44 +396,63 @@ static inline void _swift_set_errno(int to) {
387396
// We can't return Float80, but we can receive a pointer to one, so
388397
// switch the return type and the out parameter on strtold.
389398
template <typename T>
399+
#if SWIFT_STDLIB_HAS_LOCALE
390400
static const char *_swift_stdlib_strtoX_clocale_impl(
391-
const char * nptr, T* outResult, T huge,
392-
T (*posixImpl)(const char *, char **, locale_t)
393-
) {
401+
const char *nptr, T *outResult, T huge,
402+
T (*posixImpl)(const char *, char **, locale_t))
403+
#else
404+
static const char *_swift_stdlib_strtoX_impl(
405+
const char *nptr, T *outResult,
406+
T (*posixImpl)(const char *, char **))
407+
#endif
408+
{
394409
if (swift_stringIsSignalingNaN(nptr)) {
395410
// TODO: ensure that the returned sNaN bit pattern matches that of sNaNs
396411
// produced by Swift.
397412
*outResult = std::numeric_limits<T>::signaling_NaN();
398413
return nptr + std::strlen(nptr);
399414
}
400-
415+
401416
char *EndPtr;
402417
_swift_set_errno(0);
418+
#if SWIFT_STDLIB_HAS_LOCALE
403419
const auto result = posixImpl(nptr, &EndPtr, getCLocale());
420+
#else
421+
const auto result = posixImpl(nptr, &EndPtr);
422+
#endif
404423
*outResult = result;
405424
return EndPtr;
406425
}
407-
408-
const char *_swift_stdlib_strtold_clocale(
409-
const char * nptr, void *outResult) {
426+
427+
const char *_swift_stdlib_strtold_clocale(const char *nptr, void *outResult) {
428+
#if SWIFT_STDLIB_HAS_LOCALE
410429
return _swift_stdlib_strtoX_clocale_impl(
411-
nptr, static_cast<long double*>(outResult), HUGE_VALL, strtold_l);
430+
nptr, static_cast<long double *>(outResult), HUGE_VALL, strtold_l);
431+
#else
432+
return _swift_stdlib_strtoX_impl(
433+
nptr, static_cast<long double *>(outResult), strtold);
434+
#endif
412435
}
413436

414-
const char *_swift_stdlib_strtod_clocale(
415-
const char * nptr, double *outResult) {
416-
return _swift_stdlib_strtoX_clocale_impl(
417-
nptr, outResult, HUGE_VAL, strtod_l);
437+
const char *_swift_stdlib_strtod_clocale(const char *nptr, double *outResult) {
438+
#if SWIFT_STDLIB_HAS_LOCALE
439+
return _swift_stdlib_strtoX_clocale_impl(nptr, outResult, HUGE_VAL, strtod_l);
440+
#else
441+
return _swift_stdlib_strtoX_impl(nptr, outResult, strtod);
442+
#endif
418443
}
419444

420-
const char *_swift_stdlib_strtof_clocale(
421-
const char * nptr, float *outResult) {
422-
return _swift_stdlib_strtoX_clocale_impl(
423-
nptr, outResult, HUGE_VALF, strtof_l);
445+
const char *_swift_stdlib_strtof_clocale(const char *nptr, float *outResult) {
446+
#if SWIFT_STDLIB_HAS_LOCALE
447+
return _swift_stdlib_strtoX_clocale_impl(nptr, outResult, HUGE_VALF,
448+
strtof_l);
449+
#else
450+
return _swift_stdlib_strtoX_impl(nptr, outResult, strtof);
451+
#endif
424452
}
425453

426-
const char *_swift_stdlib_strtof16_clocale(
427-
const char * nptr, __fp16 *outResult) {
454+
const char *_swift_stdlib_strtof16_clocale(const char *nptr,
455+
__fp16 *outResult) {
428456
float tmp;
429457
const char *result = _swift_stdlib_strtof_clocale(nptr, &tmp);
430458
*outResult = tmp;

test/stdlib/PrintFloat.swift.gyb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// RUN: %line-directive %t/FloatingPointPrinting.swift -- %target-build-swift %t/FloatingPointPrinting.swift -o %t/main.out
44
// RUN: %target-codesign %t/main.out
55
// RUN: %line-directive %t/FloatingPointPrinting.swift -- %target-run %t/main.out
6-
// RUN: %line-directive %t/FloatingPointPrinting.swift -- %target-run %t/main.out --locale ru_RU.UTF-8
76
// REQUIRES: executable_test
87

98
// rdar://77087867
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %gyb %S/PrintFloat.swift.gyb -o %t/FloatingPointPrinting.swift
3+
// RUN: %line-directive %t/FloatingPointPrinting.swift -- %target-build-swift %t/FloatingPointPrinting.swift -o %t/main.out
4+
// RUN: %target-codesign %t/main.out
5+
// RUN: %line-directive %t/FloatingPointPrinting.swift -- %target-run %t/main.out --locale ru_RU.UTF-8
6+
// REQUIRES: executable_test
7+
8+
// rdar://77087867
9+
// UNSUPPORTED: CPU=arm64_32 && OS=watchos
10+
11+
// UNSUPPORTED: freestanding

utils/build-presets.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,7 @@ swift-stdlib-has-darwin-libmalloc=0
25302530
swift-stdlib-has-asl=0
25312531
swift-stdlib-has-stdin=0
25322532
swift-stdlib-has-environ=0
2533+
swift-stdlib-has-locale=0
25332534
swift-runtime-static-image-inspection=1
25342535
swift-stdlib-single-threaded-runtime=1
25352536
swift-stdlib-os-versioning=0

utils/build-script-impl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ KNOWN_SETTINGS=(
218218
swift-stdlib-has-asl "" "whether the stdlib can use the asl_log API, defaults to true on Darwin, false otherwise"
219219
swift-stdlib-has-stdin "1" "whether to build stdlib assuming the platform supports stdin and getline API"
220220
swift-stdlib-has-environ "1" "whether to build stdlib assuming the platform supports environment variables"
221+
swift-stdlib-has-locale "" "whether to build stdlib assuming the platform has locale support"
221222
swift-stdlib-lto "" "enable LLVM LTO on the stdlib, valid values are empty string (no LTO), 'full' and 'thin'"
222223
swift-stdlib-enable-prespecialization "" "whether stdlib should be built with generic metadata prespecialization enabled, defaults to true on Darwin and Linux, false otherwise"
223224
swift-stdlib-passthrough-metadata-allocator "0" "whether stdlib should be built without a custom implementation of MetadataAllocator, relying on malloc+free instead"
@@ -2147,6 +2148,13 @@ for host in "${ALL_HOSTS[@]}"; do
21472148
)
21482149
fi
21492150

2151+
if [[ "${SWIFT_STDLIB_HAS_LOCALE}" ]] ; then
2152+
cmake_options=(
2153+
"${cmake_options[@]}"
2154+
-DSWIFT_STDLIB_HAS_LOCALE:BOOL=$(true_false "${SWIFT_STDLIB_HAS_LOCALE}")
2155+
)
2156+
fi
2157+
21502158
if [ "${SWIFT_INSTALL_COMPONENTS}" ] ; then
21512159
cmake_options=(
21522160
"${cmake_options[@]}"

utils/check_freestanding_dependencies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
"_fputc", "_fputs", "_free", "_funlockfile", "_fwrite", "_malloc",
4848
"_malloc_size", "_memchr", "_memcmp", "_memcpy", "_memmove", "_memset",
4949
"_posix_memalign", "_putc", "_read", "_realloc", "_snprintf", "_strchr",
50-
"_strcmp", "_strdup", "_strlen", "_strncmp", "_strtod_l", "_strtof_l",
51-
"_strtol", "_strtold_l", "_vsnprintf", "_write",
50+
"_strcmp", "_strdup", "_strlen", "_strncmp", "_strtod", "_strtof",
51+
"_strtol", "_strtold", "_vsnprintf", "_write",
5252
] + cxx_dependencies + math_dependencies
5353
vendor_apple_specific_dependencies = [
5454
"___stack_chk_fail", "___stack_chk_guard",

0 commit comments

Comments
 (0)