[libcxx-commits] [libcxx] [libc++] Reintroduce LIBCXX_ENABLE_FSTREAM for independent fstream support (PR #193453)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 22 03:11:53 PDT 2026
https://github.com/quic-k created https://github.com/llvm/llvm-project/pull/193453
possible fix for https://github.com/llvm/llvm-project/issues/75284
>From bce691546f806a10fe80c591737340aa6204198e Mon Sep 17 00:00:00 2001
From: Kushal Pal <kushpal at qti.qualcomm.com>
Date: Wed, 22 Apr 2026 15:15:43 +0530
Subject: [PATCH] [libc++] Reintroduce LIBCXX_ENABLE_FSTREAM for independent
fstream support
This patch restores the LIBCXX_ENABLE_FSTREAM CMake option, allowing
fstream to be enabled independently of filesystem support.
Signed-off-by: Kushal Pal <kushpal at qti.qualcomm.com>
---
libcxx/CMakeLists.txt | 17 ++++++++++++++--
libcxx/include/__config_site.in | 1 +
libcxx/include/fstream | 34 ++++++++++++++++---------------
libcxx/src/ios.instantiations.cpp | 2 +-
4 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 845240d1b894c..dba1110bfc95b 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -59,8 +59,14 @@ option(LIBCXX_ENABLE_RTTI
This option may only be set to OFF when LIBCXX_ENABLE_EXCEPTIONS=OFF." ON)
option(LIBCXX_ENABLE_FILESYSTEM
"Whether to include support for parts of the library that rely on a filesystem being
- available on the platform. This includes things like most parts of <filesystem> and
- others like <fstream>" ON)
+ available on the platform. This includes things like most parts of <filesystem>.
+ Enabling this option also implies LIBCXX_ENABLE_FSTREAM." ON)
+option(LIBCXX_ENABLE_FSTREAM
+ "Whether to include support for <fstream> in the library. <fstream> requires only
+ basic C stdio support (fopen/fclose/fread/fwrite/fseek) and is independent of full
+ filesystem support (sys/statvfs.h, dirent.h, etc.). Enabling LIBCXX_ENABLE_FILESYSTEM
+ implies this option. Useful for targets that have file I/O but lack the full POSIX
+ filesystem API (e.g. picolibc, wasi-libc)." ON)
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
set(LIBCXX_SUPPORTED_HARDENING_MODES none fast extensive debug)
set(LIBCXX_HARDENING_MODE "none" CACHE STRING
@@ -790,6 +796,13 @@ config_define(${LIBCXX_HAS_C11_THREAD_API} _LIBCPP_HAS_THREAD_API_C11)
config_define(${LIBCXX_HAS_MUSL_LIBC} _LIBCPP_HAS_MUSL_LIBC)
config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
config_define(${LIBCXX_ENABLE_FILESYSTEM} _LIBCPP_HAS_FILESYSTEM)
+# LIBCXX_ENABLE_FILESYSTEM implies LIBCXX_ENABLE_FSTREAM since full filesystem
+# support is a strict superset of fstream support.
+if (LIBCXX_ENABLE_FILESYSTEM AND NOT LIBCXX_ENABLE_FSTREAM)
+ message(STATUS "LIBCXX_ENABLE_FILESYSTEM implies LIBCXX_ENABLE_FSTREAM=ON")
+ set(LIBCXX_ENABLE_FSTREAM ON CACHE BOOL "" FORCE)
+endif()
+config_define(${LIBCXX_ENABLE_FSTREAM} _LIBCPP_HAS_FSTREAM)
config_define(${LIBCXX_ENABLE_RANDOM_DEVICE} _LIBCPP_HAS_RANDOM_DEVICE)
config_define(${LIBCXX_ENABLE_LOCALIZATION} _LIBCPP_HAS_LOCALIZATION)
config_define(${LIBCXX_ENABLE_UNICODE} _LIBCPP_HAS_UNICODE)
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index e6e33a2eeb2a9..d169a28e97382 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -25,6 +25,7 @@
#cmakedefine _LIBCPP_NO_VCRUNTIME
#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@
#cmakedefine01 _LIBCPP_HAS_FILESYSTEM
+#cmakedefine01 _LIBCPP_HAS_FSTREAM
#cmakedefine01 _LIBCPP_HAS_RANDOM_DEVICE
#cmakedefine01 _LIBCPP_HAS_LOCALIZATION
#cmakedefine01 _LIBCPP_HAS_UNICODE
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 4000be8153731..221fe508885e8 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -191,11 +191,13 @@ typedef basic_fstream<wchar_t> wfstream;
#else
# include <__config>
-# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
+# if (_LIBCPP_HAS_FILESYSTEM || _LIBCPP_HAS_FSTREAM) && _LIBCPP_HAS_LOCALIZATION
# include <__algorithm/max.h>
# include <__assert>
-# include <__filesystem/path.h>
+# if _LIBCPP_HAS_FILESYSTEM
+# include <__filesystem/path.h>
+# endif
# include <__fwd/fstream.h>
# include <__locale>
# include <__memory/addressof.h>
@@ -261,7 +263,7 @@ public:
# endif
_LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const filesystem::path& __p, ios_base::openmode __mode) {
return open(__p.c_str(), __mode);
}
@@ -1159,11 +1161,11 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
# endif
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
: basic_ifstream(__p.c_str(), __mode) {}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
_LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
_LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
@@ -1180,11 +1182,11 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
# endif
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
return open(__p.c_str(), __mode);
}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
_LIBCPP_HIDE_FROM_ABI void close();
@@ -1316,11 +1318,11 @@ public:
# endif
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
: basic_ofstream(__p.c_str(), __mode) {}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
_LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
@@ -1339,11 +1341,11 @@ public:
# endif
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
return open(__p.c_str(), __mode);
}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
_LIBCPP_HIDE_FROM_ABI void close();
@@ -1478,11 +1480,11 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
ios_base::openmode __mode = ios_base::in | ios_base::out);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
_LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
: basic_fstream(__p.c_str(), __mode) {}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
@@ -1503,12 +1505,12 @@ public:
# endif
_LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
-# if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void
open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
return open(__p.c_str(), __mode);
}
-# endif // _LIBCPP_STD_VER >= 17
+# endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
_LIBCPP_HIDE_FROM_ABI void close();
@@ -1620,7 +1622,7 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-# endif // _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
+# endif // (_LIBCPP_HAS_FILESYSTEM || _LIBCPP_HAS_FSTREAM) && _LIBCPP_HAS_LOCALIZATION
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <atomic>
diff --git a/libcxx/src/ios.instantiations.cpp b/libcxx/src/ios.instantiations.cpp
index a8d267f7cfd42..1731b506f3c9f 100644
--- a/libcxx/src/ios.instantiations.cpp
+++ b/libcxx/src/ios.instantiations.cpp
@@ -37,7 +37,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
-#if _LIBCPP_HAS_FILESYSTEM
+#if _LIBCPP_HAS_FILESYSTEM || _LIBCPP_HAS_FSTREAM
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
More information about the libcxx-commits
mailing list