[libc-commits] [libc] [libc][cmake] Unify unit and hermetic test rules into add_libc_test (PR #233512)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Tue Oct 20 02:29:43 PDT 2026


================
@@ -286,66 +286,453 @@ function(get_link_options link_options)
   set(${link_options} "${link_opts}" PARENT_SCOPE)
 endfunction()
 
-# Rule to add a libc unittest.
-# Usage
-#    create_libc_unittest(
-#      <target name>
-#      SUITE <name of the suite this test belongs to>
-#      SRCS  <list of .cpp files for the test>
-#      HDRS  <list of .h files for the test>
-#      DEPENDS <list of dependencies>
-#      ENV <list of environment variables to set before running the test>
-#      COMPILE_OPTIONS <list of special compile options for this target>
-#      LINK_LIBRARIES <list of linking libraries for this target>
-#    )
-function(create_libc_unittest fq_target_name)
-  if(NOT LLVM_INCLUDE_TESTS)
-    return()
+# Get libgcc_s to be used in hermetic and integration tests.
+if(NOT MSVC AND NOT LIBC_CC_SUPPORTS_NOSTDLIBPP)
+  execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libgcc_s.so.1
+    OUTPUT_VARIABLE LIBGCC_S_LOCATION)
+  string(STRIP ${LIBGCC_S_LOCATION} LIBGCC_S_LOCATION)
+endif()
+
+# Hermetic and integration tests link with -nodefaultlibs, so the compiler
+# runtime builtins have to be linked explicitly. -print-libgcc-file-name
+# reports whichever library the driver would use (libgcc.a or
+# libclang_rt.builtins.a). The query uses the same flags as the test link so
+# that the driver selects the same multilib. GPU and UEFI targets do not link a
+# compiler runtime.
+if(LLVM_INCLUDE_TESTS AND LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU AND
+  NOT LIBC_TARGET_OS_IS_UEFI AND
+  NOT LIBC_TEST_BUILTINS_LIBRARY AND NOT LIBC_TEST_BUILTINS_TARGET)
+  separate_arguments(libc_cxx_flags NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
+  execute_process(
+    COMMAND ${CMAKE_CXX_COMPILER} ${libc_cxx_flags}
+      ${LIBC_COMPILE_OPTIONS_DEFAULT} ${LIBC_TEST_LINK_OPTIONS_DEFAULT}
+      -print-libgcc-file-name
+    OUTPUT_VARIABLE LIBC_TEST_BUILTINS_LIBRARY
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+  if(NOT EXISTS "${LIBC_TEST_BUILTINS_LIBRARY}")
+    message(FATAL_ERROR "Compiler runtime builtins library "
+      "'${LIBC_TEST_BUILTINS_LIBRARY}' not found. Set "
+      "LIBC_TEST_BUILTINS_LIBRARY or LIBC_TEST_BUILTINS_TARGET.")
   endif()
+endif()
 
-  cmake_parse_arguments(
-    "LIBC_UNITTEST"
-    "NO_RUN_POSTBUILD;C_TEST" # Optional arguments
-    "SUITE;CXX_STANDARD" # Single value arguments
-    "SRCS;HDRS;DEPENDS;ENV;COMPILE_OPTIONS;LINK_LIBRARIES;FLAGS" # Multi-value arguments
-    ${ARGN}
-  )
-  if(NOT LIBC_UNITTEST_SRCS)
-    message(FATAL_ERROR "'create_libc_unittest' target requires a SRCS list of .cpp "
-      "files.")
+# Rule to add a test suite in the hierarchy.
+# Automatically creates <suite_name> (run target) and <suite_name>-build (build target).
+# Connects them to libc-tests and libc-tests-build.
+function(add_libc_testsuite suite_name)
+  if(NOT TARGET ${suite_name})
----------------
labath wrote:

What is the reasoning here? Is the idea to remove all manual test suite creation and have them be created lazily?

I can live with this, but personally I like explicit target (test suite or otherwise) creation, and I'm not a big fan of `if(TARGET)` conditionals -- they make it easy to create subtle differences by reordering two function calls.

https://github.com/llvm/llvm-project/pull/233512


More information about the libc-commits mailing list