[libclc] [libclc][CMake] Add check-libclc umbrella test target (PR #186053)

Wenju He via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 12 01:26:08 PDT 2026


https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/186053

>From bf9d49b1337ccd4d7b898df25fa9e7dbba97f7ab Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Thu, 12 Mar 2026 09:19:11 +0100
Subject: [PATCH 1/2] [libclc][CMake] Add check-libclc umbrella test target

This allows running the full test suite using `ninja check-libclc`.
---
 libclc/CMakeLists.txt                     |  4 +-
 libclc/cmake/modules/AddLibclc.cmake      | 10 -----
 libclc/test/CMakeLists.txt                | 50 +++++++++++++++++++++++
 libclc/{ => test}/check_external_funcs.sh |  0
 libclc/test/lit.cfg.py                    | 43 +++++++++++++++++++
 libclc/test/lit.site.cfg.py.in            | 14 +++++++
 6 files changed, 109 insertions(+), 12 deletions(-)
 create mode 100644 libclc/test/CMakeLists.txt
 rename libclc/{ => test}/check_external_funcs.sh (100%)
 create mode 100644 libclc/test/lit.cfg.py
 create mode 100644 libclc/test/lit.site.cfg.py.in

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 95cb56aaec17d..1103711298ce3 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -138,8 +138,6 @@ add_custom_target( libclc ALL )
 add_custom_target( libclc-opencl-builtins COMMENT "Build libclc OpenCL builtins" )
 add_dependencies( libclc libclc-opencl-builtins )
 
-enable_testing()
-
 foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
   message( STATUS "libclc target '${t}' is enabled" )
   string( REPLACE "-" ";" TRIPLE  ${t} )
@@ -279,3 +277,5 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
     PARENT_TARGET libclc-opencl-builtins
   )
 endforeach()
+
+add_subdirectory(test)
diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake
index 1ae802c29626e..2b8ff956d4a8e 100644
--- a/libclc/cmake/modules/AddLibclc.cmake
+++ b/libclc/cmake/modules/AddLibclc.cmake
@@ -187,14 +187,4 @@ function(add_libclc_library target_name)
     DESTINATION ${LIBCLC_INSTALL_DIR}/${ARG_TRIPLE}
     COMPONENT ${ARG_PARENT_TARGET}
   )
-
-  # Verify there are no unresolved external functions in the library.
-  if(NOT ARG_ARCH MATCHES "^(nvptx|clspv)(64)?$" AND
-     NOT ARG_ARCH MATCHES "^spirv(64)?$")
-    set(builtins_file $<TARGET_PROPERTY:${target_name},TARGET_FILE>)
-    add_test(NAME external-funcs-${target_name}
-      COMMAND ./check_external_funcs.sh
-              ${builtins_file} ${LLVM_TOOLS_BINARY_DIR}
-      WORKING_DIRECTORY ${LIBCLC_SOURCE_DIR})
-  endif()
 endfunction()
diff --git a/libclc/test/CMakeLists.txt b/libclc/test/CMakeLists.txt
new file mode 100644
index 0000000000000..cd0253f73d43a
--- /dev/null
+++ b/libclc/test/CMakeLists.txt
@@ -0,0 +1,50 @@
+set(LIBCLC_LIBRARY_DIR ${LIBCLC_OUTPUT_LIBRARY_DIR})
+set(LLVM_TOOLS_DIR ${LLVM_TOOLS_BINARY_DIR})
+
+set(LIBCLC_TEST_DEPS
+  llvm-dis
+)
+
+umbrella_lit_testsuite_begin(check-libclc)
+
+# Testing unresolved symbols.
+# check_external_funcs.sh does not work on Windows
+if(NOT WIN32)
+  foreach(t ${LIBCLC_TARGETS_TO_BUILD})
+    string(REPLACE "-" ";" TRIPLE ${t})
+    list(GET TRIPLE 0 ARCH)
+
+    # Skip nvptx, clspv, spirv targets
+    if(ARCH MATCHES "^(nvptx|clspv)(64)?$" OR ARCH MATCHES "^spirv(64)?$")
+      continue()
+    endif()
+
+    # Get the output file from the target property
+    get_target_property(target_file libclc-${t} TARGET_FILE)
+    get_filename_component(output_file ${target_file} NAME)
+
+    set(LIBCLC_TARGET_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/${t})
+    file(MAKE_DIRECTORY ${LIBCLC_TARGET_TEST_DIR})
+    file(WRITE ${LIBCLC_TARGET_TEST_DIR}/check-external-funcs.test
+"// RUN: %check_external_funcs %libclc_library_dir/${t}/${output_file} %llvm_tools_dir
+
+// This test verifies that the libclc library for ${t} has no
+// unresolved external functions (except LLVM intrinsics).
+")
+
+    configure_lit_site_cfg(
+        ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+        ${LIBCLC_TARGET_TEST_DIR}/lit.site.cfg.py
+        MAIN_CONFIG
+        ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+    )
+
+    add_lit_testsuite(check-libclc-external-funcs-${t} "Running ${t} tests"
+      ${LIBCLC_TARGET_TEST_DIR}
+      DEPENDS libclc-${t} ${LIBCLC_TEST_DEPS}
+    )
+    set_target_properties(check-libclc-external-funcs-${t} PROPERTIES FOLDER "libclc tests")
+  endforeach()
+endif()
+
+umbrella_lit_testsuite_end(check-libclc)
diff --git a/libclc/check_external_funcs.sh b/libclc/test/check_external_funcs.sh
similarity index 100%
rename from libclc/check_external_funcs.sh
rename to libclc/test/check_external_funcs.sh
diff --git a/libclc/test/lit.cfg.py b/libclc/test/lit.cfg.py
new file mode 100644
index 0000000000000..e2899ac694863
--- /dev/null
+++ b/libclc/test/lit.cfg.py
@@ -0,0 +1,43 @@
+"""
+Lit configuration file for libclc tests.
+"""
+
+import os
+
+import lit.formats
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'libclc'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ShTest(True)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.test']
+
+# Exclude certain directories from test discovery
+config.excludes = ['CMakeLists.txt']
+
+# test_source_root: The root path where tests are located.
+# For per-target tests, this is the target's test directory.
+config.test_source_root = config.libclc_obj_root
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = config.libclc_obj_root
+
+# Propagate PATH from environment
+if 'PATH' in os.environ:
+    config.environment['PATH'] = os.path.pathsep.join([
+        config.llvm_tools_dir,
+        os.environ['PATH']
+    ])
+else:
+    config.environment['PATH'] = config.llvm_tools_dir
+
+# Define substitutions for the test files
+config.substitutions.append(('%libclc_library_dir', config.libclc_library_dir))
+config.substitutions.append(('%llvm_tools_dir', config.llvm_tools_dir))
+config.substitutions.append(('%check_external_funcs',
+                            os.path.join(config.libclc_test_root, 'check_external_funcs.sh')))
diff --git a/libclc/test/lit.site.cfg.py.in b/libclc/test/lit.site.cfg.py.in
new file mode 100644
index 0000000000000..d43d6111f4ae9
--- /dev/null
+++ b/libclc/test/lit.site.cfg.py.in
@@ -0,0 +1,14 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.libclc_obj_root = "@LIBCLC_TARGET_TEST_DIR@"
+config.libclc_test_root = "@CMAKE_CURRENT_SOURCE_DIR@"
+config.libclc_library_dir = "@LIBCLC_LIBRARY_DIR@"
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")

>From 02e2139975fe733e322a4babd0787cdaa4e93df4 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Thu, 12 Mar 2026 09:25:51 +0100
Subject: [PATCH 2/2] code formatter

---
 libclc/test/lit.cfg.py | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/libclc/test/lit.cfg.py b/libclc/test/lit.cfg.py
index e2899ac694863..d5a9b5e366e37 100644
--- a/libclc/test/lit.cfg.py
+++ b/libclc/test/lit.cfg.py
@@ -9,16 +9,16 @@
 # Configuration file for the 'lit' test runner.
 
 # name: The name of this test suite.
-config.name = 'libclc'
+config.name = "libclc"
 
 # testFormat: The test format to use to interpret tests.
 config.test_format = lit.formats.ShTest(True)
 
 # suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.test']
+config.suffixes = [".test"]
 
 # Exclude certain directories from test discovery
-config.excludes = ['CMakeLists.txt']
+config.excludes = ["CMakeLists.txt"]
 
 # test_source_root: The root path where tests are located.
 # For per-target tests, this is the target's test directory.
@@ -28,16 +28,19 @@
 config.test_exec_root = config.libclc_obj_root
 
 # Propagate PATH from environment
-if 'PATH' in os.environ:
-    config.environment['PATH'] = os.path.pathsep.join([
-        config.llvm_tools_dir,
-        os.environ['PATH']
-    ])
+if "PATH" in os.environ:
+    config.environment["PATH"] = os.path.pathsep.join(
+        [config.llvm_tools_dir, os.environ["PATH"]]
+    )
 else:
-    config.environment['PATH'] = config.llvm_tools_dir
+    config.environment["PATH"] = config.llvm_tools_dir
 
 # Define substitutions for the test files
-config.substitutions.append(('%libclc_library_dir', config.libclc_library_dir))
-config.substitutions.append(('%llvm_tools_dir', config.llvm_tools_dir))
-config.substitutions.append(('%check_external_funcs',
-                            os.path.join(config.libclc_test_root, 'check_external_funcs.sh')))
+config.substitutions.append(("%libclc_library_dir", config.libclc_library_dir))
+config.substitutions.append(("%llvm_tools_dir", config.llvm_tools_dir))
+config.substitutions.append(
+    (
+        "%check_external_funcs",
+        os.path.join(config.libclc_test_root, "check_external_funcs.sh"),
+    )
+)



More information about the cfe-commits mailing list