[libc++][libc++abi] Add tests for vendor-specific properties
authorLouis Dionne <ldionne.2@gmail.com>
Tue, 28 Sep 2021 19:54:41 +0000 (15:54 -0400)
committerLouis Dionne <ldionne.2@gmail.com>
Wed, 29 Sep 2021 21:22:37 +0000 (17:22 -0400)
Vendors take libc++ and ship it in various ways. Some vendors might
ship it differently from what upstream LLVM does, i.e. the install
location might be different, some ABI properties might differ, etc.

In the past few years, I've come across several instances where
having a place to test some of these properties would have been
incredibly useful. I also just got bitten by the lack of tests
of that kind, so I'm adding some now.

The tests added by this commit for Apple platforms have numerous
TODOs that capture discrepancies between the upstream LLVM CMake
and the slightly-modified build we perform internally to produce
Apple's system libc++. In the future, the goal would be to upstream
all those differences so that it's possible to build a faithful
Apple system libc++ with the upstream LLVM sources only.

But this isn't only useful for Apple - this lays out the path for
any vendor being able to add their own checks (either upstream or
downstream) to libc++.

Differential Revision: https://reviews.llvm.org/D110736

23 files changed:
libcxx/cmake/caches/Apple.cmake
libcxx/test/configs/legacy.cfg.in
libcxx/test/configs/libcxx-trunk-shared.cfg.in
libcxx/test/configs/libcxx-trunk-static.cfg.in
libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp [new file with mode: 0644]
libcxx/test/std/strings/c.strings/cuchar.pass.cpp
libcxx/test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp
libcxx/test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bm/default.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bm/hash.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bm/hash.pred.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bm/pred.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/default.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/hash.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/hash.pred.pass.cpp
libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/pred.pass.cpp
libcxx/utils/libcxx/test/config.py
libcxx/utils/libcxx/test/params.py
libcxxabi/test/lit.site.cfg.in
libcxxabi/test/vendor/apple/system-install-properties.sh.cpp [new file with mode: 0644]

index c884eb5..6f4030e 100644 (file)
@@ -18,3 +18,6 @@ set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
 
 set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "")
 set(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST ON CACHE BOOL "")
+
+set(LIBCXX_TEST_PARAMS "stdlib=apple-libc++" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
index 23aa505..a131978 100644 (file)
@@ -8,6 +8,7 @@ import site
 config.cxx_headers              = "@LIBCXX_GENERATED_INCLUDE_DIR@"
 config.cxx_under_test           = "@CMAKE_CXX_COMPILER@"
 config.project_obj_root         = "@CMAKE_BINARY_DIR@"
+config.install_root             = "@CMAKE_BINARY_DIR@"
 config.libcxx_src_root          = "@LIBCXX_SOURCE_DIR@"
 config.libcxx_obj_root          = "@LIBCXX_BINARY_DIR@"
 config.cxx_library_root         = "@LIBCXX_LIBRARY_DIR@"
index 3711d5d..1cc51bd 100644 (file)
@@ -49,6 +49,7 @@ config.substitutions.append(('%{exec}',
         pipes.quote(sys.executable),
         pipes.quote(runPy))
 ))
+config.substitutions.append(('%{install}', INSTALL_ROOT))
 
 # Add parameters and features to the config
 libcxx.test.newconfig.configure(
index 07f5890..6aeeb32 100644 (file)
@@ -49,6 +49,7 @@ config.substitutions.append(('%{exec}',
         pipes.quote(sys.executable),
         pipes.quote(runPy))
 ))
+config.substitutions.append(('%{install}', INSTALL_ROOT))
 
 # Add parameters and features to the config
 libcxx.test.newconfig.configure(
diff --git a/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp b/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp
new file mode 100644 (file)
index 0000000..ff14dda
--- /dev/null
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: stdlib=apple-libc++
+
+// This file checks various properties of the installation of libc++ when built as
+// a system library on Apple platforms.
+//
+// TODO: We should install to `<prefix>/usr` in CMake and check that path instead.
+
+// Make sure we install the libc++ headers in the right location.
+//
+// RUN: stat "%{install}/include/c++/v1/__config"
+
+// Make sure we install libc++.1.dylib in the right location.
+//
+// RUN: stat "%{install}/lib/libc++.1.dylib"
+
+// Make sure we install a symlink from libc++.dylib to libc++.1.dylib.
+//
+// RUN: stat "%{install}/lib/libc++.dylib"
+// RUN: readlink "%{install}/lib/libc++.dylib" | grep "libc++.1.dylib"
+
+// Make sure the install_name is /usr/lib.
+//
+// In particular, make sure we don't use any @rpath in the load commands. When building as
+// a system library, it is important to hardcode the installation paths in the dylib, because
+// various tools like dyld and ld64 will treat us specially if they recognize us as being a
+// system library.
+//
+// TODO: We currently don't do that correctly in the CMake build.
+//
+// XRUNX: otool -L "%{install}/lib/libc++.1.dylib" | grep '/usr/lib/libc++.1.dylib'
+// XRUNX: ! otool -l "%{install}/lib/libc++.1.dylib" | grep -E "LC_RPATH|@loader_path|@rpath"
+
+// Make sure the compatibility_version of libc++ is 1.0.0.
+// Failure to respect this can result in applications not being able to find libc++
+// when they are loaded by dyld, if the compatibility version was bumped.
+//
+// RUN: otool -L "%{install}/lib/libc++.1.dylib" | grep "libc++.1.dylib" | grep "compatibility version 1.0.0"
index b63df56..d0f6142 100644 (file)
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // Skip this test on windows. If built on top of the MSVC runtime, the
 // <cuchar> header actually does exist (although not provided by us).
index d771317..5d7b645 100644 (file)
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: !stdlib=libc++ && c++11
-// UNSUPPORTED: !stdlib=libc++ && c++14
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++11
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++14
 // <charconv>
 
 // In
index 0c10c0d..350b1bf 100644 (file)
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: !stdlib=libc++ && c++11
-// UNSUPPORTED: !stdlib=libc++ && c++14
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++11
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++14
 
 // <charconv>
 
index 6aa4953..a57a709 100644 (file)
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: !stdlib=libc++ && c++11
-// UNSUPPORTED: !stdlib=libc++ && c++14
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++11
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++14
 
 // The roundtrip test uses to_chars, which requires functions in the dylib
 // that were introduced in Mac OS 10.15.
index 096d979..81ce986 100644 (file)
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: !stdlib=libc++ && c++11
-// UNSUPPORTED: !stdlib=libc++ && c++14
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++11
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++14
 // <charconv>
 
 // In
index d137461..fab0c96 100644 (file)
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: !stdlib=libc++ && c++11
-// UNSUPPORTED: !stdlib=libc++ && c++14
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++11
+// UNSUPPORTED: !stdlib={{.+}}-libc++ && c++14
 
 // to_chars requires functions in the dylib that were introduced in Mac OS 10.15.
 //
index 8bcd525..9d6bc50 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 3ff0f0d..170a2ba 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index e4e72be..1a0e27b 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index f6f8851..6ca2962 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 828d6fc..266ceb8 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 904623f..237211e 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 5370088..22d40b6 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 137d1a6..acc2295 100644 (file)
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// XFAIL: stdlib=libc++
+// XFAIL: stdlib={{.+}}-libc++
 
 // <functional>
 
index 3cd0db4..77827df 100644 (file)
@@ -467,6 +467,7 @@ class Configuration(object):
         sub.append(('%{flags}',         ' '.join(map(self.quote, flags))))
         sub.append(('%{compile_flags}', ' '.join(map(self.quote, compile_flags))))
         sub.append(('%{link_flags}',    ' '.join(map(self.quote, self.cxx.link_flags))))
+        sub.append(('%{install}',       self.quote(self.config.install_root)))
 
         codesign_ident = self.get_lit_conf('llvm_codesign_identity', '')
         env_vars = ' '.join('%s=%s' % (k, self.quote(v)) for (k, v) in self.exec_env.items())
index 090e058..ec80b9a 100644 (file)
@@ -91,8 +91,21 @@ DEFAULT_PARAMETERS = [
               AddCompileFlag('-fno-rtti')
             ]),
 
-  Parameter(name='stdlib', choices=['libc++', 'libstdc++', 'msvc'], type=str, default='libc++',
-            help="The C++ Standard Library implementation being tested.",
+  Parameter(name='stdlib', choices=['llvm-libc++', 'apple-libc++', 'libstdc++', 'msvc'], type=str, default='llvm-libc++',
+            help="""The C++ Standard Library implementation being tested.
+
+                 Note that this parameter can also be used to encode different 'flavors' of the same
+                 standard library, such as libc++ as shipped by a different vendor, if it has different
+                 properties worth testing.
+
+                 The Standard libraries currently supported are:
+                 - llvm-libc++: The 'upstream' libc++ as shipped with LLVM.
+                 - apple-libc++: libc++ as shipped by Apple. This is basically like the LLVM one, but
+                                 there are a few differences like installation paths and the use of
+                                 universal dylibs.
+                 - libstdc++: The GNU C++ library typically shipped with GCC.
+                 - msvc: The Microsoft implementation of the C++ Standard Library.
+                """,
             actions=lambda stdlib: [
               AddFeature('stdlib={}'.format(stdlib))
             ]),
index 049f822..585e03e 100644 (file)
@@ -7,6 +7,7 @@ import site
 
 config.cxx_under_test           = "@CMAKE_CXX_COMPILER@"
 config.project_obj_root         = "@CMAKE_BINARY_DIR@"
+config.install_root             = "@CMAKE_BINARY_DIR@"
 config.libcxxabi_hdr_root       = "@LIBCXXABI_HEADER_DIR@"
 config.libcxxabi_src_root       = "@LIBCXXABI_SOURCE_DIR@"
 config.libcxxabi_obj_root       = "@LIBCXXABI_BINARY_DIR@"
diff --git a/libcxxabi/test/vendor/apple/system-install-properties.sh.cpp b/libcxxabi/test/vendor/apple/system-install-properties.sh.cpp
new file mode 100644 (file)
index 0000000..791fc67
--- /dev/null
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: stdlib=apple-libc++
+
+// This file checks various properties of the installation of libc++abi when built
+// as a system library on Apple platforms.
+//
+// TODO: We should install to `<prefix>/usr` in CMake and check that path instead.
+
+// Make sure we install the libc++abi headers in the right location.
+// TODO: We don't currently install them, but we should.
+//
+// XRUNX: stat "%{install}/include/cxxabi.h"
+
+// Make sure we install libc++abi.dylib in the right location.
+//
+// RUN: stat "%{install}/lib/libc++abi.dylib"
+
+// Make sure we don't install a symlink from libc++abi.dylib to libc++abi.1.dylib,
+// unlike what we do for libc++.dylib.
+// TODO: We currently don't do that correctly in the CMake build.
+//
+// XRUNX: ! readlink "%{install}/lib/libc++abi.dylib"
+// XRUNX: ! stat "%{install}/lib/libc++abi.1.dylib"
+
+// Make sure the install_name is /usr/lib.
+//
+// In particular, make sure we don't use any @rpath in the load commands. When building as
+// a system library, it is important to hardcode the installation paths in the dylib, because
+// various tools like dyld and ld64 will treat us specially if they recognize us as being a
+// system library.
+//
+// TODO: We currently don't do that correctly in the CMake build.
+//
+// XRUNX: otool -L "%{install}/lib/libc++abi.dylib" | grep '/usr/lib/libc++abi.dylib'
+// XRUNX: ! otool -l "%{install}/lib/libc++abi.dylib" | grep -E "LC_RPATH|@loader_path|@rpath"
+
+// Make sure the compatibility_version of libc++abi is 1.0.0. Failure to respect this can result
+// in applications not being able to find libc++abi when they are loaded by dyld, if the
+// compatibility version was bumped.
+//
+// RUN: otool -L "%{install}/lib/libc++abi.dylib" | grep "libc++abi.1.dylib" | grep "compatibility version 1.0.0"