diff mbox series

[2/2] PR libstdc++/86756 Move rest of std::filesystem to libstdc++.so

Message ID 20190106223631.GM15627@redhat.com
State New
Headers show
Series [1/2] PR libstdc++/86756 add std::filesystem::path to libstdc++.so | expand

Commit Message

Jonathan Wakely Jan. 6, 2019, 10:36 p.m. UTC
Move std::filesystem directory iterators and operations from
libstdc++fs.a to main libstdc++ library. These components have many
dependencies on OS support, which is not available on all targets. Some
additional autoconf checks and conditional compilation is needed to
ensure the files will build for all targets. Previously this code was
not compiled without --enable-libstdcxx-filesystem-ts but the C++17
components should be available for all hosted builds.

The tests for these components no longer need to link to libstdc++fs.a,
but are not expected to pass on all targets. To avoid numerous failures
on targets which are not expected to pass the tests (due to missing OS
functionality) leave the dg-require-filesystem-ts directives in place
for now. This will ensure the tests only run for builds where the
filesystem-ts library is built, which presumably means some level of OS
support is present.


Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.

Committed to trunk.

Comments

Christophe Lyon Jan. 7, 2019, 9:24 a.m. UTC | #1
Hi Jonathan

On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> Move std::filesystem directory iterators and operations from
> libstdc++fs.a to main libstdc++ library. These components have many
> dependencies on OS support, which is not available on all targets. Some
> additional autoconf checks and conditional compilation is needed to
> ensure the files will build for all targets. Previously this code was
> not compiled without --enable-libstdcxx-filesystem-ts but the C++17
> components should be available for all hosted builds.
>
> The tests for these components no longer need to link to libstdc++fs.a,
> but are not expected to pass on all targets. To avoid numerous failures
> on targets which are not expected to pass the tests (due to missing OS
> functionality) leave the dg-require-filesystem-ts directives in place
> for now. This will ensure the tests only run for builds where the
> filesystem-ts library is built, which presumably means some level of OS
> support is present.
>
>
> Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>
> Committed to trunk.
>

After this commit (r267616), I've noticed build failures for my
newlib-based toolchains:
aarch64-elf, arm-eabi:

In file included from
/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
error: '::truncate' has not been declared
  142 |   using ::truncate;
      |           ^~~~~~~~
/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
In function 'void std::filesystem::resize_file(const
std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
error: 'truncate' is not a member of 'posix'
 1274 |   else if (posix::truncate(p.c_str(), size))
      |                   ^~~~~~~~
make[5]: *** [fs_ops.lo] Error 1

I'm not sure if there's an obvious fix? Note that I'm using a rather
old newlib version, if that matters.

Thanks,

Christophe
Jonathan Wakely Jan. 7, 2019, 9:48 a.m. UTC | #2
On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>Hi Jonathan
>
>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> Move std::filesystem directory iterators and operations from
>> libstdc++fs.a to main libstdc++ library. These components have many
>> dependencies on OS support, which is not available on all targets. Some
>> additional autoconf checks and conditional compilation is needed to
>> ensure the files will build for all targets. Previously this code was
>> not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>> components should be available for all hosted builds.
>>
>> The tests for these components no longer need to link to libstdc++fs.a,
>> but are not expected to pass on all targets. To avoid numerous failures
>> on targets which are not expected to pass the tests (due to missing OS
>> functionality) leave the dg-require-filesystem-ts directives in place
>> for now. This will ensure the tests only run for builds where the
>> filesystem-ts library is built, which presumably means some level of OS
>> support is present.
>>
>>
>> Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>>
>> Committed to trunk.
>>
>
>After this commit (r267616), I've noticed build failures for my
>newlib-based toolchains:
>aarch64-elf, arm-eabi:
>
>In file included from
>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>error: '::truncate' has not been declared
>  142 |   using ::truncate;
>      |           ^~~~~~~~
>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>In function 'void std::filesystem::resize_file(const
>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>error: 'truncate' is not a member of 'posix'
> 1274 |   else if (posix::truncate(p.c_str(), size))
>      |                   ^~~~~~~~
>make[5]: *** [fs_ops.lo] Error 1
>
>I'm not sure if there's an obvious fix? Note that I'm using a rather
>old newlib version, if that matters.

That's probably the reason, as I didn't see this in my tests with
newlib builds.

The fix is to add yet another autoconf check and guard the uses of
truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
Jonathan Wakely Jan. 7, 2019, 12:39 p.m. UTC | #3
On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
>On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>>Hi Jonathan
>>
>>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>
>>>Move std::filesystem directory iterators and operations from
>>>libstdc++fs.a to main libstdc++ library. These components have many
>>>dependencies on OS support, which is not available on all targets. Some
>>>additional autoconf checks and conditional compilation is needed to
>>>ensure the files will build for all targets. Previously this code was
>>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>>>components should be available for all hosted builds.
>>>
>>>The tests for these components no longer need to link to libstdc++fs.a,
>>>but are not expected to pass on all targets. To avoid numerous failures
>>>on targets which are not expected to pass the tests (due to missing OS
>>>functionality) leave the dg-require-filesystem-ts directives in place
>>>for now. This will ensure the tests only run for builds where the
>>>filesystem-ts library is built, which presumably means some level of OS
>>>support is present.
>>>
>>>
>>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>>>
>>>Committed to trunk.
>>>
>>
>>After this commit (r267616), I've noticed build failures for my
>>newlib-based toolchains:
>>aarch64-elf, arm-eabi:
>>
>>In file included from
>>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>>error: '::truncate' has not been declared
>> 142 |   using ::truncate;
>>     |           ^~~~~~~~
>>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>>In function 'void std::filesystem::resize_file(const
>>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>>error: 'truncate' is not a member of 'posix'
>>1274 |   else if (posix::truncate(p.c_str(), size))
>>     |                   ^~~~~~~~
>>make[5]: *** [fs_ops.lo] Error 1
>>
>>I'm not sure if there's an obvious fix? Note that I'm using a rather
>>old newlib version, if that matters.
>
>That's probably the reason, as I didn't see this in my tests with
>newlib builds.
>
>The fix is to add yet another autoconf check and guard the uses of
>truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...


Should be fixed with this patch, committed to trunk as r267647.
commit 5f0f0401171507e887f9ba775bcf243d3b3aff91
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jan 7 11:47:20 2019 +0000

    Fix build for systems without POSIX truncate
    
    Older versions of newlib do not provide truncate so add a configure
    check for it, and provide a fallback definition.
    
    There were also some missing exports in the linker script, which went
    unnoticed because there are no tests for some functions. A new link-only
    test checks that every filesystem operation function is defined by the
    library.
    
            * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for truncate.
            * config.h.in: Regenerate.
            * config/abi/pre/gnu.ver: Order patterns for filesystem operations
            alphabetically and add missing entries for copy_symlink,
            hard_link_count, rename, and resize_file.
            * configure: Regenerate.
            * src/c++17/fs_ops.cc (resize_file): Remove #if so posix::truncate is
            used unconditionally.
            * src/filesystem/ops-common.h (__gnu_posix::truncate)
            [!_GLIBCXX_HAVE_TRUNCATE]: Provide fallback definition that only
            supports truncating to zero length.
            * testsuite/27_io/filesystem/operations/all.cc: New test.
            * testsuite/27_io/filesystem/operations/resize_file.cc: New test.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index ce91e495fab..8950e4c8872 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4589,6 +4589,19 @@ dnl
       AC_DEFINE(HAVE_SYMLINK, 1, [Define if symlink is available in <unistd.h>.])
     fi
     AC_MSG_RESULT($glibcxx_cv_symlink)
+dnl
+    AC_MSG_CHECKING([for truncate])
+    AC_CACHE_VAL(glibcxx_cv_truncate, [dnl
+      GCC_TRY_COMPILE_OR_LINK(
+        [#include <unistd.h>],
+        [truncate("", 99);],
+        [glibcxx_cv_truncate=yes],
+        [glibcxx_cv_truncate=no])
+    ])
+    if test $glibcxx_cv_truncate = yes; then
+      AC_DEFINE(HAVE_TRUNCATE, 1, [Define if truncate is available in <unistd.h>.])
+    fi
+    AC_MSG_RESULT($glibcxx_cv_truncate)
 dnl
     CXXFLAGS="$ac_save_CXXFLAGS"
     AC_LANG_RESTORE
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 20325bf7a33..02a6ec90375 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2167,31 +2167,35 @@ GLIBCXX_3.4.26 {
     _ZNSt10filesystem7__cxx114pathpLERKS1_;
     _ZT[IV]NSt10filesystem7__cxx1116filesystem_errorE;
 
-    _ZNSt10filesystem10equivalent*;
-    _ZNSt10filesystem10remove_all*;
-    _ZNSt10filesystem11permissions*;
-    _ZNSt10filesystem12current_path*;
-    _ZNSt10filesystem12read_symlink*;
-    _ZNSt10filesystem14create_symlink*;
-    _ZNSt10filesystem14symlink_status*;
-    _ZNSt10filesystem15last_write_time*;
-    _ZNSt10filesystem16create_directory*;
-    _ZNSt10filesystem16create_hard_link*;
-    _ZNSt10filesystem16weakly_canonical*;
-    _ZNSt10filesystem18create_directories*;
-    _ZNSt10filesystem19temp_directory_path*;
-    _ZNSt10filesystem24create_directory_symlink*;
-    _ZNSt10filesystem4copy*;
-    _ZNSt10filesystem5space*;
-    _ZNSt10filesystem6remove*;
-    _ZNSt10filesystem6status*;
     _ZNSt10filesystem8absolute*;
-    _ZNSt10filesystem8is_empty*;
-    _ZNSt10filesystem8relative*;
     _ZNSt10filesystem9canonical*;
+    _ZNSt10filesystem4copy*;
     _ZNSt10filesystem9copy_file*;
+    _ZNSt10filesystem12copy_symlink*;
+    _ZNSt10filesystem18create_directories*;
+    _ZNSt10filesystem16create_directory*;
+    _ZNSt10filesystem24create_directory_symlink*;
+    _ZNSt10filesystem16create_hard_link*;
+    _ZNSt10filesystem14create_symlink*;
+    _ZNSt10filesystem12current_path*;
+    _ZNSt10filesystem10equivalent*;
     _ZNSt10filesystem9file_size*;
+    _ZNSt10filesystem15hard_link_count*;
+    _ZNSt10filesystem8is_empty*;
+    _ZNSt10filesystem15last_write_time*;
+    _ZNSt10filesystem11permissions*;
     _ZNSt10filesystem9proximate*;
+    _ZNSt10filesystem12read_symlink*;
+    _ZNSt10filesystem8relative*;
+    _ZNSt10filesystem6remove*;
+    _ZNSt10filesystem10remove_all*;
+    _ZNSt10filesystem6rename*;
+    _ZNSt10filesystem11resize_file*;
+    _ZNSt10filesystem5space*;
+    _ZNSt10filesystem6status*;
+    _ZNSt10filesystem14symlink_status*;
+    _ZNSt10filesystem19temp_directory_path*;
+    _ZNSt10filesystem16weakly_canonical*;
 
     _ZNKSt10filesystem18directory_iteratordeEv;
     _ZNKSt10filesystem28recursive_directory_iterator5depthEv;
diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index fd8cf353ba2..edd9315980b 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -1268,16 +1268,12 @@ fs::resize_file(const path& p, uintmax_t size)
 void
 fs::resize_file(const path& p, uintmax_t size, error_code& ec) noexcept
 {
-#ifdef _GLIBCXX_HAVE_UNISTD_H
   if (size > static_cast<uintmax_t>(std::numeric_limits<off_t>::max()))
     ec.assign(EINVAL, std::generic_category());
   else if (posix::truncate(p.c_str(), size))
     ec.assign(errno, std::generic_category());
   else
     ec.clear();
-#else
-  ec = std::make_error_code(std::errc::not_supported);
-#endif
 }
 
 
diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h
index f20867c217e..55e482ff8f2 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -29,6 +29,9 @@
 
 #ifdef _GLIBCXX_HAVE_UNISTD_H
 # include <unistd.h>
+# ifdef _GLIBCXX_HAVE_FCNTL_H
+#  include <fcntl.h>  // AT_FDCWD, O_TRUNC etc.
+# endif
 # if defined(_GLIBCXX_HAVE_SYS_STAT_H) && defined(_GLIBCXX_HAVE_SYS_TYPES_H)
 #  include <sys/types.h>
 #  include <sys/stat.h>
@@ -139,7 +142,23 @@ namespace __gnu_posix
   using ::utime;
 # endif
   using ::rename;
+# ifdef _GLIBCXX_HAVE_TRUNCATE
   using ::truncate;
+# else
+  inline int truncate(const char* path, off_t length)
+  {
+    if (length == 0)
+      {
+	const int fd = ::open(path, O_WRONLY|O_TRUNC);
+	if (fd == -1)
+	  return fd;
+	::close(fd);
+	return 0;
+      }
+    errno = ENOTSUP;
+    return -1;
+  }
+# endif
   using char_type = char;
 #else // ! _GLIBCXX_FILESYSTEM_IS_WINDOWS && ! _GLIBCXX_HAVE_UNISTD_H
   inline int open(const char*, int, ...) { errno = ENOTSUP; return -1; }
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/all.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/all.cc
new file mode 100644
index 00000000000..c9f34f4a7af
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/all.cc
@@ -0,0 +1,188 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17 -fno-inline" }
+// { dg-do link { target c++17 } }
+
+// C++17 30.10.15 Filesystem operation functions [fs.op.funcs]
+
+#include <filesystem>
+
+// Link-only test to ensure all operation functions are exported from the lib.
+
+int
+main()
+{
+  const std::filesystem::path p;
+  std::filesystem::path p2;
+  const std::filesystem::copy_options copyopts{};
+  const std::filesystem::file_status st{};
+  std::filesystem::file_status st2;
+  const std::filesystem::file_time_type t;
+  std::filesystem::file_time_type t2;
+  const std::filesystem::perms perms{};
+  const std::filesystem::perm_options permopts{};
+  std::filesystem::space_info sp;
+  std::error_code ec;
+  bool b;
+  std::uintmax_t size;
+
+  std::filesystem::absolute(p);
+  std::filesystem::absolute(p, ec);
+
+  std::filesystem::canonical(p);
+  std::filesystem::canonical(p, ec);
+
+  std::filesystem::copy(p, p);
+  std::filesystem::copy(p, p, ec);
+  std::filesystem::copy(p, p, copyopts);
+  std::filesystem::copy(p, p, copyopts, ec);
+
+  std::filesystem::copy_file(p, p);
+  std::filesystem::copy_file(p, p, ec);
+  std::filesystem::copy_file(p, p, copyopts);
+  std::filesystem::copy_file(p, p, copyopts, ec);
+
+  std::filesystem::copy_symlink(p, p);
+  std::filesystem::copy_symlink(p, p, ec);
+
+  std::filesystem::create_directories(p);
+  std::filesystem::create_directories(p, ec);
+
+  std::filesystem::create_directory(p);
+  std::filesystem::create_directory(p, ec);
+
+  std::filesystem::create_directory(p, p);
+  std::filesystem::create_directory(p, p, ec);
+
+  std::filesystem::create_directory_symlink(p, p);
+  std::filesystem::create_directory_symlink(p, p, ec);
+
+  std::filesystem::create_hard_link(p, p);
+  std::filesystem::create_hard_link(p, p, ec);
+
+  std::filesystem::create_symlink(p, p);
+  std::filesystem::create_symlink(p, p, ec);
+
+  p2 = std::filesystem::current_path();
+  p2 = std::filesystem::current_path(ec);
+  std::filesystem::current_path(p);
+  std::filesystem::current_path(p, ec);
+
+  b = std::filesystem::equivalent(p, p);
+  b = std::filesystem::equivalent(p, p, ec);
+
+  b = std::filesystem::exists(st);
+  b = std::filesystem::exists(p);
+  b = std::filesystem::exists(p, ec);
+
+  size = std::filesystem::file_size(p);
+  size = std::filesystem::file_size(p, ec);
+
+  size = std::filesystem::hard_link_count(p);
+  size = std::filesystem::hard_link_count(p, ec);
+
+  b = std::filesystem::is_block_file(st);
+  b = std::filesystem::is_block_file(p);
+  b = std::filesystem::is_block_file(p, ec);
+
+  b = std::filesystem::is_character_file(st);
+  b = std::filesystem::is_character_file(p);
+  b = std::filesystem::is_character_file(p, ec);
+
+  b = std::filesystem::is_directory(st);
+  b = std::filesystem::is_directory(p);
+  b = std::filesystem::is_directory(p, ec);
+
+  b = std::filesystem::is_empty(p);
+  b = std::filesystem::is_empty(p, ec);
+
+  b = std::filesystem::is_fifo(st);
+  b = std::filesystem::is_fifo(p);
+  b = std::filesystem::is_fifo(p, ec);
+
+  b = std::filesystem::is_other(st);
+  b = std::filesystem::is_other(p);
+  b = std::filesystem::is_other(p, ec);
+
+  b = std::filesystem::is_regular_file(st);
+  b = std::filesystem::is_regular_file(p);
+  b = std::filesystem::is_regular_file(p, ec);
+
+  b = std::filesystem::is_socket(st);
+  b = std::filesystem::is_socket(p);
+  b = std::filesystem::is_socket(p, ec);
+
+  b = std::filesystem::is_symlink(st);
+  b = std::filesystem::is_symlink(p);
+  b = std::filesystem::is_symlink(p, ec);
+
+  t2 = std::filesystem::last_write_time(p);
+  t2 = std::filesystem::last_write_time(p, ec);
+  std::filesystem::last_write_time(p, t);
+  std::filesystem::last_write_time(p, t, ec);
+
+  std::filesystem::permissions(p, perms);
+  std::filesystem::permissions(p, perms, permopts);
+  std::filesystem::permissions(p, perms, ec);
+  std::filesystem::permissions(p, perms, permopts, ec);
+
+  p2 = std::filesystem::proximate(p, ec);
+  p2 = std::filesystem::proximate(p);
+  p2 = std::filesystem::proximate(p, p);
+  p2 = std::filesystem::proximate(p, p, ec);
+
+  p2 = std::filesystem::read_symlink(p);
+  p2 = std::filesystem::read_symlink(p, ec);
+
+  p2 = std::filesystem::relative(p, ec);
+  p2 = std::filesystem::relative(p);
+  p2 = std::filesystem::relative(p, p);
+  p2 = std::filesystem::relative(p, p, ec);
+
+  b = std::filesystem::remove(p);
+  b = std::filesystem::remove(p, ec);
+
+  size = std::filesystem::remove_all(p);
+  size = std::filesystem::remove_all(p, ec);
+
+  std::filesystem::rename(p, p);
+  std::filesystem::rename(p, p, ec);
+
+  std::filesystem::resize_file(p, size);
+  std::filesystem::resize_file(p, size, ec);
+
+  sp = std::filesystem::space(p);
+  sp = std::filesystem::space(p, ec);
+
+  st2 = std::filesystem::status(p);
+  st2 = std::filesystem::status(p, ec);
+
+  b = std::filesystem::status_known(st);
+
+  st2 = std::filesystem::symlink_status(p);
+  st2 = std::filesystem::symlink_status(p, ec);
+
+  p2 = std::filesystem::temp_directory_path();
+  p2 = std::filesystem::temp_directory_path(ec);
+
+  p2 = std::filesystem::weakly_canonical(p);
+  p2 = std::filesystem::weakly_canonical(p, ec);
+}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/resize_file.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/resize_file.cc
new file mode 100644
index 00000000000..953c4e1c664
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/resize_file.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// C++17 30.10.15.33 Resize file [fs.op.resize_file]
+
+#include <filesystem>
+#include <string>
+#include <fstream>
+#include <testsuite_fs.h>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  auto p = __gnu_test::nonexistent_path();
+  std::error_code ec;
+  resize_file(p, 0, ec);
+  VERIFY( ec );
+  ec = {};
+  resize_file(p, 1, ec);
+  VERIFY( ec );
+
+  __gnu_test::scoped_file f(p);
+  std::ofstream{p} << "some text";
+  std::ifstream fin;
+  std::string input;
+
+#ifdef _GLIBCXX_HAVE_TRUNCATE
+  resize_file(p, 4, ec);
+  VERIFY( !ec );
+  fin.open(p);
+  getline(fin, input);
+  VERIFY( input.length() == 4 );
+  fin.close();
+
+  resize_file(p, 2);
+  fin.open(p);
+  getline(fin, input);
+  VERIFY( input.length() == 2 );
+  fin.close();
+#endif
+
+  resize_file(p, 0, ec);
+  VERIFY( !ec );
+  fin.open(p);
+  getline(fin, input);
+  VERIFY( input.length() == 0 );
+  fin.close();
+}
+
+int
+main()
+{
+  test01();
+}
Christophe Lyon Jan. 7, 2019, 2:14 p.m. UTC | #4
On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
> >>Hi Jonathan
> >>
> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
> >>>
> >>>Move std::filesystem directory iterators and operations from
> >>>libstdc++fs.a to main libstdc++ library. These components have many
> >>>dependencies on OS support, which is not available on all targets. Some
> >>>additional autoconf checks and conditional compilation is needed to
> >>>ensure the files will build for all targets. Previously this code was
> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
> >>>components should be available for all hosted builds.
> >>>
> >>>The tests for these components no longer need to link to libstdc++fs.a,
> >>>but are not expected to pass on all targets. To avoid numerous failures
> >>>on targets which are not expected to pass the tests (due to missing OS
> >>>functionality) leave the dg-require-filesystem-ts directives in place
> >>>for now. This will ensure the tests only run for builds where the
> >>>filesystem-ts library is built, which presumably means some level of OS
> >>>support is present.
> >>>
> >>>
> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
> >>>
> >>>Committed to trunk.
> >>>
> >>
> >>After this commit (r267616), I've noticed build failures for my
> >>newlib-based toolchains:
> >>aarch64-elf, arm-eabi:
> >>
> >>In file included from
> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
> >>error: '::truncate' has not been declared
> >> 142 |   using ::truncate;
> >>     |           ^~~~~~~~
> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
> >>In function 'void std::filesystem::resize_file(const
> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
> >>error: 'truncate' is not a member of 'posix'
> >>1274 |   else if (posix::truncate(p.c_str(), size))
> >>     |                   ^~~~~~~~
> >>make[5]: *** [fs_ops.lo] Error 1
> >>
> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
> >>old newlib version, if that matters.
> >
> >That's probably the reason, as I didn't see this in my tests with
> >newlib builds.
> >
> >The fix is to add yet another autoconf check and guard the uses of
> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
>
>
> Should be fixed with this patch, committed to trunk as r267647.
>

Yes, it works. Thanks!

Christophe
Christophe Lyon Jan. 8, 2019, 10:13 a.m. UTC | #5
On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>
> On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
> >
> > On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
> > >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
> > >>Hi Jonathan
> > >>
> > >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
> > >>>
> > >>>Move std::filesystem directory iterators and operations from
> > >>>libstdc++fs.a to main libstdc++ library. These components have many
> > >>>dependencies on OS support, which is not available on all targets. Some
> > >>>additional autoconf checks and conditional compilation is needed to
> > >>>ensure the files will build for all targets. Previously this code was
> > >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
> > >>>components should be available for all hosted builds.
> > >>>
> > >>>The tests for these components no longer need to link to libstdc++fs.a,
> > >>>but are not expected to pass on all targets. To avoid numerous failures
> > >>>on targets which are not expected to pass the tests (due to missing OS
> > >>>functionality) leave the dg-require-filesystem-ts directives in place
> > >>>for now. This will ensure the tests only run for builds where the
> > >>>filesystem-ts library is built, which presumably means some level of OS
> > >>>support is present.
> > >>>
> > >>>
> > >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
> > >>>
> > >>>Committed to trunk.
> > >>>
> > >>
> > >>After this commit (r267616), I've noticed build failures for my
> > >>newlib-based toolchains:
> > >>aarch64-elf, arm-eabi:
> > >>
> > >>In file included from
> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
> > >>error: '::truncate' has not been declared
> > >> 142 |   using ::truncate;
> > >>     |           ^~~~~~~~
> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
> > >>In function 'void std::filesystem::resize_file(const
> > >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
> > >>error: 'truncate' is not a member of 'posix'
> > >>1274 |   else if (posix::truncate(p.c_str(), size))
> > >>     |                   ^~~~~~~~
> > >>make[5]: *** [fs_ops.lo] Error 1
> > >>
> > >>I'm not sure if there's an obvious fix? Note that I'm using a rather
> > >>old newlib version, if that matters.
> > >
> > >That's probably the reason, as I didn't see this in my tests with
> > >newlib builds.
> > >
> > >The fix is to add yet another autoconf check and guard the uses of
> > >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
> >
> >
> > Should be fixed with this patch, committed to trunk as r267647.
> >
>
> Yes, it works. Thanks!
>

Hi Jonathan,

So... this was a confirmation that the GCC build succeeded, not that
the tests pass :)

And there are actually a couple new errors with my newlib-based toolchains:
FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
which are also UNRESOLVED, because of link-time undefined reference to `chdir',
chmod, mkdir, pathconf and getcwd.

On aarch64, I'm seeing an addtional:
FAIL: 27_io/filesystem/path/compare/strings.cc execution test
because:
/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.


Christophe
Jonathan Wakely Jan. 9, 2019, 10:09 a.m. UTC | #6
On 08/01/19 11:13 +0100, Christophe Lyon wrote:
>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>>
>> On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >
>> > On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
>> > >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>> > >>Hi Jonathan
>> > >>
>> > >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>> > >>>
>> > >>>Move std::filesystem directory iterators and operations from
>> > >>>libstdc++fs.a to main libstdc++ library. These components have many
>> > >>>dependencies on OS support, which is not available on all targets. Some
>> > >>>additional autoconf checks and conditional compilation is needed to
>> > >>>ensure the files will build for all targets. Previously this code was
>> > >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>> > >>>components should be available for all hosted builds.
>> > >>>
>> > >>>The tests for these components no longer need to link to libstdc++fs.a,
>> > >>>but are not expected to pass on all targets. To avoid numerous failures
>> > >>>on targets which are not expected to pass the tests (due to missing OS
>> > >>>functionality) leave the dg-require-filesystem-ts directives in place
>> > >>>for now. This will ensure the tests only run for builds where the
>> > >>>filesystem-ts library is built, which presumably means some level of OS
>> > >>>support is present.
>> > >>>
>> > >>>
>> > >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>> > >>>
>> > >>>Committed to trunk.
>> > >>>
>> > >>
>> > >>After this commit (r267616), I've noticed build failures for my
>> > >>newlib-based toolchains:
>> > >>aarch64-elf, arm-eabi:
>> > >>
>> > >>In file included from
>> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>> > >>error: '::truncate' has not been declared
>> > >> 142 |   using ::truncate;
>> > >>     |           ^~~~~~~~
>> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>> > >>In function 'void std::filesystem::resize_file(const
>> > >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>> > >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>> > >>error: 'truncate' is not a member of 'posix'
>> > >>1274 |   else if (posix::truncate(p.c_str(), size))
>> > >>     |                   ^~~~~~~~
>> > >>make[5]: *** [fs_ops.lo] Error 1
>> > >>
>> > >>I'm not sure if there's an obvious fix? Note that I'm using a rather
>> > >>old newlib version, if that matters.
>> > >
>> > >That's probably the reason, as I didn't see this in my tests with
>> > >newlib builds.
>> > >
>> > >The fix is to add yet another autoconf check and guard the uses of
>> > >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
>> >
>> >
>> > Should be fixed with this patch, committed to trunk as r267647.
>> >
>>
>> Yes, it works. Thanks!
>>
>
>Hi Jonathan,
>
>So... this was a confirmation that the GCC build succeeded, not that
>the tests pass :)
>
>And there are actually a couple new errors with my newlib-based toolchains:
>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
>chmod, mkdir, pathconf and getcwd.

Ah, I was assuming if <unistd.h> is present, then those basic
functions will be present. More autoconf checks needed, I guess.
That isn't hard to do, just tedious.

>On aarch64, I'm seeing an addtional:
>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>because:
>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.

Odd, I don't know why that would be target-specific. It's probably
just latent on other targets. I'll try to reproduce it on my aarch64
system, but it will take a while to build current trunk.

If you have time, could you please apply this patch, re-run that test
(cd $target/libstdc++-v3 && make check
RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?

On x86_64 I get:

Comparing  as path:-1 as string:-1
Comparing / as path:-1 as string:-1
Comparing // as path:-1 as string:-1
Comparing /. as path:-51 as string:-51
Comparing /./ as path:-51 as string:-51
Comparing /a as path:-2 as string:-2
Comparing /a/ as path:-1 as string:-1
Comparing /a// as path:-1 as string:-1
Comparing /a/b/c/d as path:1 as string:1
Comparing /a//b as path:1 as string:1
Comparing a as path:-1 as string:-1
Comparing a/b as path:-1 as string:-1
Comparing a/b/ as path:-1 as string:-1
Comparing a/b/c as path:-1 as string:-1
Comparing a/b/c.d as path:-1 as string:-1
Comparing a/b/.. as path:-1 as string:-1
Comparing a/b/c. as path:-1 as string:-1
Comparing a/b/.c as path:-1 as string:-1
PASS: 27_io/filesystem/path/compare/strings.cc execution test
Jonathan Wakely Jan. 9, 2019, 10:11 a.m. UTC | #7
On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
>On 08/01/19 11:13 +0100, Christophe Lyon wrote:
>>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>>>
>>>On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>>
>>>> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
>>>> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>>>> >>Hi Jonathan
>>>> >>
>>>> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>> >>>
>>>> >>>Move std::filesystem directory iterators and operations from
>>>> >>>libstdc++fs.a to main libstdc++ library. These components have many
>>>> >>>dependencies on OS support, which is not available on all targets. Some
>>>> >>>additional autoconf checks and conditional compilation is needed to
>>>> >>>ensure the files will build for all targets. Previously this code was
>>>> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>>>> >>>components should be available for all hosted builds.
>>>> >>>
>>>> >>>The tests for these components no longer need to link to libstdc++fs.a,
>>>> >>>but are not expected to pass on all targets. To avoid numerous failures
>>>> >>>on targets which are not expected to pass the tests (due to missing OS
>>>> >>>functionality) leave the dg-require-filesystem-ts directives in place
>>>> >>>for now. This will ensure the tests only run for builds where the
>>>> >>>filesystem-ts library is built, which presumably means some level of OS
>>>> >>>support is present.
>>>> >>>
>>>> >>>
>>>> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>>>> >>>
>>>> >>>Committed to trunk.
>>>> >>>
>>>> >>
>>>> >>After this commit (r267616), I've noticed build failures for my
>>>> >>newlib-based toolchains:
>>>> >>aarch64-elf, arm-eabi:
>>>> >>
>>>> >>In file included from
>>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>>>> >>error: '::truncate' has not been declared
>>>> >> 142 |   using ::truncate;
>>>> >>     |           ^~~~~~~~
>>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>>>> >>In function 'void std::filesystem::resize_file(const
>>>> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>>>> >>error: 'truncate' is not a member of 'posix'
>>>> >>1274 |   else if (posix::truncate(p.c_str(), size))
>>>> >>     |                   ^~~~~~~~
>>>> >>make[5]: *** [fs_ops.lo] Error 1
>>>> >>
>>>> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
>>>> >>old newlib version, if that matters.
>>>> >
>>>> >That's probably the reason, as I didn't see this in my tests with
>>>> >newlib builds.
>>>> >
>>>> >The fix is to add yet another autoconf check and guard the uses of
>>>> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
>>>>
>>>>
>>>> Should be fixed with this patch, committed to trunk as r267647.
>>>>
>>>
>>>Yes, it works. Thanks!
>>>
>>
>>Hi Jonathan,
>>
>>So... this was a confirmation that the GCC build succeeded, not that
>>the tests pass :)
>>
>>And there are actually a couple new errors with my newlib-based toolchains:
>>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
>>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
>>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
>>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
>>chmod, mkdir, pathconf and getcwd.
>
>Ah, I was assuming if <unistd.h> is present, then those basic
>functions will be present. More autoconf checks needed, I guess.
>That isn't hard to do, just tedious.
>
>>On aarch64, I'm seeing an addtional:
>>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>>because:
>>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
>
>Odd, I don't know why that would be target-specific. It's probably
>just latent on other targets. I'll try to reproduce it on my aarch64
>system, but it will take a while to build current trunk.
>
>If you have time, could you please apply this patch, re-run that test

*This* patch:

--- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
@@ -36,6 +36,7 @@ test01()
     path p(s);
     VERIFY( p.compare(s) == 0 );
     VERIFY( p.compare(s.c_str()) == 0 );
+    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
     VERIFY( p.compare(p0) == p.compare(s0) );
     VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
   }




>(cd $target/libstdc++-v3 && make check
>RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
>the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
>
>On x86_64 I get:
>
>Comparing  as path:-1 as string:-1
>Comparing / as path:-1 as string:-1
>Comparing // as path:-1 as string:-1
>Comparing /. as path:-51 as string:-51
>Comparing /./ as path:-51 as string:-51
>Comparing /a as path:-2 as string:-2
>Comparing /a/ as path:-1 as string:-1
>Comparing /a// as path:-1 as string:-1
>Comparing /a/b/c/d as path:1 as string:1
>Comparing /a//b as path:1 as string:1
>Comparing a as path:-1 as string:-1
>Comparing a/b as path:-1 as string:-1
>Comparing a/b/ as path:-1 as string:-1
>Comparing a/b/c as path:-1 as string:-1
>Comparing a/b/c.d as path:-1 as string:-1
>Comparing a/b/.. as path:-1 as string:-1
>Comparing a/b/c. as path:-1 as string:-1
>Comparing a/b/.c as path:-1 as string:-1
>PASS: 27_io/filesystem/path/compare/strings.cc execution test
>
Christophe Lyon Jan. 9, 2019, 12:53 p.m. UTC | #8
On Wed, 9 Jan 2019 at 11:11, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
> >On 08/01/19 11:13 +0100, Christophe Lyon wrote:
> >>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
> >>>
> >>>On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
> >>>>
> >>>> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
> >>>> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
> >>>> >>Hi Jonathan
> >>>> >>
> >>>> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
> >>>> >>>
> >>>> >>>Move std::filesystem directory iterators and operations from
> >>>> >>>libstdc++fs.a to main libstdc++ library. These components have many
> >>>> >>>dependencies on OS support, which is not available on all targets. Some
> >>>> >>>additional autoconf checks and conditional compilation is needed to
> >>>> >>>ensure the files will build for all targets. Previously this code was
> >>>> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
> >>>> >>>components should be available for all hosted builds.
> >>>> >>>
> >>>> >>>The tests for these components no longer need to link to libstdc++fs.a,
> >>>> >>>but are not expected to pass on all targets. To avoid numerous failures
> >>>> >>>on targets which are not expected to pass the tests (due to missing OS
> >>>> >>>functionality) leave the dg-require-filesystem-ts directives in place
> >>>> >>>for now. This will ensure the tests only run for builds where the
> >>>> >>>filesystem-ts library is built, which presumably means some level of OS
> >>>> >>>support is present.
> >>>> >>>
> >>>> >>>
> >>>> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
> >>>> >>>
> >>>> >>>Committed to trunk.
> >>>> >>>
> >>>> >>
> >>>> >>After this commit (r267616), I've noticed build failures for my
> >>>> >>newlib-based toolchains:
> >>>> >>aarch64-elf, arm-eabi:
> >>>> >>
> >>>> >>In file included from
> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
> >>>> >>error: '::truncate' has not been declared
> >>>> >> 142 |   using ::truncate;
> >>>> >>     |           ^~~~~~~~
> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
> >>>> >>In function 'void std::filesystem::resize_file(const
> >>>> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
> >>>> >>error: 'truncate' is not a member of 'posix'
> >>>> >>1274 |   else if (posix::truncate(p.c_str(), size))
> >>>> >>     |                   ^~~~~~~~
> >>>> >>make[5]: *** [fs_ops.lo] Error 1
> >>>> >>
> >>>> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
> >>>> >>old newlib version, if that matters.
> >>>> >
> >>>> >That's probably the reason, as I didn't see this in my tests with
> >>>> >newlib builds.
> >>>> >
> >>>> >The fix is to add yet another autoconf check and guard the uses of
> >>>> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
> >>>>
> >>>>
> >>>> Should be fixed with this patch, committed to trunk as r267647.
> >>>>
> >>>
> >>>Yes, it works. Thanks!
> >>>
> >>
> >>Hi Jonathan,
> >>
> >>So... this was a confirmation that the GCC build succeeded, not that
> >>the tests pass :)
> >>
> >>And there are actually a couple new errors with my newlib-based toolchains:
> >>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
> >>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
> >>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
> >>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
> >>chmod, mkdir, pathconf and getcwd.
> >
> >Ah, I was assuming if <unistd.h> is present, then those basic
> >functions will be present. More autoconf checks needed, I guess.
> >That isn't hard to do, just tedious.
> >
> >>On aarch64, I'm seeing an addtional:
> >>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
> >>because:
> >>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
> >>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
> >
> >Odd, I don't know why that would be target-specific. It's probably
> >just latent on other targets. I'll try to reproduce it on my aarch64
> >system, but it will take a while to build current trunk.
> >
> >If you have time, could you please apply this patch, re-run that test
>
> *This* patch:
>
> --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
> +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
> @@ -36,6 +36,7 @@ test01()
>      path p(s);
>      VERIFY( p.compare(s) == 0 );
>      VERIFY( p.compare(s.c_str()) == 0 );
> +    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
>      VERIFY( p.compare(p0) == p.compare(s0) );
>      VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
>    }
>
>
>
>
> >(cd $target/libstdc++-v3 && make check
> >RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
> >the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
> >
> >On x86_64 I get:
> >
> >Comparing  as path:-1 as string:-1
> >Comparing / as path:-1 as string:-1
> >Comparing // as path:-1 as string:-1
> >Comparing /. as path:-51 as string:-51
> >Comparing /./ as path:-51 as string:-51
> >Comparing /a as path:-2 as string:-2
> >Comparing /a/ as path:-1 as string:-1
> >Comparing /a// as path:-1 as string:-1
> >Comparing /a/b/c/d as path:1 as string:1
> >Comparing /a//b as path:1 as string:1
> >Comparing a as path:-1 as string:-1
> >Comparing a/b as path:-1 as string:-1
> >Comparing a/b/ as path:-1 as string:-1
> >Comparing a/b/c as path:-1 as string:-1
> >Comparing a/b/c.d as path:-1 as string:-1
> >Comparing a/b/.. as path:-1 as string:-1
> >Comparing a/b/c. as path:-1 as string:-1
> >Comparing a/b/.c as path:-1 as string:-1
> >PASS: 27_io/filesystem/path/compare/strings.cc execution test
> >

Here is what I have on aarch64-none-elf:
Comparing  as path:-1 as string:-1^M
Comparing / as path:-1 as string:-1^M
Comparing // as path:-1 as string:-1^M
Comparing /. as path:-102 as string:-51^M
/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:40:
void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.^M
^M
*** EXIT code 4242^M
emu: host signal 6^M
FAIL: 27_io/filesystem/path/compare/strings.cc execution test
Jonathan Wakely Jan. 9, 2019, 5:02 p.m. UTC | #9
On 09/01/19 13:53 +0100, Christophe Lyon wrote:
>On Wed, 9 Jan 2019 at 11:11, Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
>> >On 08/01/19 11:13 +0100, Christophe Lyon wrote:
>> >>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>> >>>
>> >>>On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >>>>
>> >>>> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
>> >>>> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>> >>>> >>Hi Jonathan
>> >>>> >>
>> >>>> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >>>> >>>
>> >>>> >>>Move std::filesystem directory iterators and operations from
>> >>>> >>>libstdc++fs.a to main libstdc++ library. These components have many
>> >>>> >>>dependencies on OS support, which is not available on all targets. Some
>> >>>> >>>additional autoconf checks and conditional compilation is needed to
>> >>>> >>>ensure the files will build for all targets. Previously this code was
>> >>>> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>> >>>> >>>components should be available for all hosted builds.
>> >>>> >>>
>> >>>> >>>The tests for these components no longer need to link to libstdc++fs.a,
>> >>>> >>>but are not expected to pass on all targets. To avoid numerous failures
>> >>>> >>>on targets which are not expected to pass the tests (due to missing OS
>> >>>> >>>functionality) leave the dg-require-filesystem-ts directives in place
>> >>>> >>>for now. This will ensure the tests only run for builds where the
>> >>>> >>>filesystem-ts library is built, which presumably means some level of OS
>> >>>> >>>support is present.
>> >>>> >>>
>> >>>> >>>
>> >>>> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>> >>>> >>>
>> >>>> >>>Committed to trunk.
>> >>>> >>>
>> >>>> >>
>> >>>> >>After this commit (r267616), I've noticed build failures for my
>> >>>> >>newlib-based toolchains:
>> >>>> >>aarch64-elf, arm-eabi:
>> >>>> >>
>> >>>> >>In file included from
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>> >>>> >>error: '::truncate' has not been declared
>> >>>> >> 142 |   using ::truncate;
>> >>>> >>     |           ^~~~~~~~
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>> >>>> >>In function 'void std::filesystem::resize_file(const
>> >>>> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>> >>>> >>error: 'truncate' is not a member of 'posix'
>> >>>> >>1274 |   else if (posix::truncate(p.c_str(), size))
>> >>>> >>     |                   ^~~~~~~~
>> >>>> >>make[5]: *** [fs_ops.lo] Error 1
>> >>>> >>
>> >>>> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
>> >>>> >>old newlib version, if that matters.
>> >>>> >
>> >>>> >That's probably the reason, as I didn't see this in my tests with
>> >>>> >newlib builds.
>> >>>> >
>> >>>> >The fix is to add yet another autoconf check and guard the uses of
>> >>>> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
>> >>>>
>> >>>>
>> >>>> Should be fixed with this patch, committed to trunk as r267647.
>> >>>>
>> >>>
>> >>>Yes, it works. Thanks!
>> >>>
>> >>
>> >>Hi Jonathan,
>> >>
>> >>So... this was a confirmation that the GCC build succeeded, not that
>> >>the tests pass :)
>> >>
>> >>And there are actually a couple new errors with my newlib-based toolchains:
>> >>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
>> >>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
>> >>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
>> >>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
>> >>chmod, mkdir, pathconf and getcwd.
>> >
>> >Ah, I was assuming if <unistd.h> is present, then those basic
>> >functions will be present. More autoconf checks needed, I guess.
>> >That isn't hard to do, just tedious.
>> >
>> >>On aarch64, I'm seeing an addtional:
>> >>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>> >>because:
>> >>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>> >>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
>> >
>> >Odd, I don't know why that would be target-specific. It's probably
>> >just latent on other targets. I'll try to reproduce it on my aarch64
>> >system, but it will take a while to build current trunk.
>> >
>> >If you have time, could you please apply this patch, re-run that test
>>
>> *This* patch:
>>
>> --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> @@ -36,6 +36,7 @@ test01()
>>      path p(s);
>>      VERIFY( p.compare(s) == 0 );
>>      VERIFY( p.compare(s.c_str()) == 0 );
>> +    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
>>      VERIFY( p.compare(p0) == p.compare(s0) );
>>      VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
>>    }
>>
>>
>>
>>
>> >(cd $target/libstdc++-v3 && make check
>> >RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
>> >the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
>> >
>> >On x86_64 I get:
>> >
>> >Comparing  as path:-1 as string:-1
>> >Comparing / as path:-1 as string:-1
>> >Comparing // as path:-1 as string:-1
>> >Comparing /. as path:-51 as string:-51
>> >Comparing /./ as path:-51 as string:-51
>> >Comparing /a as path:-2 as string:-2
>> >Comparing /a/ as path:-1 as string:-1
>> >Comparing /a// as path:-1 as string:-1
>> >Comparing /a/b/c/d as path:1 as string:1
>> >Comparing /a//b as path:1 as string:1
>> >Comparing a as path:-1 as string:-1
>> >Comparing a/b as path:-1 as string:-1
>> >Comparing a/b/ as path:-1 as string:-1
>> >Comparing a/b/c as path:-1 as string:-1
>> >Comparing a/b/c.d as path:-1 as string:-1
>> >Comparing a/b/.. as path:-1 as string:-1
>> >Comparing a/b/c. as path:-1 as string:-1
>> >Comparing a/b/.c as path:-1 as string:-1
>> >PASS: 27_io/filesystem/path/compare/strings.cc execution test
>> >
>
>Here is what I have on aarch64-none-elf:
>Comparing  as path:-1 as string:-1^M
>Comparing / as path:-1 as string:-1^M
>Comparing // as path:-1 as string:-1^M
>Comparing /. as path:-102 as string:-51^M

Ah, that should help me fix it - thanks.


>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:40:
>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.^M
>^M
>*** EXIT code 4242^M
>emu: host signal 6^M
>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
Jonathan Wakely Jan. 23, 2019, 3:28 p.m. UTC | #10
On 09/01/19 13:53 +0100, Christophe Lyon wrote:
>On Wed, 9 Jan 2019 at 11:11, Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
>> >On 08/01/19 11:13 +0100, Christophe Lyon wrote:
>> >>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>> >>>
>> >>>On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >>>>
>> >>>> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
>> >>>> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
>> >>>> >>Hi Jonathan
>> >>>> >>
>> >>>> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >>>> >>>
>> >>>> >>>Move std::filesystem directory iterators and operations from
>> >>>> >>>libstdc++fs.a to main libstdc++ library. These components have many
>> >>>> >>>dependencies on OS support, which is not available on all targets. Some
>> >>>> >>>additional autoconf checks and conditional compilation is needed to
>> >>>> >>>ensure the files will build for all targets. Previously this code was
>> >>>> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
>> >>>> >>>components should be available for all hosted builds.
>> >>>> >>>
>> >>>> >>>The tests for these components no longer need to link to libstdc++fs.a,
>> >>>> >>>but are not expected to pass on all targets. To avoid numerous failures
>> >>>> >>>on targets which are not expected to pass the tests (due to missing OS
>> >>>> >>>functionality) leave the dg-require-filesystem-ts directives in place
>> >>>> >>>for now. This will ensure the tests only run for builds where the
>> >>>> >>>filesystem-ts library is built, which presumably means some level of OS
>> >>>> >>>support is present.
>> >>>> >>>
>> >>>> >>>
>> >>>> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
>> >>>> >>>
>> >>>> >>>Committed to trunk.
>> >>>> >>>
>> >>>> >>
>> >>>> >>After this commit (r267616), I've noticed build failures for my
>> >>>> >>newlib-based toolchains:
>> >>>> >>aarch64-elf, arm-eabi:
>> >>>> >>
>> >>>> >>In file included from
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
>> >>>> >>error: '::truncate' has not been declared
>> >>>> >> 142 |   using ::truncate;
>> >>>> >>     |           ^~~~~~~~
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
>> >>>> >>In function 'void std::filesystem::resize_file(const
>> >>>> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
>> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
>> >>>> >>error: 'truncate' is not a member of 'posix'
>> >>>> >>1274 |   else if (posix::truncate(p.c_str(), size))
>> >>>> >>     |                   ^~~~~~~~
>> >>>> >>make[5]: *** [fs_ops.lo] Error 1
>> >>>> >>
>> >>>> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
>> >>>> >>old newlib version, if that matters.
>> >>>> >
>> >>>> >That's probably the reason, as I didn't see this in my tests with
>> >>>> >newlib builds.
>> >>>> >
>> >>>> >The fix is to add yet another autoconf check and guard the uses of
>> >>>> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
>> >>>>
>> >>>>
>> >>>> Should be fixed with this patch, committed to trunk as r267647.
>> >>>>
>> >>>
>> >>>Yes, it works. Thanks!
>> >>>
>> >>
>> >>Hi Jonathan,
>> >>
>> >>So... this was a confirmation that the GCC build succeeded, not that
>> >>the tests pass :)
>> >>
>> >>And there are actually a couple new errors with my newlib-based toolchains:
>> >>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
>> >>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
>> >>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
>> >>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
>> >>chmod, mkdir, pathconf and getcwd.
>> >
>> >Ah, I was assuming if <unistd.h> is present, then those basic
>> >functions will be present. More autoconf checks needed, I guess.
>> >That isn't hard to do, just tedious.
>> >
>> >>On aarch64, I'm seeing an addtional:
>> >>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>> >>because:
>> >>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>> >>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
>> >
>> >Odd, I don't know why that would be target-specific. It's probably
>> >just latent on other targets. I'll try to reproduce it on my aarch64
>> >system, but it will take a while to build current trunk.
>> >
>> >If you have time, could you please apply this patch, re-run that test
>>
>> *This* patch:
>>
>> --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> @@ -36,6 +36,7 @@ test01()
>>      path p(s);
>>      VERIFY( p.compare(s) == 0 );
>>      VERIFY( p.compare(s.c_str()) == 0 );
>> +    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
>>      VERIFY( p.compare(p0) == p.compare(s0) );
>>      VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
>>    }
>>
>>
>>
>>
>> >(cd $target/libstdc++-v3 && make check
>> >RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
>> >the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
>> >
>> >On x86_64 I get:
>> >
>> >Comparing  as path:-1 as string:-1
>> >Comparing / as path:-1 as string:-1
>> >Comparing // as path:-1 as string:-1
>> >Comparing /. as path:-51 as string:-51
>> >Comparing /./ as path:-51 as string:-51
>> >Comparing /a as path:-2 as string:-2
>> >Comparing /a/ as path:-1 as string:-1
>> >Comparing /a// as path:-1 as string:-1
>> >Comparing /a/b/c/d as path:1 as string:1
>> >Comparing /a//b as path:1 as string:1
>> >Comparing a as path:-1 as string:-1
>> >Comparing a/b as path:-1 as string:-1
>> >Comparing a/b/ as path:-1 as string:-1
>> >Comparing a/b/c as path:-1 as string:-1
>> >Comparing a/b/c.d as path:-1 as string:-1
>> >Comparing a/b/.. as path:-1 as string:-1
>> >Comparing a/b/c. as path:-1 as string:-1
>> >Comparing a/b/.c as path:-1 as string:-1
>> >PASS: 27_io/filesystem/path/compare/strings.cc execution test
>> >
>
>Here is what I have on aarch64-none-elf:
>Comparing  as path:-1 as string:-1^M
>Comparing / as path:-1 as string:-1^M
>Comparing // as path:-1 as string:-1^M
>Comparing /. as path:-102 as string:-51^M
>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:40:
>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.^M
>^M
>*** EXIT code 4242^M
>emu: host signal 6^M
>FAIL: 27_io/filesystem/path/compare/strings.cc execution test

This is a strange one. With my aarch64-unknown-linux-gnu trunk build I get:

Comparing /. as path:-51 as string:-51

Which suggests it's a newlib vs glibc difference, but this target uses
glibc (right?) and has the same FAIL:
https://gcc.gnu.org/ml/gcc-testresults/2019-01/msg02276.html

The test should be reducable to simply:

// { dg-options "-std=gnu++17" }
#include <string>
#include <string_view>

int main()
{
  std::string_view s0 = "a";
  std::string p0(s0);
  std::string p(".");
  __builtin_printf("as path:%d as string:%d\n", p.compare(p0), p.compare(s0));
}

Again, I get -51 and -51 for this. Could you test it on
aarch64-none-elf?

In terms of what the standard requires, this comparison is based on
strcmp, i.e. it only specifies a result less than zero, equal to zero,
or greater than zero. But I'd like to know why the comparisons aren't
returning the same consistent value.
Christophe Lyon Jan. 23, 2019, 4:01 p.m. UTC | #11
On Wed, 23 Jan 2019 at 16:28, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On 09/01/19 13:53 +0100, Christophe Lyon wrote:
> >On Wed, 9 Jan 2019 at 11:11, Jonathan Wakely <jwakely@redhat.com> wrote:
> >>
> >> On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
> >> >On 08/01/19 11:13 +0100, Christophe Lyon wrote:
> >> >>On Mon, 7 Jan 2019 at 15:14, Christophe Lyon <christophe.lyon@linaro.org> wrote:
> >> >>>
> >> >>>On Mon, 7 Jan 2019 at 13:39, Jonathan Wakely <jwakely@redhat.com> wrote:
> >> >>>>
> >> >>>> On 07/01/19 09:48 +0000, Jonathan Wakely wrote:
> >> >>>> >On 07/01/19 10:24 +0100, Christophe Lyon wrote:
> >> >>>> >>Hi Jonathan
> >> >>>> >>
> >> >>>> >>On Sun, 6 Jan 2019 at 23:37, Jonathan Wakely <jwakely@redhat.com> wrote:
> >> >>>> >>>
> >> >>>> >>>Move std::filesystem directory iterators and operations from
> >> >>>> >>>libstdc++fs.a to main libstdc++ library. These components have many
> >> >>>> >>>dependencies on OS support, which is not available on all targets. Some
> >> >>>> >>>additional autoconf checks and conditional compilation is needed to
> >> >>>> >>>ensure the files will build for all targets. Previously this code was
> >> >>>> >>>not compiled without --enable-libstdcxx-filesystem-ts but the C++17
> >> >>>> >>>components should be available for all hosted builds.
> >> >>>> >>>
> >> >>>> >>>The tests for these components no longer need to link to libstdc++fs.a,
> >> >>>> >>>but are not expected to pass on all targets. To avoid numerous failures
> >> >>>> >>>on targets which are not expected to pass the tests (due to missing OS
> >> >>>> >>>functionality) leave the dg-require-filesystem-ts directives in place
> >> >>>> >>>for now. This will ensure the tests only run for builds where the
> >> >>>> >>>filesystem-ts library is built, which presumably means some level of OS
> >> >>>> >>>support is present.
> >> >>>> >>>
> >> >>>> >>>
> >> >>>> >>>Tested x86_64-linux (old/new string ABIs, 32/64 bit), x86_64-w64-mingw32.
> >> >>>> >>>
> >> >>>> >>>Committed to trunk.
> >> >>>> >>>
> >> >>>> >>
> >> >>>> >>After this commit (r267616), I've noticed build failures for my
> >> >>>> >>newlib-based toolchains:
> >> >>>> >>aarch64-elf, arm-eabi:
> >> >>>> >>
> >> >>>> >>In file included from
> >> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:57:
> >> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/../filesystem/ops-common.h:142:11:
> >> >>>> >>error: '::truncate' has not been declared
> >> >>>> >> 142 |   using ::truncate;
> >> >>>> >>     |           ^~~~~~~~
> >> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:
> >> >>>> >>In function 'void std::filesystem::resize_file(const
> >> >>>> >>std::filesystem::__cxx11::path&, uintmax_t, std::error_code&)':
> >> >>>> >>/tmp/5241593_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++17/fs_ops.cc:1274:19:
> >> >>>> >>error: 'truncate' is not a member of 'posix'
> >> >>>> >>1274 |   else if (posix::truncate(p.c_str(), size))
> >> >>>> >>     |                   ^~~~~~~~
> >> >>>> >>make[5]: *** [fs_ops.lo] Error 1
> >> >>>> >>
> >> >>>> >>I'm not sure if there's an obvious fix? Note that I'm using a rather
> >> >>>> >>old newlib version, if that matters.
> >> >>>> >
> >> >>>> >That's probably the reason, as I didn't see this in my tests with
> >> >>>> >newlib builds.
> >> >>>> >
> >> >>>> >The fix is to add yet another autoconf check and guard the uses of
> >> >>>> >truncate with a _GLIBCXX_USE_TRUNCATE macro. I'll do that now ...
> >> >>>>
> >> >>>>
> >> >>>> Should be fixed with this patch, committed to trunk as r267647.
> >> >>>>
> >> >>>
> >> >>>Yes, it works. Thanks!
> >> >>>
> >> >>
> >> >>Hi Jonathan,
> >> >>
> >> >>So... this was a confirmation that the GCC build succeeded, not that
> >> >>the tests pass :)
> >> >>
> >> >>And there are actually a couple new errors with my newlib-based toolchains:
> >> >>FAIL: 27_io/filesystem/operations/all.cc (test for excess errors)
> >> >>FAIL: 27_io/filesystem/operations/resize_file.cc (test for excess errors)
> >> >>FAIL: 27_io/filesystem/path/generation/normal2.cc (test for excess errors)
> >> >>which are also UNRESOLVED, because of link-time undefined reference to `chdir',
> >> >>chmod, mkdir, pathconf and getcwd.
> >> >
> >> >Ah, I was assuming if <unistd.h> is present, then those basic
> >> >functions will be present. More autoconf checks needed, I guess.
> >> >That isn't hard to do, just tedious.
> >> >
> >> >>On aarch64, I'm seeing an addtional:
> >> >>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
> >> >>because:
> >> >>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
> >> >>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
> >> >
> >> >Odd, I don't know why that would be target-specific. It's probably
> >> >just latent on other targets. I'll try to reproduce it on my aarch64
> >> >system, but it will take a while to build current trunk.
> >> >
> >> >If you have time, could you please apply this patch, re-run that test
> >>
> >> *This* patch:
> >>
> >> --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
> >> +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
> >> @@ -36,6 +36,7 @@ test01()
> >>      path p(s);
> >>      VERIFY( p.compare(s) == 0 );
> >>      VERIFY( p.compare(s.c_str()) == 0 );
> >> +    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
> >>      VERIFY( p.compare(p0) == p.compare(s0) );
> >>      VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
> >>    }
> >>
> >>
> >>
> >>
> >> >(cd $target/libstdc++-v3 && make check
> >> >RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
> >> >the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
> >> >
> >> >On x86_64 I get:
> >> >
> >> >Comparing  as path:-1 as string:-1
> >> >Comparing / as path:-1 as string:-1
> >> >Comparing // as path:-1 as string:-1
> >> >Comparing /. as path:-51 as string:-51
> >> >Comparing /./ as path:-51 as string:-51
> >> >Comparing /a as path:-2 as string:-2
> >> >Comparing /a/ as path:-1 as string:-1
> >> >Comparing /a// as path:-1 as string:-1
> >> >Comparing /a/b/c/d as path:1 as string:1
> >> >Comparing /a//b as path:1 as string:1
> >> >Comparing a as path:-1 as string:-1
> >> >Comparing a/b as path:-1 as string:-1
> >> >Comparing a/b/ as path:-1 as string:-1
> >> >Comparing a/b/c as path:-1 as string:-1
> >> >Comparing a/b/c.d as path:-1 as string:-1
> >> >Comparing a/b/.. as path:-1 as string:-1
> >> >Comparing a/b/c. as path:-1 as string:-1
> >> >Comparing a/b/.c as path:-1 as string:-1
> >> >PASS: 27_io/filesystem/path/compare/strings.cc execution test
> >> >
> >
> >Here is what I have on aarch64-none-elf:
> >Comparing  as path:-1 as string:-1^M
> >Comparing / as path:-1 as string:-1^M
> >Comparing // as path:-1 as string:-1^M
> >Comparing /. as path:-102 as string:-51^M
> >/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:40:
> >void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.^M
> >^M
> >*** EXIT code 4242^M
> >emu: host signal 6^M
> >FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>
> This is a strange one. With my aarch64-unknown-linux-gnu trunk build I get:
>
> Comparing /. as path:-51 as string:-51
>
> Which suggests it's a newlib vs glibc difference, but this target uses
> glibc (right?) and has the same FAIL:
> https://gcc.gnu.org/ml/gcc-testresults/2019-01/msg02276.html

Yes, it uses glibc-2.28

That build has this in its libstdc++.log:
/home/tcwg-buildslave/workspace/tcwg-buildfarm_0/snapshots/gcc.git~master_rev_2e9ceebcd7618d0e068e0029b43cd75d679022d7/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
timeout: the monitored command dumped core
FAIL: 27_io/filesystem/path/compare/strings.cc execution test


>
> The test should be reducable to simply:
>
> // { dg-options "-std=gnu++17" }
> #include <string>
> #include <string_view>
>
> int main()
> {
>   std::string_view s0 = "a";
>   std::string p0(s0);
>   std::string p(".");
>   __builtin_printf("as path:%d as string:%d\n", p.compare(p0), p.compare(s0));
> }
>
> Again, I get -51 and -51 for this. Could you test it on
> aarch64-none-elf?
>
> In terms of what the standard requires, this comparison is based on
> strcmp, i.e. it only specifies a result less than zero, equal to zero,
> or greater than zero. But I'd like to know why the comparisons aren't
> returning the same consistent value.
>

I get:
as path:-102 as string:-102
Jonathan Wakely Jan. 24, 2019, 1:07 p.m. UTC | #12
On 23/01/19 17:01 +0100, Christophe Lyon wrote:
>On Wed, 23 Jan 2019 at 16:28, Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> On 09/01/19 13:53 +0100, Christophe Lyon wrote:
>> >On Wed, 9 Jan 2019 at 11:11, Jonathan Wakely <jwakely@redhat.com> wrote:
>> >>
>> >> On 09/01/19 10:09 +0000, Jonathan Wakely wrote:
>> >> >On 08/01/19 11:13 +0100, Christophe Lyon wrote:
>> >> >>On aarch64, I'm seeing an addtional:
>> >> >>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>> >> >>because:
>> >> >>/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>> >> >>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
>> >> >
>> >> >Odd, I don't know why that would be target-specific. It's probably
>> >> >just latent on other targets. I'll try to reproduce it on my aarch64
>> >> >system, but it will take a while to build current trunk.
>> >> >
>> >> >If you have time, could you please apply this patch, re-run that test
>> >>
>> >> *This* patch:
>> >>
>> >> --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> >> +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
>> >> @@ -36,6 +36,7 @@ test01()
>> >>      path p(s);
>> >>      VERIFY( p.compare(s) == 0 );
>> >>      VERIFY( p.compare(s.c_str()) == 0 );
>> >> +    __builtin_printf("Comparing %s as path:%d as string:%d\n", s.c_str(), p.compare(p0), p.compare(s0));
>> >>      VERIFY( p.compare(p0) == p.compare(s0) );
>> >>      VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
>> >>    }
>> >>
>> >>
>> >>
>> >>
>> >> >(cd $target/libstdc++-v3 && make check
>> >> >RUNTESTFLAGS=conformance.exp=*/path/compare/strings/cc) and send me
>> >> >the output from the $target/libstdc++-v3/testsuite/libstdc++.log file?
>> >> >
>> >> >On x86_64 I get:
>> >> >
>> >> >Comparing  as path:-1 as string:-1
>> >> >Comparing / as path:-1 as string:-1
>> >> >Comparing // as path:-1 as string:-1
>> >> >Comparing /. as path:-51 as string:-51
>> >> >Comparing /./ as path:-51 as string:-51
>> >> >Comparing /a as path:-2 as string:-2
>> >> >Comparing /a/ as path:-1 as string:-1
>> >> >Comparing /a// as path:-1 as string:-1
>> >> >Comparing /a/b/c/d as path:1 as string:1
>> >> >Comparing /a//b as path:1 as string:1
>> >> >Comparing a as path:-1 as string:-1
>> >> >Comparing a/b as path:-1 as string:-1
>> >> >Comparing a/b/ as path:-1 as string:-1
>> >> >Comparing a/b/c as path:-1 as string:-1
>> >> >Comparing a/b/c.d as path:-1 as string:-1
>> >> >Comparing a/b/.. as path:-1 as string:-1
>> >> >Comparing a/b/c. as path:-1 as string:-1
>> >> >Comparing a/b/.c as path:-1 as string:-1
>> >> >PASS: 27_io/filesystem/path/compare/strings.cc execution test
>> >> >
>> >
>> >Here is what I have on aarch64-none-elf:
>> >Comparing  as path:-1 as string:-1^M
>> >Comparing / as path:-1 as string:-1^M
>> >Comparing // as path:-1 as string:-1^M
>> >Comparing /. as path:-102 as string:-51^M
>> >/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:40:
>> >void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.^M
>> >^M
>> >*** EXIT code 4242^M
>> >emu: host signal 6^M
>> >FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>>
>> This is a strange one. With my aarch64-unknown-linux-gnu trunk build I get:
>>
>> Comparing /. as path:-51 as string:-51
>>
>> Which suggests it's a newlib vs glibc difference, but this target uses
>> glibc (right?) and has the same FAIL:
>> https://gcc.gnu.org/ml/gcc-testresults/2019-01/msg02276.html
>
>Yes, it uses glibc-2.28
>
>That build has this in its libstdc++.log:
>/home/tcwg-buildslave/workspace/tcwg-buildfarm_0/snapshots/gcc.git~master_rev_2e9ceebcd7618d0e068e0029b43cd75d679022d7/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc:39:
>void test01(): Assertion 'p.compare(p0) == p.compare(s0)' failed.
>timeout: the monitored command dumped core
>FAIL: 27_io/filesystem/path/compare/strings.cc execution test
>
>
>>
>> The test should be reducable to simply:
>>
>> // { dg-options "-std=gnu++17" }
>> #include <string>
>> #include <string_view>
>>
>> int main()
>> {
>>   std::string_view s0 = "a";
>>   std::string p0(s0);
>>   std::string p(".");
>>   __builtin_printf("as path:%d as string:%d\n", p.compare(p0), p.compare(s0));
>> }
>>
>> Again, I get -51 and -51 for this. Could you test it on
>> aarch64-none-elf?
>>
>> In terms of what the standard requires, this comparison is based on
>> strcmp, i.e. it only specifies a result less than zero, equal to zero,
>> or greater than zero. But I'd like to know why the comparisons aren't
>> returning the same consistent value.
>>
>
>I get:
>as path:-102 as string:-102

I have no idea what's going on here, so I think I will just change the
test to only care about the sign of the result, as in the attached
patch.
commit 84fc5b9d432788414e75df1f62bf8645db57f395
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Jan 24 12:53:45 2019 +0000

    Fix failing test due to inconsistent strcmp results
    
            * testsuite/27_io/filesystem/path/compare/strings.cc: Only compare
            sign of results.

diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
index 3f0aa4bde06..83487ae35b6 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
@@ -26,6 +26,8 @@
 
 using std::filesystem::path;
 
+int sign(int i) { return i > 0 ? 1 : i < 0 ? -1 : 0; }
+
 void
 test01()
 {
@@ -36,8 +38,8 @@ test01()
     path p(s);
     VERIFY( p.compare(s) == 0 );
     VERIFY( p.compare(s.c_str()) == 0 );
-    VERIFY( p.compare(p0) == p.compare(s0) );
-    VERIFY( p.compare(p0) == p.compare(s0.c_str()) );
+    VERIFY( sign(p.compare(p0)) == sign(p.compare(s0)) );
+    VERIFY( sign(p.compare(p0)) == sign(p.compare(s0.c_str())) );
   }
 }
diff mbox series

Patch

commit e83709b79c339f92fbcee748bbe755bf40825210
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Jan 6 17:45:40 2019 +0000

    PR libstdc++/86756 Move rest of std::filesystem to libstdc++.so
    
    Move std::filesystem directory iterators and operations from
    libstdc++fs.a to main libstdc++ library. These components have many
    dependencies on OS support, which is not available on all targets. Some
    additional autoconf checks and conditional compilation is needed to
    ensure the files will build for all targets. Previously this code was
    not compiled without --enable-libstdcxx-filesystem-ts but the C++17
    components should be available for all hosted builds.
    
    The tests for these components no longer need to link to libstdc++fs.a,
    but are not expected to pass on all targets. To avoid numerous failures
    on targets which are not expected to pass the tests (due to missing OS
    functionality) leave the dg-require-filesystem-ts directives in place
    for now. This will ensure the tests only run for builds where the
    filesystem-ts library is built, which presumably means some level of OS
    support is present.
    
            PR libstdc++/86756
            * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for utime and
            lstat and define _GLIBCXX_USE_UTIME and _GLIBCXX_USE_LSTAT.
            * config.h.in: Regenerate.
            * config/abi/pre/gnu.ver (GLIBCXX_3.4.26): Export symbols for
            remaining std::filesystem types and functions.
            * configure: Regenerate.
            * src/c++17/Makefile.am: Add C++17 filesystem sources.
            * src/c++17/Makefile.in: Regenerate.
            * src/c++17/cow-fs_dir.cc: Move src/filesystem/cow-std-dir.cc to
            here, and change name of included file.
            * src/c++17/cow-fs_ops.cc: Move src/filesystem/cow-std-ops.cc to
            here, and change name of included file.
            * src/c++17/fs_dir.cc: Move src/filesystem/std-dir.cc to here. Change
            path to dir-common.h.
            * src/c++17/fs_ops.cc: Move src/filesystem/std-ops.cc to here. Change
            path to ops-common.h. Disable -Wunused-parameter warnings.
            (internal_file_clock): Define unconditionally.
            [!_GLIBCXX_HAVE_SYS_STAT_H] (internal_file_clock::from_stat): Do not
            define.
            (do_copy_file, do_space): Move definitions to ops.common.h.
            (copy, file_size, hard_link_count, last_write_time, space): Only
            perform operation when _GLIBCXX_HAVE_SYS_STAT_H is defined, otherwise
            report an error.
            (last_write_time, read_symlink): Remove unused attributes from
            parameters.
            * src/filesystem/Makefile.am: Remove C++17 filesystem sources.
            * src/filesystem/Makefile.in: Regenerate.
            * src/filesystem/cow-std-dir.cc: Move to src/c++17/cow-fs_dir.cc.
            * src/filesystem/cow-std-ops.cc: Move to src/c++17/cow-fs_ops.cc.
            * src/filesystem/std-dir.cc: Move to src/c++17/fs_dir.cc.
            * src/filesystem/std-ops.cc: Move to src/c++17/fs_ops.cc.
            * src/filesystem/dir-common.h [!_GLIBCXX_HAVE_DIRENT_H]: Define
            dummy types and functions instead of using #error.
            * src/filesystem/dir.cc [!_GLIBCXX_HAVE_DIRENT_H]: Use #error.
            * src/filesystem/ops-common.h [!_GLIBCXX_USE_LSTAT] (lstat): Define
            in terms of stat.
            [!_GLIBCXX_HAVE_UNISTD_H]: Define dummy types and functions.
            (do_copy_file, do_space): Move definitions here from std-ops.cc.
            * src/filesystem/ops.cc: Adjust calls to do_copy_file and do_space
            to account for new namespace.
            * testsuite/27_io/filesystem/directory_entry/86597.cc: Remove
            -lstdc++fs from dg-options.
            * testsuite/27_io/filesystem/directory_entry/lwg3171.cc: Likewise.
            * testsuite/27_io/filesystem/file_status/1.cc: Likewise.
            * testsuite/27_io/filesystem/filesystem_error/cons.cc: Likewise.
            * testsuite/27_io/filesystem/filesystem_error/copy.cc: Likewise.
            * testsuite/27_io/filesystem/iterators/directory_iterator.cc:
            Likewise.
            * testsuite/27_io/filesystem/iterators/pop.cc: Likewise.
            * testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
            Likewise.
            * testsuite/27_io/filesystem/operations/absolute.cc: Likewise.
            * testsuite/27_io/filesystem/operations/canonical.cc: Likewise.
            * testsuite/27_io/filesystem/operations/copy.cc: Likewise.
            * testsuite/27_io/filesystem/operations/copy_file.cc: Likewise.
            * testsuite/27_io/filesystem/operations/create_directories.cc:
            Likewise.
            * testsuite/27_io/filesystem/operations/create_directory.cc: Likewise.
            * testsuite/27_io/filesystem/operations/create_symlink.cc: Likewise.
            * testsuite/27_io/filesystem/operations/current_path.cc: Likewise.
            * testsuite/27_io/filesystem/operations/equivalent.cc: Likewise.
            * testsuite/27_io/filesystem/operations/exists.cc: Likewise.
            * testsuite/27_io/filesystem/operations/file_size.cc: Likewise.
            * testsuite/27_io/filesystem/operations/is_empty.cc: Likewise.
            * testsuite/27_io/filesystem/operations/last_write_time.cc: Likewise.
            * testsuite/27_io/filesystem/operations/permissions.cc: Likewise.
            * testsuite/27_io/filesystem/operations/proximate.cc: Likewise.
            * testsuite/27_io/filesystem/operations/read_symlink.cc: Likewise.
            * testsuite/27_io/filesystem/operations/relative.cc: Likewise.
            * testsuite/27_io/filesystem/operations/remove.cc: Likewise.
            * testsuite/27_io/filesystem/operations/remove_all.cc: Likewise.
            * testsuite/27_io/filesystem/operations/space.cc: Likewise.
            * testsuite/27_io/filesystem/operations/status.cc: Likewise.
            * testsuite/27_io/filesystem/operations/symlink_status.cc: Likewise.
            * testsuite/27_io/filesystem/operations/temp_directory_path.cc:
            Likewise.
            * testsuite/27_io/filesystem/operations/weakly_canonical.cc: Likewise.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 6bcd29dc8c3..ce91e495fab 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4451,6 +4451,40 @@  dnl
       AC_DEFINE(_GLIBCXX_USE_UTIMENSAT, 1, [Define if utimensat and UTIME_OMIT are available in <sys/stat.h> and AT_FDCWD in <fcntl.h>.])
     fi
     AC_MSG_RESULT($glibcxx_cv_utimensat)
+dnl
+    AC_MSG_CHECKING([for utime])
+    AC_CACHE_VAL(glibcxx_cv_utime, [dnl
+      GCC_TRY_COMPILE_OR_LINK(
+        [
+          #include <utime.h>
+        ],
+        [
+          struct utimbuf t = { 1, 1 };
+          int i = utime("path", &t);
+        ],
+        [glibcxx_cv_utime=yes],
+        [glibcxx_cv_utime=no])
+    ])
+    if test $glibcxx_cv_utime = yes; then
+      AC_DEFINE(_GLIBCXX_USE_UTIME, 1, [Define if utime is available in <utime.h>.])
+    fi
+    AC_MSG_RESULT($glibcxx_cv_utime)
+dnl
+    AC_MSG_CHECKING([for lstat])
+    AC_CACHE_VAL(glibcxx_cv_lstat, [dnl
+      GCC_TRY_COMPILE_OR_LINK(
+        [ #include <sys/stat.h> ],
+        [
+          struct stat st;
+          int i = lstat("path", &st);
+        ],
+        [glibcxx_cv_lstat=yes],
+        [glibcxx_cv_lstat=no])
+    ])
+    if test $glibcxx_cv_lstat = yes; then
+      AC_DEFINE(_GLIBCXX_USE_LSTAT, 1, [Define if lstat is available in <sys/stat.h>.])
+    fi
+    AC_MSG_RESULT($glibcxx_cv_lstat)
 dnl
     AC_MSG_CHECKING([for struct stat.st_mtim.tv_nsec])
     AC_CACHE_VAL(glibcxx_cv_st_mtim, [dnl
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index f83d2b1cca9..20325bf7a33 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2167,6 +2167,58 @@  GLIBCXX_3.4.26 {
     _ZNSt10filesystem7__cxx114pathpLERKS1_;
     _ZT[IV]NSt10filesystem7__cxx1116filesystem_errorE;
 
+    _ZNSt10filesystem10equivalent*;
+    _ZNSt10filesystem10remove_all*;
+    _ZNSt10filesystem11permissions*;
+    _ZNSt10filesystem12current_path*;
+    _ZNSt10filesystem12read_symlink*;
+    _ZNSt10filesystem14create_symlink*;
+    _ZNSt10filesystem14symlink_status*;
+    _ZNSt10filesystem15last_write_time*;
+    _ZNSt10filesystem16create_directory*;
+    _ZNSt10filesystem16create_hard_link*;
+    _ZNSt10filesystem16weakly_canonical*;
+    _ZNSt10filesystem18create_directories*;
+    _ZNSt10filesystem19temp_directory_path*;
+    _ZNSt10filesystem24create_directory_symlink*;
+    _ZNSt10filesystem4copy*;
+    _ZNSt10filesystem5space*;
+    _ZNSt10filesystem6remove*;
+    _ZNSt10filesystem6status*;
+    _ZNSt10filesystem8absolute*;
+    _ZNSt10filesystem8is_empty*;
+    _ZNSt10filesystem8relative*;
+    _ZNSt10filesystem9canonical*;
+    _ZNSt10filesystem9copy_file*;
+    _ZNSt10filesystem9file_size*;
+    _ZNSt10filesystem9proximate*;
+
+    _ZNKSt10filesystem18directory_iteratordeEv;
+    _ZNKSt10filesystem28recursive_directory_iterator5depthEv;
+    _ZNKSt10filesystem28recursive_directory_iteratordeEv;
+    _ZNSt10filesystem18directory_iteratorC[12]ERKNS_4pathENS_17directory_optionsEPSt10error_code;
+    _ZNSt10filesystem18directory_iteratorppEv;
+    _ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code;
+    _ZNSt10filesystem28recursive_directory_iterator3popEv;
+    _ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code;
+    _ZNSt10filesystem28recursive_directory_iteratorC[12]ERKNS_4pathENS_17directory_optionsEPSt10error_code;
+    _ZNSt10filesystem28recursive_directory_iteratorD[12]Ev;
+    _ZNSt10filesystem28recursive_directory_iteratoraSEOS0_;
+    _ZNSt10filesystem28recursive_directory_iteratorppEv;
+
+    _ZNKSt10filesystem7__cxx1118directory_iteratordeEv;
+    _ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv;
+    _ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv;
+    _ZNSt10filesystem7__cxx1118directory_iteratorC[12]ERKNS0_4pathENS_17directory_optionsEPSt10error_code;
+    _ZNSt10filesystem7__cxx1118directory_iteratorppEv;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iteratorC[12]ERKNS0_4pathENS_17directory_optionsEPSt10error_code;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iteratorD[12]Ev;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_;
+    _ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv;
+
 } GLIBCXX_3.4.25;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/src/c++17/Makefile.am b/libstdc++-v3/src/c++17/Makefile.am
index 85883c33f2d..4200f7f8259 100644
--- a/libstdc++-v3/src/c++17/Makefile.am
+++ b/libstdc++-v3/src/c++17/Makefile.am
@@ -29,7 +29,10 @@  headers =
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = cow-string-inst.cc
-extra_fs_sources = cow-fs_path.cc
+extra_fs_sources = \
+	cow-fs_dir.cc \
+	cow-fs_ops.cc \
+	cow-fs_path.cc
 else
 extra_string_inst_sources =
 extra_fs_sources =
@@ -45,6 +48,8 @@  inst_sources =
 endif
 
 sources = \
+	fs_dir.cc \
+	fs_ops.cc \
 	fs_path.cc \
 	memory_resource.cc \
 	string-inst.cc \
diff --git a/libstdc++-v3/src/filesystem/cow-std-dir.cc b/libstdc++-v3/src/c++17/cow-fs_dir.cc
similarity index 98%
rename from libstdc++-v3/src/filesystem/cow-std-dir.cc
rename to libstdc++-v3/src/c++17/cow-fs_dir.cc
+++ b/libstdc++-v3/src/c++17/cow-fs_dir.cc
@@ -23,4 +23,4 @@ 
 // <http://www.gnu.org/licenses/>.
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "std-dir.cc"
+#include "fs_dir.cc"
diff --git a/libstdc++-v3/src/filesystem/cow-std-ops.cc b/libstdc++-v3/src/c++17/cow-fs_ops.cc
similarity index 98%
rename from libstdc++-v3/src/filesystem/cow-std-ops.cc
rename to libstdc++-v3/src/c++17/cow-fs_ops.cc
+++ b/libstdc++-v3/src/c++17/cow-fs_ops.cc
@@ -23,4 +23,4 @@ 
 // <http://www.gnu.org/licenses/>.
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "std-ops.cc"
+#include "fs_ops.cc"
diff --git a/libstdc++-v3/src/filesystem/std-dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
similarity index 99%
rename from libstdc++-v3/src/filesystem/std-dir.cc
rename to libstdc++-v3/src/c++17/fs_dir.cc
+++ b/libstdc++-v3/src/c++17/fs_dir.cc
@@ -27,14 +27,13 @@ 
 #endif
 
 #include <filesystem>
-#include <experimental/filesystem>
 #include <utility>
 #include <stack>
 #include <string.h>
 #include <errno.h>
 #define _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM namespace filesystem {
 #define _GLIBCXX_END_NAMESPACE_FILESYSTEM }
-#include "dir-common.h"
+#include "../filesystem/dir-common.h"
 
 namespace fs = std::filesystem;
 namespace posix = std::filesystem::__gnu_posix;
diff --git a/libstdc++-v3/src/filesystem/std-ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
similarity index 84%
rename from libstdc++-v3/src/filesystem/std-ops.cc
rename to libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -29,11 +29,9 @@ 
 #endif
 
 #include <filesystem>
-#include <experimental/filesystem>
 #include <functional>
 #include <ostream>
 #include <stack>
-#include <ext/stdio_filebuf.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
@@ -47,9 +45,6 @@ 
 #ifdef _GLIBCXX_HAVE_SYS_STATVFS_H
 # include <sys/statvfs.h> // statvfs
 #endif
-#ifdef _GLIBCXX_USE_SENDFILE
-# include <sys/sendfile.h> // sendfile
-#endif
 #if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
 # include <utime.h> // utime
 #endif
@@ -59,7 +54,9 @@ 
 
 #define _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM namespace filesystem {
 #define _GLIBCXX_END_NAMESPACE_FILESYSTEM }
-#include "ops-common.h"
+#include "../filesystem/ops-common.h"
+
+#pragma GCC diagnostic ignored "-Wunused-parameter"
 
 namespace fs = std::filesystem;
 namespace posix = std::filesystem::__gnu_posix;
@@ -274,8 +271,6 @@  namespace std::filesystem
   }
 }
 
-#ifdef _GLIBCXX_HAVE_SYS_STAT_H
-
 namespace
 {
   struct internal_file_clock : fs::__file_clock
@@ -283,6 +278,7 @@  namespace
     using __file_clock::_S_to_sys;
     using __file_clock::_S_from_sys;
 
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
     static fs::file_time_type
     from_stat(const fs::stat_type& st, std::error_code& ec) noexcept
     {
@@ -291,209 +287,15 @@  namespace
 	return fs::file_time_type::min();
       return _S_from_sys(sys_time);
     }
+#endif
   };
 }
 
-#ifdef NEED_DO_COPY_FILE
-bool
-fs::do_copy_file(const path::value_type* from, const path::value_type* to,
-		 copy_options_existing_file options,
-		 stat_type* from_st, stat_type* to_st,
-		 std::error_code& ec) noexcept
-{
-  stat_type st1, st2;
-  fs::file_status t, f;
-
-  if (to_st == nullptr)
-    {
-      if (posix::stat(to, &st1))
-	{
-	  const int err = errno;
-	  if (!is_not_found_errno(err))
-	    {
-	      ec.assign(err, std::generic_category());
-	      return false;
-	    }
-	}
-      else
-	to_st = &st1;
-    }
-  else if (to_st == from_st)
-    to_st = nullptr;
-
-  if (to_st == nullptr)
-    t = fs::file_status{fs::file_type::not_found};
-  else
-    t = make_file_status(*to_st);
-
-  if (from_st == nullptr)
-    {
-      if (posix::stat(from, &st2))
-	{
-	  ec.assign(errno, std::generic_category());
-	  return false;
-	}
-      else
-	from_st = &st2;
-    }
-  f = make_file_status(*from_st);
-  // _GLIBCXX_RESOLVE_LIB_DEFECTS
-  // 2712. copy_file() has a number of unspecified error conditions
-  if (!is_regular_file(f))
-    {
-      ec = std::make_error_code(std::errc::not_supported);
-      return false;
-    }
-
-  if (exists(t))
-    {
-      if (!is_regular_file(t))
-	{
-	  ec = std::make_error_code(std::errc::not_supported);
-	  return false;
-	}
-
-      if (to_st->st_dev == from_st->st_dev
-	  && to_st->st_ino == from_st->st_ino)
-	{
-	  ec = std::make_error_code(std::errc::file_exists);
-	  return false;
-	}
-
-      if (options.skip)
-	{
-	  ec.clear();
-	  return false;
-	}
-      else if (options.update)
-	{
-	  const auto from_mtime = internal_file_clock::from_stat(*from_st, ec);
-	  if (ec)
-	    return false;
-	  if ((from_mtime <= internal_file_clock::from_stat(*to_st, ec)) || ec)
-	    return false;
-	}
-      else if (!options.overwrite)
-	{
-	  ec = std::make_error_code(std::errc::file_exists);
-	  return false;
-	}
-      else if (!is_regular_file(t))
-	{
-	  ec = std::make_error_code(std::errc::not_supported);
-	  return false;
-	}
-    }
-
-  struct CloseFD {
-    ~CloseFD() { if (fd != -1) posix::close(fd); }
-    bool close() { return posix::close(std::exchange(fd, -1)) == 0; }
-    int fd;
-  };
-
-  CloseFD in = { posix::open(from, O_RDONLY) };
-  if (in.fd == -1)
-    {
-      ec.assign(errno, std::generic_category());
-      return false;
-    }
-  int oflag = O_WRONLY|O_CREAT;
-  if (options.overwrite || options.update)
-    oflag |= O_TRUNC;
-  else
-    oflag |= O_EXCL;
-  CloseFD out = { posix::open(to, oflag, S_IWUSR) };
-  if (out.fd == -1)
-    {
-      if (errno == EEXIST && options.skip)
-	ec.clear();
-      else
-	ec.assign(errno, std::generic_category());
-      return false;
-    }
-
-#if defined _GLIBCXX_USE_FCHMOD && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  if (::fchmod(out.fd, from_st->st_mode))
-#elif defined _GLIBCXX_USE_FCHMODAT && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  if (::fchmodat(AT_FDCWD, to, from_st->st_mode, 0))
-#else
-  if (posix::chmod(to, from_st->st_mode))
-#endif
-    {
-      ec.assign(errno, std::generic_category());
-      return false;
-    }
-
-  size_t count = from_st->st_size;
-#if defined _GLIBCXX_USE_SENDFILE && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  off_t offset = 0;
-  ssize_t n = ::sendfile(out.fd, in.fd, &offset, count);
-  if (n < 0 && errno != ENOSYS && errno != EINVAL)
-    {
-      ec.assign(errno, std::generic_category());
-      return false;
-    }
-  if ((size_t)n == count)
-    {
-      if (!out.close() || !in.close())
-	{
-	  ec.assign(errno, std::generic_category());
-	  return false;
-	}
-      ec.clear();
-      return true;
-    }
-  else if (n > 0)
-    count -= n;
-#endif // _GLIBCXX_USE_SENDFILE
-
-  using std::ios;
-  __gnu_cxx::stdio_filebuf<char> sbin(in.fd, ios::in|ios::binary);
-  __gnu_cxx::stdio_filebuf<char> sbout(out.fd, ios::out|ios::binary);
-
-  if (sbin.is_open())
-    in.fd = -1;
-  if (sbout.is_open())
-    out.fd = -1;
-
-#ifdef _GLIBCXX_USE_SENDFILE
-  if (n != 0)
-    {
-      if (n < 0)
-	n = 0;
-
-      const auto p1 = sbin.pubseekoff(n, ios::beg, ios::in);
-      const auto p2 = sbout.pubseekoff(n, ios::beg, ios::out);
-
-      const std::streampos errpos(std::streamoff(-1));
-      if (p1 == errpos || p2 == errpos)
-	{
-	  ec = std::make_error_code(std::errc::io_error);
-	  return false;
-	}
-    }
-#endif
-
-  if (count && !(std::ostream(&sbout) << &sbin))
-    {
-      ec = std::make_error_code(std::errc::io_error);
-      return false;
-    }
-  if (!sbout.close() || !sbin.close())
-    {
-      ec.assign(errno, std::generic_category());
-      return false;
-    }
-  ec.clear();
-  return true;
-}
-#endif // NEED_DO_COPY_FILE
-#endif // _GLIBCXX_HAVE_SYS_STAT_H
-
 void
 fs::copy(const path& from, const path& to, copy_options options,
 	 error_code& ec)
 {
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
   const bool skip_symlinks = is_set(options, copy_options::skip_symlinks);
   const bool create_symlinks = is_set(options, copy_options::create_symlinks);
   const bool copy_symlinks = is_set(options, copy_options::copy_symlinks);
@@ -591,6 +393,9 @@  fs::copy(const path& from, const path& to, copy_options options,
   // 2683. filesystem::copy() says "no effects"
   else
     ec.clear();
+#else
+  ec = std::make_error_code(std::errc::not_supported);
+#endif
 }
 
 bool
@@ -1068,6 +873,7 @@  namespace
 std::uintmax_t
 fs::file_size(const path& p, error_code& ec) noexcept
 {
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
   struct S
   {
     S(const stat_type& st) : type(make_file_type(st)), size(st.st_size) { }
@@ -1085,6 +891,9 @@  fs::file_size(const path& p, error_code& ec) noexcept
       else
 	ec = std::make_error_code(std::errc::not_supported);
     }
+#else
+  ec = std::make_error_code(std::errc::not_supported);
+#endif
   return -1;
 }
 
@@ -1101,8 +910,13 @@  fs::hard_link_count(const path& p)
 std::uintmax_t
 fs::hard_link_count(const path& p, error_code& ec) noexcept
 {
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
   return do_stat(p, ec, std::mem_fn(&stat_type::st_nlink),
 		 static_cast<uintmax_t>(-1));
+#else
+  ec = std::make_error_code(std::errc::not_supported);
+  return static_cast<uintmax_t>(-1);
+#endif
 }
 
 bool
@@ -1141,11 +955,16 @@  fs::last_write_time(const path& p)
 fs::file_time_type
 fs::last_write_time(const path& p, error_code& ec) noexcept
 {
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
   return do_stat(p, ec,
 		 [&ec](const auto& st) {
 		     return internal_file_clock::from_stat(st, ec);
 		 },
 		 file_time_type::min());
+#else
+  ec = std::make_error_code(std::errc::not_supported);
+  return file_time_type::min();
+#endif
 }
 
 void
@@ -1158,7 +977,7 @@  fs::last_write_time(const path& p, file_time_type new_time)
 }
 
 void
-fs::last_write_time(const path& p __attribute__((__unused__)),
+fs::last_write_time(const path& p,
 		    file_time_type new_time, error_code& ec) noexcept
 {
   auto d = internal_file_clock::_S_to_sys(new_time).time_since_epoch();
@@ -1179,7 +998,7 @@  fs::last_write_time(const path& p __attribute__((__unused__)),
     ec.assign(errno, std::generic_category());
   else
     ec.clear();
-#elif _GLIBCXX_HAVE_UTIME_H
+#elif _GLIBCXX_USE_UTIME && _GLIBCXX_HAVE_SYS_STAT_H
   posix::utimbuf times;
   times.modtime = s.count();
   times.actime = do_stat(p, ec, [](const auto& st) { return st.st_atime; },
@@ -1279,7 +1098,7 @@  fs::read_symlink(const path& p)
   return tgt;
 }
 
-fs::path fs::read_symlink(const path& p [[gnu::unused]], error_code& ec)
+fs::path fs::read_symlink(const path& p, error_code& ec)
 {
   path result;
 #if defined(_GLIBCXX_HAVE_READLINK) && defined(_GLIBCXX_HAVE_SYS_STAT_H)
@@ -1472,51 +1291,6 @@  fs::space(const path& p)
   return s;
 }
 
-#ifdef NEED_DO_SPACE
-void
-fs::do_space(const __gnu_posix::char_type* pathname,
-	 uintmax_t& capacity, uintmax_t& free, uintmax_t& available,
-	 std::error_code& ec)
-{
-#ifdef _GLIBCXX_HAVE_SYS_STATVFS_H
-  struct ::statvfs f;
-  if (::statvfs(pathname, &f))
-      ec.assign(errno, std::generic_category());
-  else
-    {
-      if (f.f_frsize != (unsigned long)-1)
-	{
-	  const uintmax_t fragment_size = f.f_frsize;
-	  const fsblkcnt_t unknown = -1;
-	  if (f.f_blocks != unknown)
-	    capacity = f.f_blocks * fragment_size;
-	  if (f.f_bfree != unknown)
-	    free = f.f_bfree * fragment_size;
-	  if (f.f_bavail != unknown)
-	    available = f.f_bavail * fragment_size;
-	}
-      ec.clear();
-    }
-#elif _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  ULARGE_INTEGER bytes_avail = {}, bytes_total = {}, bytes_free = {};
-  if (GetDiskFreeSpaceExW(pathname, &bytes_avail, &bytes_total, &bytes_free))
-    {
-      if (bytes_total.QuadPart != 0)
-	capacity = bytes_total.QuadPart;
-      if (bytes_free.QuadPart != 0)
-	free = bytes_free.QuadPart;
-      if (bytes_avail.QuadPart != 0)
-	available = bytes_avail.QuadPart;
-      ec.clear();
-    }
-  else
-    ec.assign((int)GetLastError(), std::system_category());
-#else
-  ec = std::make_error_code(std::errc::not_supported);
-#endif
-}
-#endif // NEED_DO_SPACE
-
 fs::space_info
 fs::space(const path& p, error_code& ec) noexcept
 {
@@ -1525,6 +1299,7 @@  fs::space(const path& p, error_code& ec) noexcept
     static_cast<uintmax_t>(-1),
     static_cast<uintmax_t>(-1)
   };
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
 #if _GLIBCXX_FILESYSTEM_IS_WINDOWS
   path dir = absolute(p);
   dir.remove_filename();
@@ -1532,7 +1307,10 @@  fs::space(const path& p, error_code& ec) noexcept
 #else
   auto str = p.c_str();
 #endif
+
   do_space(str, info.capacity, info.free, info.available, ec);
+#endif // _GLIBCXX_HAVE_SYS_STAT_H
+
   return info;
 }
 
diff --git a/libstdc++-v3/src/filesystem/Makefile.am b/libstdc++-v3/src/filesystem/Makefile.am
index 6f2a9f63b8a..af9dcd25f8e 100644
--- a/libstdc++-v3/src/filesystem/Makefile.am
+++ b/libstdc++-v3/src/filesystem/Makefile.am
@@ -30,9 +30,7 @@  if ENABLE_DUAL_ABI
 cxx11_abi_sources = \
 	cow-dir.cc \
 	cow-ops.cc \
-	cow-path.cc \
-	cow-std-dir.cc \
-	cow-std-ops.cc
+	cow-path.cc
 else
 cxx11_abi_sources =
 endif
@@ -41,8 +39,6 @@  sources = \
 	dir.cc \
 	ops.cc \
 	path.cc \
-	std-dir.cc \
-	std-ops.cc \
 	${cxx11_abi_sources}
 
 # vpath % $(top_srcdir)/src/filesystem
diff --git a/libstdc++-v3/src/filesystem/dir-common.h b/libstdc++-v3/src/filesystem/dir-common.h
index bcfbfcd0bea..6ec798c9aa0 100644
--- a/libstdc++-v3/src/filesystem/dir-common.h
+++ b/libstdc++-v3/src/filesystem/dir-common.h
@@ -26,6 +26,7 @@ 
 #define _GLIBCXX_DIR_COMMON_H 1
 
 #include <string.h>  // strcmp
+#include <errno.h>
 #if _GLIBCXX_FILESYSTEM_IS_WINDOWS
 #include <wchar.h>  // wcscmp
 #endif
@@ -34,8 +35,6 @@ 
 #  include <sys/types.h>
 # endif
 # include <dirent.h>
-#else
-# error "the <dirent.h> header is needed to build the Filesystem TS"
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -53,13 +52,20 @@  using dirent = _wdirent;
 inline DIR* opendir(const wchar_t* path) { return ::_wopendir(path); }
 inline dirent* readdir(DIR* dir) { return ::_wreaddir(dir); }
 inline int closedir(DIR* dir) { return ::_wclosedir(dir); }
-#else
+#elif defined _GLIBCXX_HAVE_DIRENT_H
 using char_type = char;
 using DIR = ::DIR;
 typedef struct ::dirent dirent;
 using ::opendir;
 using ::readdir;
 using ::closedir;
+#else
+using char_type = char;
+struct dirent { const char* d_name; };
+struct DIR { };
+inline DIR* opendir(const char*) { return nullptr; }
+inline dirent* readdir(DIR*) { return nullptr; }
+inline int closedir(DIR*) { return -1; }
 #endif
 } // namespace __gnu_posix
 
diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc
index 0738ea784f7..3e6e598fa64 100644
--- a/libstdc++-v3/src/filesystem/dir.cc
+++ b/libstdc++-v3/src/filesystem/dir.cc
@@ -27,6 +27,11 @@ 
 #endif
 
 #include <experimental/filesystem>
+
+#ifndef _GLIBCXX_HAVE_DIRENT_H
+# error "the <dirent.h> header is needed to build the Filesystem TS"
+#endif
+
 #include <utility>
 #include <stack>
 #include <string.h>
diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h
index 1c0d650f444..f20867c217e 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -42,6 +42,14 @@ 
 # include <wchar.h>
 #endif
 
+#ifdef NEED_DO_COPY_FILE
+# include <filesystem>
+# include <ext/stdio_filebuf.h>
+# ifdef _GLIBCXX_USE_SENDFILE
+#  include <sys/sendfile.h> // sendfile
+# endif
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -108,26 +116,42 @@  namespace __gnu_posix
     return ret;
   }
   using char_type = wchar_t;
-#else // _GLIBCXX_FILESYSTEM_IS_WINDOWS
+#elif defined _GLIBCXX_HAVE_UNISTD_H
   using ::open;
   using ::close;
-#ifdef _GLIBCXX_HAVE_SYS_STAT_H
+# ifdef _GLIBCXX_HAVE_SYS_STAT_H
   typedef struct ::stat stat_type;
   using ::stat;
+#  ifdef _GLIBCXX_USE_LSTAT
   using ::lstat;
-#endif
+#  else
+  inline int lstat(const char* path, stat_type* buffer)
+  { return stat(path, buffer); }
+#  endif
+# endif
   using ::mode_t;
   using ::chmod;
   using ::mkdir;
   using ::getcwd;
   using ::chdir;
-#if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
+# if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_USE_UTIME
   using ::utimbuf;
   using ::utime;
-#endif
+# endif
   using ::rename;
   using ::truncate;
   using char_type = char;
+#else // ! _GLIBCXX_FILESYSTEM_IS_WINDOWS && ! _GLIBCXX_HAVE_UNISTD_H
+  inline int open(const char*, int, ...) { errno = ENOTSUP; return -1; }
+  inline int close(int) { errno = ENOTSUP; return -1; }
+  using mode_t = int;
+  inline int chmod(const char*, mode_t) { errno = ENOTSUP; return -1; }
+  inline int mkdir(const char*, mode_t) { errno = ENOTSUP; return -1; }
+  inline char* getcwd(char*, size_t) { errno = ENOTSUP; return nullptr; }
+  inline int chdir(const char*) { errno = ENOTSUP; return -1; }
+  inline int rename(const char*, const char*) { errno = ENOTSUP; return -1; }
+  inline int truncate(const char*, long) { errno = ENOTSUP; return -1; }
+  using char_type = char;
 #endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
 } // namespace __gnu_posix
 
@@ -190,18 +214,6 @@  namespace __gnu_posix
     bool skip, update, overwrite;
   };
 
-  bool
-  do_copy_file(const __gnu_posix::char_type* from,
-	       const __gnu_posix::char_type* to,
-	       copy_options_existing_file options,
-	       stat_type* from_st, stat_type* to_st,
-	       std::error_code& ec) noexcept;
-
-  void
-  do_space(const __gnu_posix::char_type* pathname,
-	   uintmax_t& capacity, uintmax_t& free, uintmax_t& available,
-	   std::error_code&);
-
 #endif // _GLIBCXX_HAVE_SYS_STAT_H
 
 } // namespace filesystem
@@ -211,6 +223,19 @@  _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
 
 #ifdef _GLIBCXX_HAVE_SYS_STAT_H
   using std::filesystem::__gnu_posix::stat_type;
+  using std::filesystem::__gnu_posix::char_type;
+
+  bool
+  do_copy_file(const char_type* from, const char_type* to,
+	       std::filesystem::copy_options_existing_file options,
+	       stat_type* from_st, stat_type* to_st,
+	       std::error_code& ec) noexcept;
+
+  void
+  do_space(const char_type* pathname,
+	   uintmax_t& capacity, uintmax_t& free, uintmax_t& available,
+	   std::error_code&);
+
 
   inline file_type
   make_file_type(const stat_type& st) noexcept
@@ -257,6 +282,253 @@  _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
 	is_set(opt, copy_options::overwrite_existing)
     };
   }
+
+#ifdef NEED_DO_COPY_FILE
+  bool
+  do_copy_file(const char_type* from, const char_type* to,
+	       std::filesystem::copy_options_existing_file options,
+	       stat_type* from_st, stat_type* to_st,
+	       std::error_code& ec) noexcept
+  {
+    namespace fs = std::filesystem;
+    namespace posix = fs::__gnu_posix;
+
+    stat_type st1, st2;
+    file_status t, f;
+
+    if (to_st == nullptr)
+      {
+	if (posix::stat(to, &st1))
+	  {
+	    const int err = errno;
+	    if (!fs::is_not_found_errno(err))
+	      {
+		ec.assign(err, std::generic_category());
+		return false;
+	      }
+	  }
+	else
+	  to_st = &st1;
+      }
+    else if (to_st == from_st)
+      to_st = nullptr;
+
+    if (to_st == nullptr)
+      t = file_status{file_type::not_found};
+    else
+      t = make_file_status(*to_st);
+
+    if (from_st == nullptr)
+      {
+	if (posix::stat(from, &st2))
+	  {
+	    ec.assign(errno, std::generic_category());
+	    return false;
+	  }
+	else
+	  from_st = &st2;
+      }
+    f = make_file_status(*from_st);
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 2712. copy_file() has a number of unspecified error conditions
+    if (!is_regular_file(f))
+      {
+	ec = std::make_error_code(std::errc::not_supported);
+	return false;
+      }
+
+    if (exists(t))
+      {
+	if (!is_regular_file(t))
+	  {
+	    ec = std::make_error_code(std::errc::not_supported);
+	    return false;
+	  }
+
+	if (to_st->st_dev == from_st->st_dev
+	    && to_st->st_ino == from_st->st_ino)
+	  {
+	    ec = std::make_error_code(std::errc::file_exists);
+	    return false;
+	  }
+
+	if (options.skip)
+	  {
+	    ec.clear();
+	    return false;
+	  }
+	else if (options.update)
+	  {
+	    const auto from_mtime = fs::file_time(*from_st, ec);
+	    if (ec)
+	      return false;
+	    if ((from_mtime <= fs::file_time(*to_st, ec)) || ec)
+	      return false;
+	  }
+	else if (!options.overwrite)
+	  {
+	    ec = std::make_error_code(std::errc::file_exists);
+	    return false;
+	  }
+	else if (!is_regular_file(t))
+	  {
+	    ec = std::make_error_code(std::errc::not_supported);
+	    return false;
+	  }
+      }
+
+    struct CloseFD {
+      ~CloseFD() { if (fd != -1) posix::close(fd); }
+      bool close() { return posix::close(std::exchange(fd, -1)) == 0; }
+      int fd;
+    };
+
+    CloseFD in = { posix::open(from, O_RDONLY) };
+    if (in.fd == -1)
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+    int oflag = O_WRONLY|O_CREAT;
+    if (options.overwrite || options.update)
+      oflag |= O_TRUNC;
+    else
+      oflag |= O_EXCL;
+    CloseFD out = { posix::open(to, oflag, S_IWUSR) };
+    if (out.fd == -1)
+      {
+	if (errno == EEXIST && options.skip)
+	  ec.clear();
+	else
+	  ec.assign(errno, std::generic_category());
+	return false;
+      }
+
+#if defined _GLIBCXX_USE_FCHMOD && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    if (::fchmod(out.fd, from_st->st_mode))
+#elif defined _GLIBCXX_USE_FCHMODAT && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    if (::fchmodat(AT_FDCWD, to, from_st->st_mode, 0))
+#else
+    if (posix::chmod(to, from_st->st_mode))
+#endif
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+
+    size_t count = from_st->st_size;
+#if defined _GLIBCXX_USE_SENDFILE && ! defined _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    off_t offset = 0;
+    ssize_t n = ::sendfile(out.fd, in.fd, &offset, count);
+    if (n < 0 && errno != ENOSYS && errno != EINVAL)
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+    if ((size_t)n == count)
+      {
+	if (!out.close() || !in.close())
+	  {
+	    ec.assign(errno, std::generic_category());
+	    return false;
+	  }
+	ec.clear();
+	return true;
+      }
+    else if (n > 0)
+      count -= n;
+#endif // _GLIBCXX_USE_SENDFILE
+
+    using std::ios;
+    __gnu_cxx::stdio_filebuf<char> sbin(in.fd, ios::in|ios::binary);
+    __gnu_cxx::stdio_filebuf<char> sbout(out.fd, ios::out|ios::binary);
+
+    if (sbin.is_open())
+      in.fd = -1;
+    if (sbout.is_open())
+      out.fd = -1;
+
+#ifdef _GLIBCXX_USE_SENDFILE
+    if (n != 0)
+      {
+	if (n < 0)
+	  n = 0;
+
+	const auto p1 = sbin.pubseekoff(n, ios::beg, ios::in);
+	const auto p2 = sbout.pubseekoff(n, ios::beg, ios::out);
+
+	const std::streampos errpos(std::streamoff(-1));
+	if (p1 == errpos || p2 == errpos)
+	  {
+	    ec = std::make_error_code(std::errc::io_error);
+	    return false;
+	  }
+      }
+#endif
+
+    if (count && !(std::ostream(&sbout) << &sbin))
+      {
+	ec = std::make_error_code(std::errc::io_error);
+	return false;
+      }
+    if (!sbout.close() || !sbin.close())
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+    ec.clear();
+    return true;
+  }
+#endif // NEED_DO_COPY_FILE
+
+#ifdef NEED_DO_SPACE
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+  void
+  do_space(const char_type* pathname,
+	   uintmax_t& capacity, uintmax_t& free, uintmax_t& available,
+	   std::error_code& ec)
+  {
+#ifdef _GLIBCXX_HAVE_SYS_STATVFS_H
+    struct ::statvfs f;
+    if (::statvfs(pathname, &f))
+	ec.assign(errno, std::generic_category());
+    else
+      {
+	if (f.f_frsize != (unsigned long)-1)
+	  {
+	    const uintmax_t fragment_size = f.f_frsize;
+	    const fsblkcnt_t unknown = -1;
+	    if (f.f_blocks != unknown)
+	      capacity = f.f_blocks * fragment_size;
+	    if (f.f_bfree != unknown)
+	      free = f.f_bfree * fragment_size;
+	    if (f.f_bavail != unknown)
+	      available = f.f_bavail * fragment_size;
+	  }
+	ec.clear();
+      }
+#elif _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    ULARGE_INTEGER bytes_avail = {}, bytes_total = {}, bytes_free = {};
+    if (GetDiskFreeSpaceExW(pathname, &bytes_avail, &bytes_total, &bytes_free))
+      {
+	if (bytes_total.QuadPart != 0)
+	  capacity = bytes_total.QuadPart;
+	if (bytes_free.QuadPart != 0)
+	  free = bytes_free.QuadPart;
+	if (bytes_avail.QuadPart != 0)
+	  available = bytes_avail.QuadPart;
+	ec.clear();
+      }
+    else
+      ec.assign((int)GetLastError(), std::system_category());
+#else
+    ec = std::make_error_code(std::errc::not_supported);
+#endif
+  }
+#pragma GCC diagnostic pop
+#endif // NEED_DO_SPACE
+
 #endif // _GLIBCXX_HAVE_SYS_STAT_H
 
 _GLIBCXX_END_NAMESPACE_FILESYSTEM
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 95bf23b5b52..369604da80f 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -24,6 +24,8 @@ 
 
 #ifndef _GLIBCXX_USE_CXX11_ABI
 # define _GLIBCXX_USE_CXX11_ABI 1
+# define NEED_DO_COPY_FILE
+# define NEED_DO_SPACE
 #endif
 
 #include <experimental/filesystem>
@@ -243,7 +245,6 @@  namespace
 
   using std::filesystem::is_not_found_errno;
   using std::filesystem::file_time;
-  using std::filesystem::do_copy_file;
 #endif // _GLIBCXX_HAVE_SYS_STAT_H
 
 } // namespace
@@ -1175,7 +1176,7 @@  fs::space(const path& p, error_code& ec) noexcept
 #else
   auto str = p.c_str();
 #endif
-  std::filesystem::do_space(str, info.capacity, info.free, info.available, ec);
+  fs::do_space(str, info.capacity, info.free, info.available, ec);
   return info;
 }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/86597.cc b/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/86597.cc
index 10202f5be3e..67c70abf4a1 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/86597.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/86597.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/lwg3171.cc b/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/lwg3171.cc
index 95158c63ca8..b688d69085e 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/lwg3171.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/directory_entry/lwg3171.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/file_status/1.cc b/libstdc++-v3/testsuite/27_io/filesystem/file_status/1.cc
index 030a1d273f3..0bda10d28e2 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/file_status/1.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/file_status/1.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
index cd40397c346..8b24541cbc6 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/copy.cc b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/copy.cc
index 71eac38e0d3..926f164f5fa 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/copy.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/copy.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/iterators/directory_iterator.cc b/libstdc++-v3/testsuite/27_io/filesystem/iterators/directory_iterator.cc
index 71ecd21ab40..ddb424b4be0 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/iterators/directory_iterator.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/iterators/directory_iterator.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/iterators/pop.cc b/libstdc++-v3/testsuite/27_io/filesystem/iterators/pop.cc
index fab7ac0f896..b092dee91e0 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/iterators/pop.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/iterators/pop.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc
index ca4899d058c..bf67bfd215b 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
index 496f3f8d4fb..45f66ac96c5 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
@@ -1,4 +1,4 @@ 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/canonical.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/canonical.cc
index 9f511c51a9d..8051a4bfb7a 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/canonical.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/canonical.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
index 2fba1fba2d1..7234e34831f 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
@@ -1,4 +1,4 @@ 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file.cc
index 85e97c634d3..dfad8541bfe 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directories.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directories.cc
index 007c5cd55fc..d248676b82d 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directories.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directories.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directory.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directory.cc
index e196c57e799..da78fb2de87 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directory.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_directory.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_symlink.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_symlink.cc
index 55a103f8936..4236f20f62d 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/create_symlink.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/create_symlink.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/current_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/current_path.cc
index b5a6c638476..c62ada9f111 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/current_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/current_path.cc
@@ -1,4 +1,4 @@ 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc
index f371cdb0afe..ca1d691bc7c 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/equivalent.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/exists.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/exists.cc
index 330ec542ce8..df8251e55c2 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/exists.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/exists.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/file_size.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/file_size.cc
index bb11653cae2..57c9e96e4dc 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/file_size.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/file_size.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/is_empty.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/is_empty.cc
index e4e4c3e3bc7..c572a834576 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/is_empty.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/is_empty.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/last_write_time.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/last_write_time.cc
index 49822e166b1..7a693a1ddcb 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/last_write_time.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/last_write_time.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/permissions.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/permissions.cc
index 669b04903f1..23d5817acad 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/permissions.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/permissions.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/proximate.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/proximate.cc
index 09358250628..8a7e258628a 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/proximate.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/proximate.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/read_symlink.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/read_symlink.cc
index f04932fcc0f..038c0447a04 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/read_symlink.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/read_symlink.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 // { dg-xfail-if "symlinks not supported" { *-*-mingw* } }
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/relative.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/relative.cc
index c7521d13262..e013faaaf68 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/relative.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/relative.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc
index 066bd2bad0e..afe9580fa33 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc
index 255a6b1b9ff..2f2802ff859 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/space.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/space.cc
index 4070e7bdb92..e545e5e8f70 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/space.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/space.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/status.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/status.cc
index 8a526db7cab..b5ab1b5fd5e 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/status.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/status.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/symlink_status.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/symlink_status.cc
index 66125743001..6f01419da3e 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/symlink_status.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/symlink_status.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 // { dg-xfail-if "symlinks not supported" { *-*-mingw* } }
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/temp_directory_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/temp_directory_path.cc
index 8f03b9dc324..b3ae66d7d64 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/temp_directory_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/temp_directory_path.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/weakly_canonical.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/weakly_canonical.cc
index ef6a8b563ea..e7f1a4ca782 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/weakly_canonical.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/weakly_canonical.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 // { dg-require-filesystem-ts "" }