diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt index 53cd54dfd215e..e1ab73d7d9301 100644 --- a/flang-rt/unittests/CMakeLists.txt +++ b/flang-rt/unittests/CMakeLists.txt @@ -22,12 +22,8 @@ if (CMAKE_CROSSCOMPILING) return () endif () -if (NOT TARGET llvm_gtest) - message(WARNING "Flang-RT unittests disabled due to GTest being unavailable; " - "Try LLVM_INSTALL_GTEST=ON for the LLVM build") - return () -endif () - +# Make the targets default_gtest and default_gtest_main available. +build_gtest() add_dependencies(flang-rt-test-depends FlangRTUnitTests diff --git a/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp b/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp index 8c0a6f29b6967..1a9817cc665de 100644 --- a/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp +++ b/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp @@ -9,7 +9,6 @@ #include "flang-rt/runtime/descriptor.h" #include "flang/Common/ISO_Fortran_binding_wrapper.h" #include "flang/Testing/testing.h" -#include "llvm/Support/raw_ostream.h" #include using namespace Fortran::runtime; @@ -73,26 +72,9 @@ static void AddNoiseToCdesc(CFI_cdesc_t *dv, CFI_rank_t rank) { } } -#ifdef VERBOSE -static void DumpTestWorld(const void *bAddr, CFI_attribute_t attr, - CFI_type_t ty, std::size_t eLen, CFI_rank_t rank, - const CFI_index_t *eAddr) { - llvm::outs() << " base_addr: "; - llvm::outs().write_hex(reinterpret_cast(bAddr)) - << " attribute: " << static_cast(attr) - << " type: " << static_cast(ty) << " elem_len: " << eLen - << " rank: " << static_cast(rank) << " extent: "; - llvm::outs().write_hex(reinterpret_cast(eAddr)) << '\n'; - llvm::outs().flush(); -} -#endif - static void check_CFI_establish(CFI_cdesc_t *dv, void *base_addr, CFI_attribute_t attribute, CFI_type_t type, std::size_t elem_len, CFI_rank_t rank, const CFI_index_t extents[]) { -#ifdef VERBOSE - DumpTestWorld(base_addr, attribute, type, elem_len, rank, extent); -#endif // CFI_establish reqs from F2018 section 18.5.5 int retCode{ CFI_establish(dv, base_addr, attribute, type, elem_len, rank, extents)}; @@ -305,9 +287,6 @@ static void check_CFI_allocate(CFI_cdesc_t *dv, const CFI_type_t type{dv->type}; const void *base_addr{dv->base_addr}; const int version{dv->version}; -#ifdef VERBOSE - DumpTestWorld(base_addr, attribute, type, elem_len, rank, nullptr); -#endif int retCode{CFI_allocate(dv, lower_bounds, upper_bounds, elem_len)}; Descriptor *desc = reinterpret_cast(dv); if (retCode == CFI_SUCCESS) { diff --git a/flang-rt/unittests/Runtime/AccessTest.cpp b/flang-rt/unittests/Runtime/AccessTest.cpp index d431d0d19bd61..d44f0ec3ced23 100644 --- a/flang-rt/unittests/Runtime/AccessTest.cpp +++ b/flang-rt/unittests/Runtime/AccessTest.cpp @@ -12,8 +12,8 @@ #include "CrashHandlerFixture.h" #include "gtest/gtest.h" #include "flang/Runtime/extensions.h" -#include "llvm/ADT/Twine.h" +#include #include #include #include @@ -82,8 +82,9 @@ static const char *temp_directory_path() { static std::string createTemporaryFile( const char *name, const AccessType &accessType) { - std::string path = - (llvm::Twine{temp_directory_path()} + "/" + addPIDSuffix(name)).str(); + std::ostringstream pathS; + pathS << temp_directory_path() << "/" << addPIDSuffix(name); + std::string path = pathS.str(); // O_CREAT | O_EXCL enforces that this file is newly created by this call. // This feels risky. If we don't have permission to create files in the diff --git a/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp b/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp index 8213edd1f9225..34901b5cd2139 100644 --- a/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp +++ b/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp @@ -17,12 +17,11 @@ char buffer[1000]; std::vsnprintf(buffer, sizeof buffer, message, ap); va_end(ap); - llvm::errs() - << "Test " - << ::testing::UnitTest::GetInstance()->current_test_info()->name() - << " crashed in file " - << (sourceFile ? sourceFile : "unknown source file") << '(' << sourceLine - << "): " << buffer << '\n'; + std::cerr << "Test " + << ::testing::UnitTest::GetInstance()->current_test_info()->name() + << " crashed in file " + << (sourceFile ? sourceFile : "unknown source file") << '(' + << sourceLine << "): " << buffer << '\n'; std::exit(EXIT_FAILURE); } diff --git a/flang-rt/unittests/Runtime/Descriptor.cpp b/flang-rt/unittests/Runtime/Descriptor.cpp index 3a4a7670fc62e..4a7bb43a492af 100644 --- a/flang-rt/unittests/Runtime/Descriptor.cpp +++ b/flang-rt/unittests/Runtime/Descriptor.cpp @@ -32,8 +32,8 @@ TEST(Descriptor, FixedStride) { extent[0] = 8; descriptor.Establish(integer, four, data, 1, extent); ASSERT_EQ(descriptor.rank(), 1); - ASSERT_EQ(descriptor.Elements(), 8); - ASSERT_EQ(descriptor.ElementBytes(), four); + ASSERT_EQ(descriptor.Elements(), 8u); + ASSERT_EQ(descriptor.ElementBytes(), static_cast(four)); ASSERT_EQ(descriptor.GetDimension(0).LowerBound(), 0); ASSERT_EQ(descriptor.GetDimension(0).ByteStride(), four); ASSERT_EQ(descriptor.GetDimension(0).Extent(), 8); diff --git a/flang-rt/unittests/Runtime/ExternalIOTest.cpp b/flang-rt/unittests/Runtime/ExternalIOTest.cpp index 6c148b1de6f82..6421194f45141 100644 --- a/flang-rt/unittests/Runtime/ExternalIOTest.cpp +++ b/flang-rt/unittests/Runtime/ExternalIOTest.cpp @@ -16,7 +16,6 @@ #include "flang/Runtime/io-api.h" #include "flang/Runtime/main.h" #include "flang/Runtime/stop.h" -#include "llvm/Support/raw_ostream.h" #include #include diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt index 60f522d7d8c65..c17cc106f96d7 100644 --- a/libc/benchmarks/CMakeLists.txt +++ b/libc/benchmarks/CMakeLists.txt @@ -19,6 +19,8 @@ set(LLVM_LINK_COMPONENTS # Add Unit Testing Support #============================================================================== +make_gtest_target() + function(add_libc_benchmark_unittest target_name) if(NOT LLVM_INCLUDE_TESTS) return() @@ -38,8 +40,8 @@ function(add_libc_benchmark_unittest target_name) ) target_link_libraries(${target_name} PRIVATE - llvm_gtest_main - llvm_gtest + default_gtest_main + default_gtest ${LIBC_BENCHMARKS_UNITTEST_DEPENDS} ) llvm_update_compile_flags(${target_name}) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index f192cd05b5a34..c02c75f10b12f 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -1340,9 +1340,7 @@ if( LLVM_INCLUDE_UTILS ) add_subdirectory(utils/mlgo-utils) add_subdirectory(utils/llvm-test-mustache-spec) if( LLVM_INCLUDE_TESTS ) - set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest) - set(LLVM_SUBPROJECT_TITLE) endif() else() if ( LLVM_INCLUDE_TESTS ) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 7d40d309d538e..3c3695a77cb7b 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1802,7 +1802,13 @@ function(add_unittest test_suite test_name) # libpthreads overrides some standard library symbols, so main # executable must be linked with it in order to provide consistent # API for all shared libaries loaded by this executable. - target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB}) + # default_gtest should be an alias to either llvm_gtest or runtimes_gtest. + # If it is not defined, fall back to llvm_gtest. + if(TARGET default_gtest) + target_link_libraries(${test_name} PRIVATE default_gtest_main default_gtest ${LLVM_PTHREAD_LIB}) + else () + target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB}) + endif () add_dependencies(${test_suite} ${test_name}) endfunction() diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index cc756da426e62..b17bd8f665361 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -256,6 +256,20 @@ endif() # This can be used to detect whether we're in the runtimes build. set(LLVM_RUNTIMES_BUILD ON) +# Make GTest available to all runtimes +# The runtime must call make_gtest_target() for it to become available. This is +# to avoid build failures when gtest is not actually needed. In particular, +# mingw-incomplete-sysroot is missing C++ header files that GTest needs to +# compile. +function(build_gtest) + if(TARGET default_gtest) + # Already available + return() + endif() + + add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/runtimes_gtest") +endfunction() + foreach(entry ${runtimes}) get_filename_component(projName ${entry} NAME) diff --git a/third-party/unittest/CMakeLists.txt b/third-party/unittest/CMakeLists.txt index 3fa885a16ea1e..79535a1de4616 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -11,6 +11,34 @@ # # Project-wide settings +set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") + +if(LLVM_RUNTIMES_BUILD) + # This instance of GTest is use for unittests for the runtime libraries. It + # must not link to LLVMSupport (used for llvm::raw_ostream and llvm::cl + # support) of the host build: It may be a different architecture and/or + # using a different C++ ABI such as libcxx/libstdc++. + set(GTEST_LLVM_COMPONENTS "") + + # We cannot use llvm_gtest for the target; it would clash with + # find_package(LLVM) with LLVM_EXPORT_GTEST=ON. Instead, we define an alias + # default_gtest that points to llvm_gtest in the LLVM build and + # runtimes_gtest in an runtimes build. + set(gtest_name "runtimes_gtest") + + # Override locally; never install the runtimes-GTest. + set(LLVM_INSTALL_GTEST OFF) + + # Build the library containing main() so unittests need less boilerplate. + # UnitTestMain/TestMain.cpp always needs LLVMSupport, use GTest's original + # main when unavailable. + set(gtest_main_src googletest/src/gtest_main.cc) +else() + set(GTEST_LLVM_COMPONENTS "Support") + set(gtest_name "llvm_gtest") + set(gtest_main_src UnitTestMain/TestMain.cpp) +endif() + if(WIN32) add_definitions(-DGTEST_OS_WINDOWS=1) endif() @@ -38,17 +66,13 @@ if (HAVE_LIBPTHREAD) list(APPEND LIBS pthread) endif() -# Make available for runtimes using the LLVM buildtree -# (required for unittests in bootstrapping builds) -set(EXCLUDE_FROM_ALL OFF) - # Install GTest only if requested. set(BUILDTREE_ONLY BUILDTREE_ONLY) if (LLVM_INSTALL_GTEST) set(BUILDTREE_ONLY "") endif () -add_llvm_library(llvm_gtest +add_llvm_library("${gtest_name}" googletest/src/gtest-all.cc googlemock/src/gmock-all.cc @@ -56,7 +80,7 @@ add_llvm_library(llvm_gtest ${LIBS} LINK_COMPONENTS - Support # Depends on llvm::raw_ostream + ${GTEST_LLVM_COMPONENTS} # This is a library meant only for the build tree. ${BUILDTREE_ONLY} @@ -67,15 +91,14 @@ add_llvm_library(llvm_gtest # that warning here for any targets that link to gtest. if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG) add_definitions("-Wno-suggest-override") - set_target_properties(llvm_gtest PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override") + set_target_properties("${gtest_name}" PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override") endif() if (NOT LLVM_ENABLE_THREADS) - target_compile_definitions(llvm_gtest PUBLIC GTEST_HAS_PTHREAD=0) + target_compile_definitions("${gtest_name}" PUBLIC GTEST_HAS_PTHREAD=0) endif () -# Top-level include directory required for "llvm/Support/raw_os_ostream.h" -target_include_directories(llvm_gtest +target_include_directories("${gtest_name}" PUBLIC $ $ $ @@ -84,21 +107,36 @@ target_include_directories(llvm_gtest PRIVATE googletest googlemock ) -# When used from the buildtree, also force use of buildtree LLVM headers, -# (instead locally installed version) -# FIXME: Shouldn't this be done for all LLVM libraries? Currently, LLVM uses a -# big giant `include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})` -# which CMake does not add to the import library. -target_include_directories(llvm_gtest BEFORE - PUBLIC $ - $ - ) +if(LLVM_RUNTIMES_BUILD) + target_compile_definitions("${gtest_name}" PUBLIC GTEST_NO_LLVM_SUPPORT=1) +else() + # When used from the buildtree, also force use of buildtree LLVM headers, + # (instead locally installed version) + # FIXME: Shouldn't this be done for all LLVM libraries? Currently, LLVM uses a + # big giant `include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})` + # which CMake does not add to the import library. + target_include_directories("${gtest_name}" BEFORE + PUBLIC $ + $ + ) +endif() + -add_subdirectory(UnitTestMain) +add_llvm_library("${gtest_name}_main" + ${gtest_main_src} + + LINK_LIBS + "${gtest_name}" + + LINK_COMPONENTS + ${GTEST_LLVM_COMPONENTS} + + ${BUILDTREE_ONLY} +) if (LLVM_INSTALL_GTEST) - install(DIRECTORY googletest/include/gtest/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/llvm-gtest/gtest/" COMPONENT llvm_gtest) - install(DIRECTORY googlemock/include/gmock/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/llvm-gmock/gmock/" COMPONENT llvm_gtest) + install(DIRECTORY googletest/include/gtest/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/llvm-gtest/gtest/" COMPONENT "${gtest_name}") + install(DIRECTORY googlemock/include/gmock/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/llvm-gmock/gmock/" COMPONENT "${gtest_name}") endif() # When LLVM_LINK_LLVM_DYLIB is enabled, libLLVM.so is added to the interface @@ -118,5 +156,14 @@ function (gtest_remove_dylib_from_link_interface target) endif() endfunction() -gtest_remove_dylib_from_link_interface(llvm_gtest) -gtest_remove_dylib_from_link_interface(llvm_gtest_main) +if (NOT LLVM_RUNTIMES_BUILD) + gtest_remove_dylib_from_link_interface("${gtest_name}") + gtest_remove_dylib_from_link_interface("${gtest_name}_main") +endif () + +# The build processing this file always uses this GTest for unittests. +# Projects that do not use the LLVM_ENABLE_PROJECTS mechanism, but are +# standalone-builds using find_package(LLVM) can define these aliases +# explicitly. +add_library(default_gtest ALIAS "${gtest_name}") +add_library(default_gtest_main ALIAS "${gtest_name}_main") diff --git a/third-party/unittest/UnitTestMain/CMakeLists.txt b/third-party/unittest/UnitTestMain/CMakeLists.txt deleted file mode 100644 index 729ea7e3fa7e2..0000000000000 --- a/third-party/unittest/UnitTestMain/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(BUILDTREE_ONLY BUILDTREE_ONLY) -if (LLVM_INSTALL_GTEST) - set(BUILDTREE_ONLY "") -endif () - -add_llvm_library(llvm_gtest_main - TestMain.cpp - - LINK_LIBS - llvm_gtest - - LINK_COMPONENTS - Support # Depends on llvm::cl - - ${BUILDTREE_ONLY} - )