From 0a169b49add9f12cb3558b6147e784819de4b3ca Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Thu, 23 Oct 2025 09:09:36 +0200 Subject: [PATCH 01/11] Test no-LLVM gtest --- cmake/Modules/AddGTest.cmake | 12 +++++ flang-rt/unittests/CMakeLists.txt | 2 +- .../unittests/Runtime/CrashHandlerFixture.cpp | 2 +- libc/benchmarks/CMakeLists.txt | 4 +- llvm/CMakeLists.txt | 7 +-- llvm/cmake/modules/AddLLVM.cmake | 2 +- runtimes/CMakeLists.txt | 8 +++ third-party/unittest/CMakeLists.txt | 53 ++++++++++++++----- .../unittest/UnitTestMain/CMakeLists.txt | 4 +- 9 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 cmake/Modules/AddGTest.cmake diff --git a/cmake/Modules/AddGTest.cmake b/cmake/Modules/AddGTest.cmake new file mode 100644 index 0000000000000..d62b5b2c31995 --- /dev/null +++ b/cmake/Modules/AddGTest.cmake @@ -0,0 +1,12 @@ + +function (build_gtest gtest_name) + cmake_parse_arguments(ARG "LLVM_SUPPORT" "" "" ${ARGN}) + + if (ARG_LLVM_SUPPORT) + set(GTEST_USE_LLVM 1) + else () + set(GTEST_USE_LLVM 0) + endif () + add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/${gtest_name}_gtest") +endfunction () + diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt index 53cd54dfd215e..f3ea468c5367a 100644 --- a/flang-rt/unittests/CMakeLists.txt +++ b/flang-rt/unittests/CMakeLists.txt @@ -22,7 +22,7 @@ if (CMAKE_CROSSCOMPILING) return () endif () -if (NOT TARGET llvm_gtest) +if (NOT TARGET default_gtest) message(WARNING "Flang-RT unittests disabled due to GTest being unavailable; " "Try LLVM_INSTALL_GTEST=ON for the LLVM build") return () diff --git a/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp b/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp index 8213edd1f9225..92fe67405db3a 100644 --- a/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp +++ b/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp @@ -17,7 +17,7 @@ char buffer[1000]; std::vsnprintf(buffer, sizeof buffer, message, ap); va_end(ap); - llvm::errs() + std::cerr << "Test " << ::testing::UnitTest::GetInstance()->current_test_info()->name() << " crashed in file " diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt index 60f522d7d8c65..63051dad8e23b 100644 --- a/libc/benchmarks/CMakeLists.txt +++ b/libc/benchmarks/CMakeLists.txt @@ -38,8 +38,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 c450ee5a3d72e..19e541122541e 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -1340,9 +1340,10 @@ 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) + include(AddGTest) + build_gtest(llvm_gtest LLVM_SUPPORT) + add_library(default_gtest ALIAS llvm_gtest) + add_library(default_gtest_main ALIAS llvm_gtest_main) endif() else() if ( LLVM_INCLUDE_TESTS ) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 80e59a4df2433..45bbbbb6381d1 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1797,7 +1797,7 @@ 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}) + target_link_libraries(${test_name} PRIVATE default_gtest_main default_gtest ${LLVM_PTHREAD_LIB}) add_dependencies(${test_suite} ${test_name}) endfunction() diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index d3280a5867dec..91c95473cb4ea 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -242,6 +242,14 @@ 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 +if (LLVM_INCLUDE_TESTS) + include(AddGTest) + build_gtest(runtimes_gtest) + add_library(default_gtest ALIAS runtimes_gtest) + add_library(default_gtest_main ALIAS runtimes_gtest_main) +endif () + 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..5242bf30dcc77 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -11,6 +11,15 @@ # # Project-wide settings +set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") + +if (GTEST_USE_LLVM) + set(GTEST_LLVM_COMPONENTS "Support") # For llvm::raw_ostream +else () + # Override locally; never install a non-LLVM GTest + set(LLVM_INSTALL_GTEST OFF) +endif () + if(WIN32) add_definitions(-DGTEST_OS_WINDOWS=1) endif() @@ -48,7 +57,7 @@ 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 +65,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 +76,15 @@ 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 $ $ $ @@ -89,16 +98,32 @@ target_include_directories(llvm_gtest # 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 (GTEST_USE_LLVM) + target_include_directories("${gtest_name}" BEFORE + PUBLIC $ + $ + ) +else () + target_compile_definitions("${gtest_name}" PUBLIC GTEST_NO_LLVM_SUPPORT=1) +endif () -add_subdirectory(UnitTestMain) +# Library that contains main() +if (GTEST_USE_LLVM) + add_subdirectory(UnitTestMain) +else () + add_llvm_library("${gtest_name}_main" + googletest/src/gtest_main.cc + + LINK_LIBS + "${gtest_name}" + + ${BUILDTREE_ONLY} + ) +endif () 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 +143,5 @@ 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) +gtest_remove_dylib_from_link_interface("${gtest_name}") +gtest_remove_dylib_from_link_interface("${gtest_name}_main") diff --git a/third-party/unittest/UnitTestMain/CMakeLists.txt b/third-party/unittest/UnitTestMain/CMakeLists.txt index 729ea7e3fa7e2..225c33c911f7e 100644 --- a/third-party/unittest/UnitTestMain/CMakeLists.txt +++ b/third-party/unittest/UnitTestMain/CMakeLists.txt @@ -3,11 +3,11 @@ if (LLVM_INSTALL_GTEST) set(BUILDTREE_ONLY "") endif () -add_llvm_library(llvm_gtest_main +add_llvm_library("${gtest_name}_main" TestMain.cpp LINK_LIBS - llvm_gtest + "${gtest_name}" LINK_COMPONENTS Support # Depends on llvm::cl From a4f3218b55184c5cb5f153d759e36771a091b168 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Thu, 23 Oct 2025 12:34:21 +0200 Subject: [PATCH 02/11] clang-format --- flang-rt/unittests/Runtime/CrashHandlerFixture.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp b/flang-rt/unittests/Runtime/CrashHandlerFixture.cpp index 92fe67405db3a..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); - std::cerr - << "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); } From ec055d40dd2c19c3cbc0513730c41f0f4202e2e2 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Thu, 23 Oct 2025 13:10:19 +0200 Subject: [PATCH 03/11] Avoid use of llvm::Twine --- flang-rt/unittests/Runtime/AccessTest.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 From 837e56560a4eb7c8727f5fa1e2454c58c39e4a5f Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Thu, 23 Oct 2025 13:55:41 +0200 Subject: [PATCH 04/11] -Werror fix --- .../unittests/Evaluate/ISO-Fortran-binding.cpp | 14 ++++++-------- flang-rt/unittests/Runtime/Descriptor.cpp | 4 ++-- flang-rt/unittests/Runtime/ExternalIOTest.cpp | 1 - 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp b/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp index 8c0a6f29b6967..530682327611b 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; @@ -77,13 +76,12 @@ static void AddNoiseToCdesc(CFI_cdesc_t *dv, CFI_rank_t rank) { 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(); + std::cout << " base_addr: " << std::hex << reinterpret_cast(bAddr) + " attribute: " << std::dec << static_cast(attr) + " type: " << std::dec << static_cast(ty) << " elem_len: " << std::dec << eLen + " rank: " << std::dec << static_cast(rank) << " extent: " + << std::hex << reinterpret_cast(eAddr)) << std::endl; + std::cout << std::dec; } #endif 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 From 7cd1a750af5287850dd1cb9d4cd8283437553162 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Thu, 23 Oct 2025 14:04:18 +0200 Subject: [PATCH 05/11] Remove unused debug code --- .../Evaluate/ISO-Fortran-binding.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp b/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp index 530682327611b..1a9817cc665de 100644 --- a/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp +++ b/flang-rt/unittests/Evaluate/ISO-Fortran-binding.cpp @@ -72,25 +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) { - std::cout << " base_addr: " << std::hex << reinterpret_cast(bAddr) - " attribute: " << std::dec << static_cast(attr) - " type: " << std::dec << static_cast(ty) << " elem_len: " << std::dec << eLen - " rank: " << std::dec << static_cast(rank) << " extent: " - << std::hex << reinterpret_cast(eAddr)) << std::endl; - std::cout << std::dec; -} -#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)}; @@ -303,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) { From 5448b16a482a53a145b2b8285f5185961506ed44 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 27 Oct 2025 14:42:37 +0100 Subject: [PATCH 06/11] Adjust warning message --- flang-rt/unittests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt index f3ea468c5367a..3502ed6de6efe 100644 --- a/flang-rt/unittests/CMakeLists.txt +++ b/flang-rt/unittests/CMakeLists.txt @@ -24,7 +24,7 @@ endif () if (NOT TARGET default_gtest) message(WARNING "Flang-RT unittests disabled due to GTest being unavailable; " - "Try LLVM_INSTALL_GTEST=ON for the LLVM build") + "FLANG_RT_INCLUDE_TESTS=ON requires LLVM_INCLUDE_TESTS=ON") return () endif () From c97bef422d8afdfe2f8519f293dae9d6a8a87171 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 10 Nov 2025 12:54:14 +0100 Subject: [PATCH 07/11] Fix mingw-incomplete-sysroot build --- flang-rt/unittests/CMakeLists.txt | 7 +------ libc/benchmarks/CMakeLists.txt | 2 ++ runtimes/CMakeLists.txt | 14 ++++++++++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt index 3502ed6de6efe..47366d22bafb2 100644 --- a/flang-rt/unittests/CMakeLists.txt +++ b/flang-rt/unittests/CMakeLists.txt @@ -22,12 +22,7 @@ if (CMAKE_CROSSCOMPILING) return () endif () -if (NOT TARGET default_gtest) - message(WARNING "Flang-RT unittests disabled due to GTest being unavailable; " - "FLANG_RT_INCLUDE_TESTS=ON requires LLVM_INCLUDE_TESTS=ON") - return () -endif () - +make_gtest_target() add_dependencies(flang-rt-test-depends FlangRTUnitTests diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt index 63051dad8e23b..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() diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index 84804e64a9822..9b9b859353240 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -256,13 +256,23 @@ 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 -if (LLVM_INCLUDE_TESTS) +# 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 header files that GTest needs to compile. +function(make_gtest_target) + if(TARGET default_gtest) + # Already available + return () + endif () + include(AddGTest) build_gtest(runtimes_gtest) add_library(default_gtest ALIAS runtimes_gtest) add_library(default_gtest_main ALIAS runtimes_gtest_main) -endif () +endfunction() + foreach(entry ${runtimes}) get_filename_component(projName ${entry} NAME) From 93aea3b73c6cfb5c2f06624efeb767493626f725 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 10 Nov 2025 16:12:42 +0100 Subject: [PATCH 08/11] LLDB and Flang standalone build fixes --- cmake/Modules/AddGTest.cmake | 1 - flang/CMakeLists.txt | 10 ++++++++-- lldb/cmake/modules/LLDBStandalone.cmake | 5 +++-- third-party/unittest/CMakeLists.txt | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cmake/Modules/AddGTest.cmake b/cmake/Modules/AddGTest.cmake index d62b5b2c31995..61c555ed789d2 100644 --- a/cmake/Modules/AddGTest.cmake +++ b/cmake/Modules/AddGTest.cmake @@ -9,4 +9,3 @@ function (build_gtest gtest_name) endif () add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/${gtest_name}_gtest") endfunction () - diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index c01eb56d5e496..7b465d15f23c8 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -76,6 +76,11 @@ endif() set(MLIR_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mlir" CACHE PATH "Path to MLIR source tree") if (FLANG_STANDALONE_BUILD) + if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) + set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) + endif() + list(APPEND CMAKE_MODULE_PATH "${LLVM_COMMON_CMAKE_UTILS}/Modules") + set(FLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) if (NOT MSVC_IDE) @@ -226,8 +231,9 @@ if (FLANG_STANDALONE_BUILD) if (FLANG_INCLUDE_TESTS) set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h) - if (NOT TARGET llvm_gtest) - add_subdirectory(${UNITTEST_DIR} third-party/unittest) + if (NOT TARGET default_gtest) + include(AddGTest) + build_gtest(flang_gtest LLVM_SUPPORT) endif() set(FLANG_GTEST_AVAIL 1) else() diff --git a/lldb/cmake/modules/LLDBStandalone.cmake b/lldb/cmake/modules/LLDBStandalone.cmake index 1a4cdbfbb1cc7..987cc515a7a45 100644 --- a/lldb/cmake/modules/LLDBStandalone.cmake +++ b/lldb/cmake/modules/LLDBStandalone.cmake @@ -106,8 +106,9 @@ include_directories( if(LLDB_INCLUDE_TESTS) # Build the gtest library needed for unittests, if we have LLVM sources # handy. - if (EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest AND NOT TARGET llvm_gtest) - add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest third-party/unittest) + if (EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest AND NOT TARGET default_gtest) + include(AddGTest) + build_gtest(lldb_gtest LLVM_SUPPORT) endif() # LLVMTestingSupport library is needed for Process/gdb-remote. if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support diff --git a/third-party/unittest/CMakeLists.txt b/third-party/unittest/CMakeLists.txt index 5242bf30dcc77..cfc18c4416d76 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -7,12 +7,28 @@ # To run the tests for Google Test itself on Linux, use 'make test' or # ctest. You can select which tests to run using 'ctest -R regex'. # For more options, run 'ctest --help'. +# +# Do not add_subdirectory(third-party/unittest) this file directly. +# Instead use: +# +# include(AddGTest) +# build_gtest(llvm_gtest [LLVM_SUPPORT]) +# ######################################################################## # # Project-wide settings set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") +if (NOT gtest_name) + message(FATAL_ERROR "Do not add_subdirectory GTest directly. Use the + following helper function instead: + + include(AddGTest) + build_gtest(llvm_gtest [LLVM_SUPPORT]) + ") +endif () + if (GTEST_USE_LLVM) set(GTEST_LLVM_COMPONENTS "Support") # For llvm::raw_ostream else () From 73f1f820b3185ac6679c1678bfda20f1040a1cf0 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 10 Nov 2025 19:36:24 +0100 Subject: [PATCH 09/11] Remove AddGTest.cmake for simplicity --- cmake/Modules/AddGTest.cmake | 11 --- flang-rt/unittests/CMakeLists.txt | 3 +- flang/CMakeLists.txt | 10 +- lldb/cmake/modules/LLDBStandalone.cmake | 5 +- llvm/CMakeLists.txt | 5 +- llvm/cmake/modules/AddLLVM.cmake | 8 +- runtimes/CMakeLists.txt | 16 ++-- third-party/unittest/CMakeLists.txt | 95 ++++++++++--------- .../unittest/UnitTestMain/CMakeLists.txt | 16 ---- 9 files changed, 69 insertions(+), 100 deletions(-) delete mode 100644 cmake/Modules/AddGTest.cmake delete mode 100644 third-party/unittest/UnitTestMain/CMakeLists.txt diff --git a/cmake/Modules/AddGTest.cmake b/cmake/Modules/AddGTest.cmake deleted file mode 100644 index 61c555ed789d2..0000000000000 --- a/cmake/Modules/AddGTest.cmake +++ /dev/null @@ -1,11 +0,0 @@ - -function (build_gtest gtest_name) - cmake_parse_arguments(ARG "LLVM_SUPPORT" "" "" ${ARGN}) - - if (ARG_LLVM_SUPPORT) - set(GTEST_USE_LLVM 1) - else () - set(GTEST_USE_LLVM 0) - endif () - add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_BINARY_DIR}/third-party/${gtest_name}_gtest") -endfunction () diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt index 47366d22bafb2..e1ab73d7d9301 100644 --- a/flang-rt/unittests/CMakeLists.txt +++ b/flang-rt/unittests/CMakeLists.txt @@ -22,7 +22,8 @@ if (CMAKE_CROSSCOMPILING) return () endif () -make_gtest_target() +# Make the targets default_gtest and default_gtest_main available. +build_gtest() add_dependencies(flang-rt-test-depends FlangRTUnitTests diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 7b465d15f23c8..c01eb56d5e496 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -76,11 +76,6 @@ endif() set(MLIR_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mlir" CACHE PATH "Path to MLIR source tree") if (FLANG_STANDALONE_BUILD) - if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) - set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) - endif() - list(APPEND CMAKE_MODULE_PATH "${LLVM_COMMON_CMAKE_UTILS}/Modules") - set(FLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) if (NOT MSVC_IDE) @@ -231,9 +226,8 @@ if (FLANG_STANDALONE_BUILD) if (FLANG_INCLUDE_TESTS) set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h) - if (NOT TARGET default_gtest) - include(AddGTest) - build_gtest(flang_gtest LLVM_SUPPORT) + if (NOT TARGET llvm_gtest) + add_subdirectory(${UNITTEST_DIR} third-party/unittest) endif() set(FLANG_GTEST_AVAIL 1) else() diff --git a/lldb/cmake/modules/LLDBStandalone.cmake b/lldb/cmake/modules/LLDBStandalone.cmake index 987cc515a7a45..1a4cdbfbb1cc7 100644 --- a/lldb/cmake/modules/LLDBStandalone.cmake +++ b/lldb/cmake/modules/LLDBStandalone.cmake @@ -106,9 +106,8 @@ include_directories( if(LLDB_INCLUDE_TESTS) # Build the gtest library needed for unittests, if we have LLVM sources # handy. - if (EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest AND NOT TARGET default_gtest) - include(AddGTest) - build_gtest(lldb_gtest LLVM_SUPPORT) + if (EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest AND NOT TARGET llvm_gtest) + add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest third-party/unittest) endif() # LLVMTestingSupport library is needed for Process/gdb-remote. if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index c02f5398df1ce..c02c75f10b12f 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -1340,10 +1340,7 @@ if( LLVM_INCLUDE_UTILS ) add_subdirectory(utils/mlgo-utils) add_subdirectory(utils/llvm-test-mustache-spec) if( LLVM_INCLUDE_TESTS ) - include(AddGTest) - build_gtest(llvm_gtest LLVM_SUPPORT) - add_library(default_gtest ALIAS llvm_gtest) - add_library(default_gtest_main ALIAS llvm_gtest_main) + add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest) endif() else() if ( LLVM_INCLUDE_TESTS ) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 2fe23afa31c97..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 default_gtest_main default_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 9b9b859353240..b17bd8f665361 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -256,24 +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 header files that GTest needs to compile. -function(make_gtest_target) +# mingw-incomplete-sysroot is missing C++ header files that GTest needs to +# compile. +function(build_gtest) if(TARGET default_gtest) # Already available - return () - endif () + return() + endif() - include(AddGTest) - build_gtest(runtimes_gtest) - add_library(default_gtest ALIAS runtimes_gtest) - add_library(default_gtest_main ALIAS runtimes_gtest_main) + 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 cfc18c4416d76..54f037e2f9de7 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -7,34 +7,37 @@ # To run the tests for Google Test itself on Linux, use 'make test' or # ctest. You can select which tests to run using 'ctest -R regex'. # For more options, run 'ctest --help'. -# -# Do not add_subdirectory(third-party/unittest) this file directly. -# Instead use: -# -# include(AddGTest) -# build_gtest(llvm_gtest [LLVM_SUPPORT]) -# ######################################################################## # # Project-wide settings set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") -if (NOT gtest_name) - message(FATAL_ERROR "Do not add_subdirectory GTest directly. Use the - following helper function instead: +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 "") - include(AddGTest) - build_gtest(llvm_gtest [LLVM_SUPPORT]) - ") -endif () + # 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") -if (GTEST_USE_LLVM) - set(GTEST_LLVM_COMPONENTS "Support") # For llvm::raw_ostream -else () - # Override locally; never install a non-LLVM GTest + # Override locally; never install the runtimes-GTest. set(LLVM_INSTALL_GTEST OFF) -endif () + + # 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) @@ -63,10 +66,6 @@ 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) @@ -99,7 +98,6 @@ if (NOT LLVM_ENABLE_THREADS) 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("${gtest_name}" PUBLIC $ $ @@ -109,33 +107,29 @@ target_include_directories("${gtest_name}" 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. -if (GTEST_USE_LLVM) +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 $ $ ) -else () - target_compile_definitions("${gtest_name}" PUBLIC GTEST_NO_LLVM_SUPPORT=1) -endif () +endif() -# Library that contains main() -if (GTEST_USE_LLVM) - add_subdirectory(UnitTestMain) -else () - add_llvm_library("${gtest_name}_main" - googletest/src/gtest_main.cc - LINK_LIBS - "${gtest_name}" +add_llvm_library("${gtest_name}_main" + googletest/src/gtest_main.cc - ${BUILDTREE_ONLY} - ) -endif () + LINK_LIBS + "${gtest_name}" + + ${BUILDTREE_ONLY} +) if (LLVM_INSTALL_GTEST) install(DIRECTORY googletest/include/gtest/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/llvm-gtest/gtest/" COMPONENT "${gtest_name}") @@ -159,5 +153,14 @@ function (gtest_remove_dylib_from_link_interface target) endif() endfunction() -gtest_remove_dylib_from_link_interface("${gtest_name}") -gtest_remove_dylib_from_link_interface("${gtest_name}_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 225c33c911f7e..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("${gtest_name}_main" - TestMain.cpp - - LINK_LIBS - "${gtest_name}" - - LINK_COMPONENTS - Support # Depends on llvm::cl - - ${BUILDTREE_ONLY} - ) From 1bdbaafa569afe1762c8fcff0dfd8a058476ba3f Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 10 Nov 2025 20:50:49 +0100 Subject: [PATCH 10/11] gtest_main build fix --- third-party/unittest/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/unittest/CMakeLists.txt b/third-party/unittest/CMakeLists.txt index 54f037e2f9de7..97cf1e34c1f7e 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -123,7 +123,7 @@ endif() add_llvm_library("${gtest_name}_main" - googletest/src/gtest_main.cc + ${gtest_main_src} LINK_LIBS "${gtest_name}" From 31f52c3d47c47eec89644123550ea78d0b51c59b Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Tue, 11 Nov 2025 10:57:48 +0100 Subject: [PATCH 11/11] explicitly link LLVMSupport --- third-party/unittest/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third-party/unittest/CMakeLists.txt b/third-party/unittest/CMakeLists.txt index 97cf1e34c1f7e..79535a1de4616 100644 --- a/third-party/unittest/CMakeLists.txt +++ b/third-party/unittest/CMakeLists.txt @@ -128,6 +128,9 @@ add_llvm_library("${gtest_name}_main" LINK_LIBS "${gtest_name}" + LINK_COMPONENTS + ${GTEST_LLVM_COMPONENTS} + ${BUILDTREE_ONLY} )