Skip to content

Commit

Permalink
[libc++][libc++abi] Add tests for vendor-specific properties
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ldionne committed Sep 29, 2021
1 parent af10d6f commit 9892d16
Show file tree
Hide file tree
Showing 23 changed files with 135 additions and 21 deletions.
3 changes: 3 additions & 0 deletions libcxx/cmake/caches/Apple.cmake
Expand Up @@ -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 "")
1 change: 1 addition & 0 deletions libcxx/test/configs/legacy.cfg.in
Expand Up @@ -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@"
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/configs/libcxx-trunk-shared.cfg.in
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/configs/libcxx-trunk-static.cfg.in
Expand Up @@ -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(
Expand Down
45 changes: 45 additions & 0 deletions libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp
@@ -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"
2 changes: 1 addition & 1 deletion libcxx/test/std/strings/c.strings/cuchar.pass.cpp
Expand Up @@ -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).
Expand Down
Expand Up @@ -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
Expand Down
Expand Up @@ -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>

Expand Down
Expand Up @@ -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.
Expand Down
Expand Up @@ -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
Expand Down
Expand Up @@ -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.
//
Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: stdlib=libc++
// XFAIL: stdlib={{.+}}-libc++

// <functional>

Expand Down
1 change: 1 addition & 0 deletions libcxx/utils/libcxx/test/config.py
Expand Up @@ -467,6 +467,7 @@ def configure_substitutions(self):
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())
Expand Down
17 changes: 15 additions & 2 deletions libcxx/utils/libcxx/test/params.py
Expand Up @@ -91,8 +91,21 @@ def getStdFlag(cfg, std):
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))
]),
Expand Down
1 change: 1 addition & 0 deletions libcxxabi/test/lit.site.cfg.in
Expand Up @@ -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@"
Expand Down
48 changes: 48 additions & 0 deletions libcxxabi/test/vendor/apple/system-install-properties.sh.cpp
@@ -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"

0 comments on commit 9892d16

Please sign in to comment.