Skip to content

Commit 0957656

Browse files
authored
[runtimes][GTest] LLVM-independent unittests (llvm#164794)
The LLVM-customized GTest has a dependency on LLVM to support `llvm::raw_ostream` and hence has to link to LLVMSupport. The runtimes use the LLVMSupport from the bootstrapping LLVM build. The problem is that the boostrapping compiler and the runtimes target can diverge in their ABI, even in the runtimes default build. For instance, Clang is built using gcc which uses libstdc++, but the runtimes is built by Clang which can be configured to use libcxx by default. Altough it does not use gcc, this issue has caused [flang-aarch64-libcxx](https://lab.llvm.org/buildbot/#/builders/89)) to break, and is still (again?) broken. This patch makes the runtimes' GTest independent from LLVMSupport so we do not link any runtimes component with LLVM components. Runtime projects that use GTest unittests: * flang-rt * libc * compiler-rt: Adds `gtest-all.cpp` with [GTEST_NO_LLVM_SUPPORT=1](https://github.com/llvm/llvm-project/blob/f801b6f67ea896d6e4d2de38bce9a79689ceb254/compiler-rt/CMakeLists.txt#L723) to each unittest without using `llvm_gtest`. Not touched by this PR. * openmp: Handled by llvm#159416. Not touched for now by this PR to avoid conflict. The current state of this PR tries to reuse https://github.com/llvm/llvm-project/blob/main/third-party/unittest/CMakeLists.txt as much as possible, altough personally I would prefer to make it use "modern CMake" style. third-party/unittest/CMakeLists.txt will detect whether it is used in runtimes build and adjaust accordingly. It creates a different target for LLVM (`llvm_gtest`, NFCI) and another one for the runtimes (`runtimes_gtest`). It is not possible to reuse `llvm_gtest` for both since `llvm_gtest` is imported using `find_package(LLVM)` if configured using LLVM_INSTALL_GTEST. An alias `default_gtest` is used to select between the two. `default_gtest` could also be used for openmp which also supports standalone and [LLVM_ENABLE_PROJECTS](llvm#152189) build mode.
1 parent a276624 commit 0957656

File tree

12 files changed

+109
-84
lines changed

12 files changed

+109
-84
lines changed

flang-rt/unittests/CMakeLists.txt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,8 @@ if (CMAKE_CROSSCOMPILING)
2222
return ()
2323
endif ()
2424

25-
if (NOT TARGET llvm_gtest)
26-
message(WARNING "Flang-RT unittests disabled due to GTest being unavailable; "
27-
"Try LLVM_INSTALL_GTEST=ON for the LLVM build")
28-
return ()
29-
endif ()
30-
25+
# Make the targets default_gtest and default_gtest_main available.
26+
build_gtest()
3127

3228
add_dependencies(flang-rt-test-depends
3329
FlangRTUnitTests

flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "flang-rt/runtime/descriptor.h"
1010
#include "flang/Common/ISO_Fortran_binding_wrapper.h"
1111
#include "flang/Testing/testing.h"
12-
#include "llvm/Support/raw_ostream.h"
1312
#include <type_traits>
1413

1514
using namespace Fortran::runtime;
@@ -73,26 +72,9 @@ static void AddNoiseToCdesc(CFI_cdesc_t *dv, CFI_rank_t rank) {
7372
}
7473
}
7574

76-
#ifdef VERBOSE
77-
static void DumpTestWorld(const void *bAddr, CFI_attribute_t attr,
78-
CFI_type_t ty, std::size_t eLen, CFI_rank_t rank,
79-
const CFI_index_t *eAddr) {
80-
llvm::outs() << " base_addr: ";
81-
llvm::outs().write_hex(reinterpret_cast<std::intptr_t>(bAddr))
82-
<< " attribute: " << static_cast<int>(attr)
83-
<< " type: " << static_cast<int>(ty) << " elem_len: " << eLen
84-
<< " rank: " << static_cast<int>(rank) << " extent: ";
85-
llvm::outs().write_hex(reinterpret_cast<std::intptr_t>(eAddr)) << '\n';
86-
llvm::outs().flush();
87-
}
88-
#endif
89-
9075
static void check_CFI_establish(CFI_cdesc_t *dv, void *base_addr,
9176
CFI_attribute_t attribute, CFI_type_t type, std::size_t elem_len,
9277
CFI_rank_t rank, const CFI_index_t extents[]) {
93-
#ifdef VERBOSE
94-
DumpTestWorld(base_addr, attribute, type, elem_len, rank, extent);
95-
#endif
9678
// CFI_establish reqs from F2018 section 18.5.5
9779
int retCode{
9880
CFI_establish(dv, base_addr, attribute, type, elem_len, rank, extents)};
@@ -305,9 +287,6 @@ static void check_CFI_allocate(CFI_cdesc_t *dv,
305287
const CFI_type_t type{dv->type};
306288
const void *base_addr{dv->base_addr};
307289
const int version{dv->version};
308-
#ifdef VERBOSE
309-
DumpTestWorld(base_addr, attribute, type, elem_len, rank, nullptr);
310-
#endif
311290
int retCode{CFI_allocate(dv, lower_bounds, upper_bounds, elem_len)};
312291
Descriptor *desc = reinterpret_cast<Descriptor *>(dv);
313292
if (retCode == CFI_SUCCESS) {

flang-rt/unittests/Runtime/AccessTest.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include "CrashHandlerFixture.h"
1313
#include "gtest/gtest.h"
1414
#include "flang/Runtime/extensions.h"
15-
#include "llvm/ADT/Twine.h"
1615

16+
#include <cstring>
1717
#include <fcntl.h>
1818
#include <sys/stat.h>
1919
#include <sys/types.h>
@@ -82,8 +82,9 @@ static const char *temp_directory_path() {
8282

8383
static std::string createTemporaryFile(
8484
const char *name, const AccessType &accessType) {
85-
std::string path =
86-
(llvm::Twine{temp_directory_path()} + "/" + addPIDSuffix(name)).str();
85+
std::ostringstream pathS;
86+
pathS << temp_directory_path() << "/" << addPIDSuffix(name);
87+
std::string path = pathS.str();
8788

8889
// O_CREAT | O_EXCL enforces that this file is newly created by this call.
8990
// This feels risky. If we don't have permission to create files in the

flang-rt/unittests/Runtime/CrashHandlerFixture.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
char buffer[1000];
1818
std::vsnprintf(buffer, sizeof buffer, message, ap);
1919
va_end(ap);
20-
llvm::errs()
21-
<< "Test "
22-
<< ::testing::UnitTest::GetInstance()->current_test_info()->name()
23-
<< " crashed in file "
24-
<< (sourceFile ? sourceFile : "unknown source file") << '(' << sourceLine
25-
<< "): " << buffer << '\n';
20+
std::cerr << "Test "
21+
<< ::testing::UnitTest::GetInstance()->current_test_info()->name()
22+
<< " crashed in file "
23+
<< (sourceFile ? sourceFile : "unknown source file") << '('
24+
<< sourceLine << "): " << buffer << '\n';
2625
std::exit(EXIT_FAILURE);
2726
}
2827

flang-rt/unittests/Runtime/Descriptor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ TEST(Descriptor, FixedStride) {
3232
extent[0] = 8;
3333
descriptor.Establish(integer, four, data, 1, extent);
3434
ASSERT_EQ(descriptor.rank(), 1);
35-
ASSERT_EQ(descriptor.Elements(), 8);
36-
ASSERT_EQ(descriptor.ElementBytes(), four);
35+
ASSERT_EQ(descriptor.Elements(), 8u);
36+
ASSERT_EQ(descriptor.ElementBytes(), static_cast<unsigned>(four));
3737
ASSERT_EQ(descriptor.GetDimension(0).LowerBound(), 0);
3838
ASSERT_EQ(descriptor.GetDimension(0).ByteStride(), four);
3939
ASSERT_EQ(descriptor.GetDimension(0).Extent(), 8);

flang-rt/unittests/Runtime/ExternalIOTest.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "flang/Runtime/io-api.h"
1717
#include "flang/Runtime/main.h"
1818
#include "flang/Runtime/stop.h"
19-
#include "llvm/Support/raw_ostream.h"
2019
#include <cstring>
2120
#include <string_view>
2221

libc/benchmarks/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ set(LLVM_LINK_COMPONENTS
1919
# Add Unit Testing Support
2020
#==============================================================================
2121

22+
make_gtest_target()
23+
2224
function(add_libc_benchmark_unittest target_name)
2325
if(NOT LLVM_INCLUDE_TESTS)
2426
return()
@@ -38,8 +40,8 @@ function(add_libc_benchmark_unittest target_name)
3840
)
3941
target_link_libraries(${target_name}
4042
PRIVATE
41-
llvm_gtest_main
42-
llvm_gtest
43+
default_gtest_main
44+
default_gtest
4345
${LIBC_BENCHMARKS_UNITTEST_DEPENDS}
4446
)
4547
llvm_update_compile_flags(${target_name})

llvm/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,9 +1340,7 @@ if( LLVM_INCLUDE_UTILS )
13401340
add_subdirectory(utils/mlgo-utils)
13411341
add_subdirectory(utils/llvm-test-mustache-spec)
13421342
if( LLVM_INCLUDE_TESTS )
1343-
set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test")
13441343
add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest)
1345-
set(LLVM_SUBPROJECT_TITLE)
13461344
endif()
13471345
else()
13481346
if ( LLVM_INCLUDE_TESTS )

llvm/cmake/modules/AddLLVM.cmake

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,13 @@ function(add_unittest test_suite test_name)
18021802
# libpthreads overrides some standard library symbols, so main
18031803
# executable must be linked with it in order to provide consistent
18041804
# API for all shared libaries loaded by this executable.
1805-
target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB})
1805+
# default_gtest should be an alias to either llvm_gtest or runtimes_gtest.
1806+
# If it is not defined, fall back to llvm_gtest.
1807+
if(TARGET default_gtest)
1808+
target_link_libraries(${test_name} PRIVATE default_gtest_main default_gtest ${LLVM_PTHREAD_LIB})
1809+
else ()
1810+
target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB})
1811+
endif ()
18061812

18071813
add_dependencies(${test_suite} ${test_name})
18081814
endfunction()

runtimes/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,20 @@ endif()
256256
# This can be used to detect whether we're in the runtimes build.
257257
set(LLVM_RUNTIMES_BUILD ON)
258258

259+
# Make GTest available to all runtimes
260+
# The runtime must call make_gtest_target() for it to become available. This is
261+
# to avoid build failures when gtest is not actually needed. In particular,
262+
# mingw-incomplete-sysroot is missing C++ header files that GTest needs to
263+
# compile.
264+
function(build_gtest)
265+
if(TARGET default_gtest)
266+
# Already available
267+
return()
268+
endif()
269+
270+
add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/runtimes_gtest")
271+
endfunction()
272+
259273
foreach(entry ${runtimes})
260274
get_filename_component(projName ${entry} NAME)
261275

0 commit comments

Comments
 (0)