Skip to content

[offload][openmp] - Remove standalone build in favor of 'runtimes'#170693

Open
estewart08 wants to merge 1 commit intollvm:mainfrom
estewart08:remove-openmp-standalone-support
Open

[offload][openmp] - Remove standalone build in favor of 'runtimes'#170693
estewart08 wants to merge 1 commit intollvm:mainfrom
estewart08:remove-openmp-standalone-support

Conversation

@estewart08
Copy link
Contributor

Summary:
We have supported standalone builds in the past, but these should likely all go through the LLVM runtimes handling instead. This simplifies a lot of leftover code and opens the way for future cleanups. Offload directly depends on LLVM so this makes even more sense, but already several runtimes projects don't allow these sorts of standalone builds (libc, libcxx).

Building on #162904, which should solve the build/lit issues seen.

@llvmbot llvmbot added openmp:libomp OpenMP host runtime offload labels Dec 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 4, 2025

@llvm/pr-subscribers-offload

Author: None (estewart08)

Changes

Summary:
We have supported standalone builds in the past, but these should likely all go through the LLVM runtimes handling instead. This simplifies a lot of leftover code and opens the way for future cleanups. Offload directly depends on LLVM so this makes even more sense, but already several runtimes projects don't allow these sorts of standalone builds (libc, libcxx).

Building on #162904, which should solve the build/lit issues seen.


Patch is 34.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170693.diff

12 Files Affected:

  • (modified) offload/CMakeLists.txt (+33-138)
  • (modified) offload/cmake/Modules/LibomptargetGetDependencies.cmake (+10-26)
  • (modified) offload/cmake/OpenMPTesting.cmake (+17-18)
  • (modified) offload/test/CMakeLists.txt (+1-1)
  • (modified) openmp/CMakeLists.txt (+35-77)
  • (modified) openmp/cmake/OpenMPTesting.cmake (+37-60)
  • (modified) openmp/docs/SupportAndFAQ.rst (+15)
  • (modified) openmp/runtime/CMakeLists.txt (+46-90)
  • (modified) openmp/runtime/src/CMakeLists.txt (+3-5)
  • (modified) openmp/runtime/test/CMakeLists.txt (-1)
  • (modified) openmp/runtime/test/lit.site.cfg.in (-1)
  • (modified) openmp/tools/omptest/CMakeLists.txt (+1-1)
diff --git a/offload/CMakeLists.txt b/offload/CMakeLists.txt
index 6e801b1d47011..bcf7f57c8bedc 100644
--- a/offload/CMakeLists.txt
+++ b/offload/CMakeLists.txt
@@ -4,14 +4,6 @@
 cmake_minimum_required(VERSION 3.20.0)
 set(LLVM_SUBPROJECT_TITLE "liboffload")
 
-# Permit redefining OPENMP_STANDALONE_BUILD when doing a runtimes build.
-if (OPENMP_STANDALONE_BUILD OR "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
-  set(OPENMP_STANDALONE_BUILD TRUE)
-  project(offload C CXX ASM)
-else()
-  set(OPENMP_STANDALONE_BUILD FALSE)
-endif()
-
 # Check that the library can actually be built.
 if(APPLE OR WIN32 OR WASM)
   message(WARNING "libomptarget cannot be built on Windows and MacOS X!")
@@ -26,20 +18,13 @@ endif()
 
 set(OFFLOAD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
-if(OPENMP_STANDALONE_BUILD)
-  set(OFFLOAD_LIBDIR_SUFFIX "" CACHE STRING
-    "Suffix of lib installation directory, e.g. 64 => lib64")
-  set(OFFLOAD_INSTALL_LIBDIR "lib${OFFLOAD_LIBDIR_SUFFIX}" CACHE STRING
-      "Path where built offload libraries should be installed.")
+# When building in tree we install the runtime according to the LLVM settings.
+if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
+  set(OFFLOAD_INSTALL_LIBDIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING
+    "Path where built offload libraries should be installed.")
 else()
-  # When building in tree we install the runtime according to the LLVM settings.
-  if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
-    set(OFFLOAD_INSTALL_LIBDIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING
-      "Path where built offload libraries should be installed.")
-  else()
-    set(OFFLOAD_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}" CACHE STRING
-      "Path where built offload libraries should be installed.")
-  endif()
+  set(OFFLOAD_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}" CACHE STRING
+    "Path where built offload libraries should be installed.")
 endif()
 
 set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
@@ -55,69 +40,38 @@ list(INSERT CMAKE_MODULE_PATH 0
   "${LLVM_COMMON_CMAKE_UTILS}/Modules"
   )
 
-if (OPENMP_STANDALONE_BUILD)
-  # CMAKE_BUILD_TYPE was not set, default to Release.
-  if (NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE Release)
-  endif()
+set(OPENMP_ENABLE_WERROR ${LLVM_ENABLE_WERROR})
+# If building in tree, we honor the same install suffix LLVM uses.
+set(OPENMP_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}")
 
-  # Group common settings.
-  set(OPENMP_ENABLE_WERROR FALSE CACHE BOOL
-    "Enable -Werror flags to turn warnings into errors for supporting compilers.")
-  set(OPENMP_LIBDIR_SUFFIX "" CACHE STRING
-    "Suffix of lib installation directory, e.g. 64 => lib64")
-  # Do not use OPENMP_LIBDIR_SUFFIX directly, use OPENMP_INSTALL_LIBDIR.
-  set(OPENMP_INSTALL_LIBDIR "lib${OPENMP_LIBDIR_SUFFIX}")
-
-  # Used by llvm_add_tool() and tests.
-  set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR})
-
-  # Group test settings.
-  set(OPENMP_TEST_C_COMPILER ${CMAKE_C_COMPILER} CACHE STRING
-    "C compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING
-    "C++ compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_TEST_Fortran_COMPILER ${CMAKE_Fortran_COMPILER} CACHE STRING
-    "FORTRAN compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_LLVM_TOOLS_DIR "" CACHE PATH "Path to LLVM tools for testing.")
-
-  set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
-  set(CMAKE_CXX_STANDARD_REQUIRED NO)
-  set(CMAKE_CXX_EXTENSIONS NO)
+if (NOT MSVC)
+  set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang)
+  set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++)
 else()
-  set(OPENMP_ENABLE_WERROR ${LLVM_ENABLE_WERROR})
-  # If building in tree, we honor the same install suffix LLVM uses.
-  set(OPENMP_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}")
-
-  if (NOT MSVC)
-    set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang)
-    set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++)
-  else()
-    set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang.exe)
-    set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++.exe)
-  endif()
-
-  # Check for flang
-  if (NOT MSVC)
-    set(OPENMP_TEST_Fortran_COMPILER ${LLVM_TOOLS_BINARY_DIR}/flang)
-  else()
-    set(OPENMP_TEST_Fortran_COMPILER ${LLVM_TOOLS_BINARY_DIR}/flang.exe)
-  endif()
+  set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang.exe)
+  set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++.exe)
+endif()
 
-  # Set fortran test compiler if flang is found
-  if (EXISTS "${OPENMP_TEST_Fortran_COMPILER}")
-    message("Using local flang build at ${OPENMP_TEST_Fortran_COMPILER}")
-  else()
-    unset(OPENMP_TEST_Fortran_COMPILER)
-  endif()
+# Check for flang
+if (NOT MSVC)
+  set(OPENMP_TEST_Fortran_COMPILER ${LLVM_TOOLS_BINARY_DIR}/flang)
+else()
+  set(OPENMP_TEST_Fortran_COMPILER ${LLVM_TOOLS_BINARY_DIR}/flang.exe)
+endif()
 
-  # If not standalone, set CMAKE_CXX_STANDARD but don't set the global cache value,
-  # only set it locally for OpenMP.
-  set(CMAKE_CXX_STANDARD 17)
-  set(CMAKE_CXX_STANDARD_REQUIRED NO)
-  set(CMAKE_CXX_EXTENSIONS NO)
+# Set fortran test compiler if flang is found
+if (EXISTS "${OPENMP_TEST_Fortran_COMPILER}")
+  message("Using local flang build at ${OPENMP_TEST_Fortran_COMPILER}")
+else()
+  unset(OPENMP_TEST_Fortran_COMPILER)
 endif()
 
+# If not standalone, set CMAKE_CXX_STANDARD but don't set the global cache value,
+# only set it locally for OpenMP.
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED NO)
+set(CMAKE_CXX_EXTENSIONS NO)
+
 # Set the path of all resulting libraries to a unified location so that it can
 # be used for testing.
 set(LIBOMPTARGET_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -125,7 +79,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBOMPTARGET_LIBRARY_DIR})
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBOMPTARGET_LIBRARY_DIR})
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBOMPTARGET_LIBRARY_DIR})
 
-if(NOT LLVM_LIBRARY_OUTPUT_INTDIR)
+if(NOT LLVM_LIBRARY_OUTPUT_INTDIR OR NOT TARGET Clang)
   set(LIBOMPTARGET_INTDIR ${LIBOMPTARGET_LIBRARY_DIR})
 else()
   set(LIBOMPTARGET_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
@@ -260,65 +214,6 @@ if (LIBOMPTARGET_USE_LTO)
   list(APPEND offload_link_flags ${CMAKE_CXX_COMPILE_OPTIONS_IPO})
 endif()
 
-if(OPENMP_STANDALONE_BUILD)
-  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-    execute_process(
-      OUTPUT_STRIP_TRAILING_WHITESPACE
-      COMMAND ${CMAKE_CXX_COMPILER} --print-resource-dir
-      RESULT_VARIABLE COMMAND_RETURN_CODE
-      OUTPUT_VARIABLE COMPILER_RESOURCE_DIR
-    )
-  endif()
-
-  set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
-  set(LIBOMP_OMPT_SUPPORT FALSE)
-
-  find_path (
-    LIBOMP_OMP_TOOLS_INCLUDE_DIR
-    NAMES
-      omp-tools.h
-    HINTS
-    ${COMPILER_RESOURCE_DIR}/include
-    ${CMAKE_INSTALL_PREFIX}/include
-  )
-
-  if(LIBOMP_OMP_TOOLS_INCLUDE_DIR)
-    set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
-    set(LIBOMP_OMPT_SUPPORT TRUE)
-  endif()
-
-  # LLVM_LIBRARY_DIRS set by find_package(LLVM) in LibomptargetGetDependencies
-  find_library (
-    LIBOMP_STANDALONE
-    NAMES
-      omp
-    HINTS
-      ${CMAKE_INSTALL_PREFIX}/lib
-      ${LLVM_LIBRARY_DIRS}
-    REQUIRED
-  )
-
-  find_path (
-    LIBOMP_INCLUDE_DIR
-    NAMES
-      omp.h
-    HINTS
-    ${COMPILER_RESOURCE_DIR}/include
-    ${CMAKE_INSTALL_PREFIX}/include
-  )
-
-  get_filename_component(LIBOMP_LIBRARY_DIR ${LIBOMP_STANDALONE} DIRECTORY)
-
-  set(OPENMP_TEST_FLAGS "" CACHE STRING
-    "Extra compiler flags to send to the test compiler.")
-  set(OPENMP_TEST_OPENMP_FLAGS ${OPENMP_TEST_COMPILER_OPENMP_FLAGS} CACHE STRING
-    "OpenMP compiler flag to use for testing OpenMP runtime libraries.")
-  set(LIBOMPTARGET_OPENMP_HEADER_FOLDER "${LIBOMP_INCLUDE_DIR}" CACHE STRING
-    "Path to folder containing omp.h")
-  set(LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER "${LIBOMP_LIBRARY_DIR}" CACHE STRING
-    "Path to folder containing libomp.so, and libLLVMSupport.so with profiling enabled")
-endif()
-
 macro(pythonize_bool var)
 if (${var})
   set(${var} True)
diff --git a/offload/cmake/Modules/LibomptargetGetDependencies.cmake b/offload/cmake/Modules/LibomptargetGetDependencies.cmake
index 2a8bdebf2c1dd..d11d32004614f 100644
--- a/offload/cmake/Modules/LibomptargetGetDependencies.cmake
+++ b/offload/cmake/Modules/LibomptargetGetDependencies.cmake
@@ -9,32 +9,16 @@ include (FindPackageHandleStandardArgs)
 ################################################################################
 # Looking for LLVM...
 ################################################################################
-
-if (OPENMP_STANDALONE_BUILD)
-  # Complete LLVM package is required for building libomptarget
-  # in an out-of-tree mode.
-  find_package(LLVM REQUIRED)
-  message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
-  message(STATUS "Using LLVM in: ${LLVM_DIR}")
-  list(APPEND LIBOMPTARGET_LLVM_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS})
-  list(APPEND CMAKE_MODULE_PATH ${LLVM_CMAKE_DIR})
-  include(AddLLVM)
-  if(TARGET omptarget)
-    message(FATAL_ERROR "CMake target 'omptarget' already exists. "
-                        "Use an LLVM installation that doesn't expose its 'omptarget' target.")
-  endif()
-else()
-  # Note that OPENMP_STANDALONE_BUILD is FALSE, when
-  # openmp is built with -DLLVM_ENABLE_RUNTIMES="openmp" vs
-  # -DLLVM_ENABLE_PROJECTS="openmp", but openmp build
-  # is actually done as a standalone project build with many
-  # LLVM CMake variables propagated to it.
-  list(APPEND LIBOMPTARGET_LLVM_INCLUDE_DIRS
-    ${LLVM_MAIN_INCLUDE_DIR} ${LLVM_BINARY_DIR}/include
-    )
-  message(STATUS
-    "Using LLVM include directories: ${LIBOMPTARGET_LLVM_INCLUDE_DIRS}")
-endif()
+# Note that OPENMP_STANDALONE_BUILD is FALSE, when
+# openmp is built with -DLLVM_ENABLE_RUNTIMES="openmp" vs
+# -DLLVM_ENABLE_PROJECTS="openmp", but openmp build
+# is actually done as a standalone project build with many
+# LLVM CMake variables propagated to it.
+list(APPEND LIBOMPTARGET_LLVM_INCLUDE_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR} ${LLVM_BINARY_DIR}/include
+  )
+message(STATUS
+  "Using LLVM include directories: ${LIBOMPTARGET_LLVM_INCLUDE_DIRS}")
 
 ################################################################################
 # Looking for libffi...
diff --git a/offload/cmake/OpenMPTesting.cmake b/offload/cmake/OpenMPTesting.cmake
index b564e46b7b193..0ff4391f98dc1 100644
--- a/offload/cmake/OpenMPTesting.cmake
+++ b/offload/cmake/OpenMPTesting.cmake
@@ -49,28 +49,27 @@ function(find_standalone_test_dependencies)
   endif()
 endfunction()
 
-if (${OPENMP_STANDALONE_BUILD})
-  find_standalone_test_dependencies()
-
-  # Set lit arguments.
-  set(DEFAULT_LIT_ARGS "-sv --show-unsupported --show-xfail")
-  if (MSVC OR XCODE)
-    set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --no-progress-bar")
-  endif()
-  if ("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
-    set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --time-tests --timeout=1800")
-  endif()
-  set(OPENMP_LIT_ARGS "${DEFAULT_LIT_ARGS}" CACHE STRING "Options for lit.")
-  separate_arguments(OPENMP_LIT_ARGS)
+if (TARGET FileCheck)
+  set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck)
+  set(OPENMP_NOT_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/not)
 else()
-  if (NOT TARGET "FileCheck")
+  find_standalone_test_dependencies()
+  if(OPENMP_FILECHECK_EXECUTABLE)
+    # Set lit arguments.
+    set(DEFAULT_LIT_ARGS "-sv --show-unsupported --show-xfail")
+    if (MSVC OR XCODE)
+      set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --no-progress-bar")
+    endif()
+    if ("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
+      set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --time-tests --timeout=1800")
+    endif()
+    set(OPENMP_LIT_ARGS "${DEFAULT_LIT_ARGS}" CACHE STRING "Options for lit.")
+    separate_arguments(OPENMP_LIT_ARGS)
+  else()
     message(STATUS "Cannot find 'FileCheck'.")
     message(WARNING "The check targets will not be available!")
     set(ENABLE_CHECK_TARGETS FALSE)
-  else()
-    set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_TOOLS_BINARY_DIR}/FileCheck)
   endif()
-  set(OPENMP_NOT_EXECUTABLE ${LLVM_TOOLS_BINARY_DIR}/not)
 endif()
 set(OFFLOAD_DEVICE_INFO_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-offload-device-info)
 set(OFFLOAD_TBLGEN_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/offload-tblgen)
@@ -211,7 +210,7 @@ function(add_offload_testsuite target comment)
     set_property(GLOBAL APPEND PROPERTY OPENMP_LIT_DEPENDS ${ARG_DEPENDS})
   endif()
 
-  if (${OPENMP_STANDALONE_BUILD})
+  if (NOT TARGET Clang)
     set(LIT_ARGS ${OPENMP_LIT_ARGS} ${ARG_ARGS})
     add_custom_target(${target}
       COMMAND ${Python3_EXECUTABLE} ${OPENMP_LLVM_LIT_EXECUTABLE} ${LIT_ARGS} ${ARG_UNPARSED_ARGUMENTS}
diff --git a/offload/test/CMakeLists.txt b/offload/test/CMakeLists.txt
index 711621de9075d..40da2a7d573ee 100644
--- a/offload/test/CMakeLists.txt
+++ b/offload/test/CMakeLists.txt
@@ -12,7 +12,7 @@ else()
   set(LIBOMPTARGET_DEBUG False)
 endif()
 
-if (NOT OPENMP_STANDALONE_BUILD AND "compiler-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+if ("compiler-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
   set(LIBOMPTARGET_TEST_GPU_PGO True)
 else()
   set(LIBOMPTARGET_TEST_GPU_PGO False)
diff --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt
index 44cef3fb3f413..d485bac10bae1 100644
--- a/openmp/CMakeLists.txt
+++ b/openmp/CMakeLists.txt
@@ -9,89 +9,50 @@ list(INSERT CMAKE_MODULE_PATH 0
   "${LLVM_COMMON_CMAKE_UTILS}/Modules"
   )
 
-# llvm/runtimes/ will set OPENMP_STANDALONE_BUILD.
-if (OPENMP_STANDALONE_BUILD OR "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
-  set(OPENMP_STANDALONE_BUILD TRUE)
-  project(openmp C CXX ASM)
-else()
-  set(OPENMP_STANDALONE_BUILD FALSE)
-endif()
-
 # Must go below project(..)
 include(GNUInstallDirs)
 
-if (OPENMP_STANDALONE_BUILD)
-  set(LLVM_TREE_AVAILABLE False)
+# Usually <llvm-project>/runtimes/CMakeLists.txt sets LLVM_TREE_AVAILABLE and
+# we assume it is not available otherwise. The exception is that we are in an
+# LLVM_ENABLE_PROJECTS=openmp build, the LLVM tree is actually available.
+# Note that this build mode has been deprecated.
+# See https://github.com/llvm/llvm-project/issues/124014
+if (NOT LLVM_RUNTIMES_BUILD AND "openmp" IN_LIST LLVM_ENABLE_PROJECTS)
+  set(LLVM_TREE_AVAILABLE True)
+endif ()
 
-  # CMAKE_BUILD_TYPE was not set, default to Release.
-  if (NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE Release)
-  endif()
+set(OPENMP_ENABLE_WERROR ${LLVM_ENABLE_WERROR})
 
-  # Group common settings.
-  set(OPENMP_ENABLE_WERROR FALSE CACHE BOOL
-    "Enable -Werror flags to turn warnings into errors for supporting compilers.")
-  set(OPENMP_LIBDIR_SUFFIX "" CACHE STRING
-    "Suffix of lib installation directory, e.g. 64 => lib64")
-  # Do not use OPENMP_LIBDIR_SUFFIX directly, use OPENMP_INSTALL_LIBDIR.
-  set(OPENMP_INSTALL_LIBDIR "lib${OPENMP_LIBDIR_SUFFIX}" CACHE STRING
+# When building in tree we install the runtime according to the LLVM settings.
+if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
+  set(OPENMP_INSTALL_LIBDIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING
+      "Path where built openmp libraries should be installed.")
+else()
+  set(OPENMP_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}" CACHE STRING
       "Path where built OpenMP libraries should be installed.")
+endif()
 
-  # Group test settings.
-  set(OPENMP_TEST_C_COMPILER ${CMAKE_C_COMPILER} CACHE STRING
-    "C compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING
-    "C++ compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_TEST_Fortran_COMPILER ${CMAKE_Fortran_COMPILER} CACHE STRING
-    "FORTRAN compiler to use for testing OpenMP runtime libraries.")
-  set(OPENMP_LLVM_TOOLS_DIR "" CACHE PATH "Path to LLVM tools for testing.")
-
-  set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
-  set(CMAKE_CXX_STANDARD_REQUIRED NO)
-  set(CMAKE_CXX_EXTENSIONS NO)
+if (NOT MSVC)
+  set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang)
+  set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++)
 else()
-  # Usually <llvm-project>/runtimes/CMakeLists.txt sets LLVM_TREE_AVAILABLE and
-  # we assume it is not available otherwise. The exception is that we are in an
-  # LLVM_ENABLE_PROJECTS=openmp build, the LLVM tree is actually available.
-  # Note that this build mode has been deprecated.
-  # See https://github.com/llvm/llvm-project/issues/124014
-  if (NOT LLVM_RUNTIMES_BUILD AND "openmp" IN_LIST LLVM_ENABLE_PROJECTS)
-    set(LLVM_TREE_AVAILABLE True)
-  endif ()
-
-  set(OPENMP_ENABLE_WERROR ${LLVM_ENABLE_WERROR})
-
-  # When building in tree we install the runtime according to the LLVM settings.
-  if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
-    set(OPENMP_INSTALL_LIBDIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING
-        "Path where built openmp libraries should be installed.")
-  else()
-    set(OPENMP_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}" CACHE STRING
-        "Path where built OpenMP libraries should be installed.")
-  endif()
-
-  if (NOT MSVC)
-    set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang)
-    set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++)
-  else()
-    set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang.exe)
-    set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++.exe)
-  endif()
-
-  # Set fortran test compiler if flang is found
-  if (EXISTS "${OPENMP_TEST_Fortran_COMPILER}")
-    message("Using local flang build at ${OPENMP_TEST_Fortran_COMPILER}")
-  else()
-    unset(OPENMP_TEST_Fortran_COMPILER)
-  endif()
+  set(OPENMP_TEST_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang.exe)
+  set(OPENMP_TEST_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++.exe)
+endif()
 
-  # If not standalone, set CMAKE_CXX_STANDARD but don't set the global cache value,
-  # only set it locally for OpenMP.
-  set(CMAKE_CXX_STANDARD 17)
-  set(CMAKE_CXX_STANDARD_REQUIRED NO)
-  set(CMAKE_CXX_EXTENSIONS NO)
+# Set fortran test compiler if flang is found
+if (EXISTS "${OPENMP_TEST_Fortran_COMPILER}")
+  message("Using local flang build at ${OPENMP_TEST_Fortran_COMPILER}")
+else()
+  unset(OPENMP_TEST_Fortran_COMPILER)
 endif()
 
+# If not standalone, set CMAKE_CXX_STANDARD but don't set the global cache value,
+# only set it locally for OpenMP.
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED NO)
+set(CMAKE_CXX_EXTENSIONS NO)
+
 # Check and set up common compiler flags.
 include(config-ix)
 include(HandleOpenMPOptions)
@@ -155,11 +116,8 @@ else()
     add_subdirectory(tools)
   endif()
 
-  # Propagate OMPT support to offload
-  if(NOT ${OPENMP_STANDALONE_BUILD})
-    set(LIBOMP_HAVE_OMPT_SUPPORT ${LIBOMP_HAVE_OMPT_SUPPORT} PARENT_SCOPE)
-    set(LIBOMP_OMP_TOOLS_INCLUDE_DIR ${LIBOMP_OMP_TOOLS_INCLUDE_DIR} PARENT_SCOPE)
-  endif()
+  set(LIBOMP_HAVE_OMPT_SUPPORT ${LIBOMP_HAVE_OMPT_SUPPORT} PARENT_SCOPE)
+  set(LIBOMP_OMP_TOOLS_INCLUDE_DIR ${LIBOMP_OMP_TOOLS_INCLUDE_DIR} PARENT_SCOPE)
 
   option(OPENMP_MSVC_NAME_SCHEME "Build dll with MSVC naming scheme." OFF)
 
diff --git a/openmp/cmake/OpenMPTesting.cmake b/openmp/cmake/OpenMPTesting.cmake
index 262ea968c8351..92d07f69563ba 100644
--- a/openmp/cmake/OpenMPTesting.cmake
+++ b/openmp/cmake/OpenMPTesting.cmake
@@ -49,28 +49,27 @@ function(find_standalone_test_dependencies)
   endif()
 endfunction()
 
-if (${OPENMP_STANDALONE_BUILD})
-  find_standalone_test_dependencies()
-
-  # Set lit arguments.
-  set(DEFAULT_LIT_ARGS "-sv --show-unsupported --show-xfail")
-  if (MSVC OR XCODE)
-    set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --no-progress-bar")
-  endif()
-  if ("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
-    set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --time-tests --timeout=3000")
-  endif()
-  set(OPENMP_LIT_ARGS "${DEFAULT_LIT_ARGS}" CACHE STRING "Options for lit.")
-  separate_arguments(OPENMP_LIT_ARGS)
+if(TARGET FileCheck)
+  set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck)
+  set(OPENMP_NOT_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/not)
 else()
-  if (NOT TARGET "FileCheck")
+  find_standalone_test_dependencies()
+  if(OPENMP_FILECHECK_EXECUTABLE)
+    # Set lit arguments.
+    set(DEFAULT_LIT_ARGS "-sv --show-unsupported --show-xfail")
+    if (MSVC OR XCODE)
+      set(DEFAULT_LIT_ARGS "${DEFAULT_LI...
[truncated]

@estewart08 estewart08 requested review from jhuber6 and mgorny December 4, 2025 16:54
Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the work here! Just one concern, and also we should probably try to be consistent with if () vs. if(). I think we prefer the latter.

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBOMPTARGET_LIBRARY_DIR})

if(NOT LLVM_LIBRARY_OUTPUT_INTDIR)
if(NOT LLVM_LIBRARY_OUTPUT_INTDIR OR NOT TARGET Clang)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have the clang target in a normal runtimes build? Will this modify where we put the files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the Clang target is present in the normal runtimes builds. It actually is in the deps list in runtimes/CMakeLists.txt. This prevents the standalone build from thinking the build tree is where llvm is currently installed.

@jprotze
Copy link
Collaborator

jprotze commented Dec 4, 2025

For a standalone build, it was sufficient to download the openmp src tarball and build the code: https://github.com/llvm/llvm-project/releases/tag/llvmorg-21.1.7

The documentation should explain, which source tarballs are necessary and sufficient for the new workflow and how we need to extract them

@mgorny
Copy link
Member

mgorny commented Dec 4, 2025

How is it supposed to work? FWICS llvm_gtest target requires find_package(LLVM) to succeed but the runtimes CMakeLists has only:

find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

which cannot succeed because LLVM_BINARY_DIR is empty and NO_DEFAULT_PATH suppresses any way to specify the correct path.

Summary:
We have supported standalone builds in the past, but these should likely
all go through the LLVM runtimes handling instead. This simplifies a lot
of leftover code and opens the way for future cleanups. Offload directly
depends on LLVM so this makes even more sense, but already several
runtimes projects don't allow these sorts of standalone builds (libc,
libcxx).

Co-authored-by: Joseph Huber <joseph.huber@amd.com>
@estewart08 estewart08 force-pushed the remove-openmp-standalone-support branch from 62dadf3 to 19e14c2 Compare December 4, 2025 20:00
@estewart08
Copy link
Contributor Author

How is it supposed to work? FWICS llvm_gtest target requires find_package(LLVM) to succeed but the runtimes CMakeLists has only:

find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

which cannot succeed because LLVM_BINARY_DIR is empty and NO_DEFAULT_PATH suppresses any way to specify the correct path.

See https://github.com/llvm/llvm-project/pull/170693/files#diff-f55c23c16cfc0dfde75afe6d6fe297481ed8e9221a0041360ee14ec70030a44fR100

The new 'standalone' runtimes method would require additional cmake options, LLVM_BINARY_DIR being one of them. Maybe those should be mentioned in the commit message. I wonder if a we should add a fatal error if it is not set.

@jhuber6
Copy link
Contributor

jhuber6 commented Dec 5, 2025

The offloading runtime is unique because it relies on the LLVM binary directory, whereas most others can be built standalone. There's already a case where we do find_package(LLVM) in the runtimes handling but it's not a requirement. We could probably add some more useful diagnostic there, like if someone's enabled offloading and we can't find LLVM we suggest setting that and fatal error.

Another issue with the offloading build is that we rely on a tablegen tool for the liboffload part, which means we can't do real cross-compiling like runtimes implies. This should probably be moved to LLVM and just built by default. It should hopefully show up in the NATIVE directory and we can fish it out from there.

@mgorny
Copy link
Member

mgorny commented Dec 5, 2025

The new 'standalone' runtimes method would require additional cmake options, LLVM_BINARY_DIR being one of them. Maybe those should be mentioned in the commit message. I wonder if a we should add a fatal error if it is not set.

But isn't LLVM_BINARY_DIR used as an output directory in a bunch of macros? I can try overriding it in a few minutes, but I do wonder if that's not going to cause the build system to try writing into the live system.

@mgorny
Copy link
Member

mgorny commented Dec 5, 2025

Okay, openmp built now but a number of tests are failing over looking for FileCheck in the wrong directory:

FAIL: libomp :: transform/reverse/parallel-wsloop-collapse-foreach.cpp (431 of 463)
******************** TEST 'libomp :: transform/reverse/parallel-wsloop-collapse-foreach.cpp' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
/usr/lib/llvm/22/bin/clang++ -fopenmp   -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/
src -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test -L /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/
work/runtimes_build-.arm64/openmp/runtime/src  -fno-omit-frame-pointer -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp
/runtime/test/ompt -std=c++20 /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsl
oop-collapse-foreach.cpp -o /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/test/transform/
reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp -lm -latomic && /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes
_build-.arm64/openmp/runtime/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp | tee /var/tmp/portage/llvm-runtime
s/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp.o
ut | /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck /var/tmp/portage/llvm-runtimes/openmp
-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsloop-collapse-foreach.cpp --match-full-lines
# executed command: /usr/lib/llvm/22/bin/clang++ -fopenmp -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm
64/openmp/runtime/src -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test -L /var/tmp/portage/llvm-runtimes/o
penmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/src -fno-omit-frame-pointer -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0
.9999/work/openmp/runtime/test/ompt -std=c++20 /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/rev
erse/parallel-wsloop-collapse-foreach.cpp -o /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtim
e/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp -lm -latomic
# executed command: /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck /var/tmp/portage/llvm-
runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsloop-collapse-foreach.cpp --match-full-lines
# .---command stderr------------
# | '/var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck': command not found
# `-----------------------------
# error: command failed with exit status: 127

@mgorny
Copy link
Member

mgorny commented Dec 5, 2025

For offload, I'm getting:

CMake Error at /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/plugins-nextgen/common/CMakeLists.txt:20 (add_dependencies):
  The dependency target "intrinsics_gen" of target "PluginCommon" does not
  exist.

@estewart08
Copy link
Contributor Author

Okay, openmp built now but a number of tests are failing over looking for FileCheck in the wrong directory:

FAIL: libomp :: transform/reverse/parallel-wsloop-collapse-foreach.cpp (431 of 463)
******************** TEST 'libomp :: transform/reverse/parallel-wsloop-collapse-foreach.cpp' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
/usr/lib/llvm/22/bin/clang++ -fopenmp   -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/
src -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test -L /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/
work/runtimes_build-.arm64/openmp/runtime/src  -fno-omit-frame-pointer -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp
/runtime/test/ompt -std=c++20 /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsl
oop-collapse-foreach.cpp -o /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/test/transform/
reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp -lm -latomic && /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes
_build-.arm64/openmp/runtime/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp | tee /var/tmp/portage/llvm-runtime
s/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp.o
ut | /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck /var/tmp/portage/llvm-runtimes/openmp
-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsloop-collapse-foreach.cpp --match-full-lines
# executed command: /usr/lib/llvm/22/bin/clang++ -fopenmp -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm
64/openmp/runtime/src -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test -L /var/tmp/portage/llvm-runtimes/o
penmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtime/src -fno-omit-frame-pointer -I /var/tmp/portage/llvm-runtimes/openmp-22.0.0
.9999/work/openmp/runtime/test/ompt -std=c++20 /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/rev
erse/parallel-wsloop-collapse-foreach.cpp -o /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/openmp/runtim
e/test/transform/reverse/Output/parallel-wsloop-collapse-foreach.cpp.tmp -lm -latomic
# executed command: /var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck /var/tmp/portage/llvm-
runtimes/openmp-22.0.0.9999/work/openmp/runtime/test/transform/reverse/parallel-wsloop-collapse-foreach.cpp --match-full-lines
# .---command stderr------------
# | '/var/tmp/portage/llvm-runtimes/openmp-22.0.0.9999/work/runtimes_build-.arm64/./bin/FileCheck': command not found
# `-----------------------------
# error: command failed with exit status: 127

You most likely need to set -DOPENMP_LLVM_TOOLS_DIR=<PATH> during the build, which is where FileCheck and lit testing tools live. By default FileCheck is not installed unless you tell the build to do so, meaning the PATH might be to your build directory.

@estewart08
Copy link
Contributor Author

For offload, I'm getting:

CMake Error at /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/plugins-nextgen/common/CMakeLists.txt:20 (add_dependencies):
  The dependency target "intrinsics_gen" of target "PluginCommon" does not
  exist.

Huh, I was not seeing that locally. What was your cmake command?

@mgorny
Copy link
Member

mgorny commented Dec 5, 2025

You most likely need to set -DOPENMP_LLVM_TOOLS_DIR=<PATH> during the build, which is where FileCheck and lit testing tools live.

That doesn't work, and CMake indicates it isn't used:

CMake Warning:
  Manually-specified variables were not used by the project:

    OPENMP_LIBDIR_SUFFIX
    OPENMP_LLVM_TOOLS_DIR
    OPENMP_STANDALONE_BUILD

(ignore the other two, they're leftovers from old standalone build)

@mgorny
Copy link
Member

mgorny commented Dec 5, 2025

For offload, I'm getting:

CMake Error at /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/plugins-nextgen/common/CMakeLists.txt:20 (add_dependencies):
  The dependency target "intrinsics_gen" of target "PluginCommon" does not
  exist.

Huh, I was not seeing that locally. What was your cmake command?

cmake -C /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/gentoo_common_config.cmake
 -G Ninja
 -DCMAKE_INSTALL_PREFIX=/usr
 -DLLVM_ENABLE_RUNTIMES=offload
 -DOPENMP_STANDALONE_BUILD=ON
 -DOFFLOAD_LIBDIR_SUFFIX=64
 -DLLVM_ROOT=/usr/lib/llvm/22
 -DLLVM_BINARY_DIR=/usr/lib/llvm/22/bin
 -DOFFLOAD_INCLUDE_TESTS=yes
 -DLIBOMPTARGET_PLUGINS_TO_BUILD="host;cuda"
 -DLIBOMPTARGET_OMPT_SUPPORT=no
 -DBUILD_SHARED_LIBS=OFF
 -DLIBOMPTARGET_AMDGPU_ARCH=LIBOMPTARGET_AMDGPU_ARCH-NOTFOUND
 -DLIBOMPTARGET_NVPTX_ARCH=LIBOMPTARGET_NVPTX_ARCH-NOTFOUND
 -DOPENMP_LLVM_LIT_EXECUTABLE=/usr/bin/lit
 -DOPENMP_LIT_ARGS="-vv;-j;96"
 -DOPENMP_TEST_C_COMPILER=/usr/lib/ccache/bin/aarch64-unknown-
linux-gnu-clang
 -DOPENMP_TEST_CXX_COMPILER=/usr/lib/ccache/bin/aarch64-unknown-linux-gnu-clang++
 -DOPENMP_TEST_Fortran_COMPILER=
 -DCMAKE_BUILD_TYPE=RelWithDebInfo
 -DCMAKE_TOOLCHAIN_FILE=/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/gentoo_toolchain.cmake
 /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes

(I've broken lines for readability)

@shiltian
Copy link
Contributor

shiltian commented Dec 6, 2025

I don’t think we should drop standalone builds. Many users of libomp don't care about offloading at all, so losing the ability to build it standalone would definitely be a step backward.

@kevinsala
Copy link
Contributor

Rust colleagues rely on standalone builds for their offloading extensions (see rust-lang/rust#148671).

CC @ZuseZ4

@ZuseZ4
Copy link

ZuseZ4 commented Dec 8, 2025

Yep, just for context from the Rust side. We have a lot of builders in CI, but the slowest one we have is the x86 dist builder, which we use to e.g. create compiler artifacts. We already build LLVM there around 4 times due to PGO and Bolt, so we really try hard not to make it any slower, since we are already at ~3.5 hrs, and we run this CI before any merge into main.

One of the compromises there is that we have two checkouts of LLVM - once as a standalone llvm/llvm-project build (A) and once as a submodule of rustc in src/tools/llvm-project. We use build A to compile C/C++ code, and keep rebuilding the second checkout (B) during bootstrapping.
We only build clang as part of our LLVM Build A. However, rustc is based on LLVM B, and as such we'd also want the openmp and offload libraries to also be part of our LLVM Build B, which does not build the in-tree clang to save compile times.

We've tried for quite a bit to get the runtimes to build despite no in-tree clang or lld in LLVM B, and failed, I'm happy to share all the issues I ran into there. A standalone build instead allows me to use clang from build A to build offload+openmp from checkout B, that's compatible with what we have in rustc. So until that is fixed, standalone builds are likely the only builds that our infra team would be ok with.

@jhuber6
Copy link
Contributor

jhuber6 commented Dec 8, 2025

This removes the 'standalone' builds, not the ability to build these projects individually. The following two should be equivalent. The only significant difference is that the first only requires the openmp directory while the other requires an LLVM checkout. I think it's reasonable to require an LLVM checkout for these always.

$ cmake ../openmp
$ cmake ../runtimes -DLLVM_ENABLE_RUNTIMES=openmp

@shiltian
Copy link
Contributor

shiltian commented Dec 8, 2025

I recommend removing standalone build for libomptarget, and still keep libomp as it is. libomp doesn't depend on LLVM anyway, except those very limited feature(s) that are rarely used.

@jhuber6
Copy link
Contributor

jhuber6 commented Dec 8, 2025

I recommend removing standalone build for libomptarget, and still keep libomp as it is. libomp doesn't depend on LLVM anyway, except those very limited feature(s) that are rarely used.

That'd be fine, offload doesn't make sense without LLVM anyway because it depends on it

Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with removing both, it's much easier to constrain the different configurations we need to test. If anyone out there is still relying on a dedicated checkout of OpenMP they should either move to the new format (You need runtimes, llvm, and openmp instead of just openmp directories) or write some convincing arguments for why we should keep both of them.

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

I'd be fine with removing it if it didn't break runtimes build for me. However, unless anything changed since #170693 (comment), it does.

@jhuber6
Copy link
Contributor

jhuber6 commented Jan 7, 2026

I'd be fine with removing it if it didn't break runtimes build for me. However, unless anything changed since #170693 (comment), it does.

Usually for me to get it to work I need to put -DLLVM_BINARY_DIR=$DIR/llvm-project/build or whatever else is the root of your LLVM tree. Does that not work for you?

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

I don't have a build tree. That's the whole point of building standalone. And the installed binary tree doesn't work.

@jhuber6
Copy link
Contributor

jhuber6 commented Jan 7, 2026

I don't have a build tree. That's the whole point of building standalone. And the installed binary tree doesn't work.

You need LLVM for offload to work in the first place, but openmp should be fine.

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

Yes, I have installed LLVM and the runtimes build against installed LLVM works just fine without this patch. With this patch, it's broken — either with my "old" setup or with LLVM_BINARY_DIR set as discussed above.

@jhuber6
Copy link
Contributor

jhuber6 commented Jan 7, 2026

Yes, I have installed LLVM and the runtimes build against installed LLVM works just fine without this patch. With this patch, it's broken — either with my "old" setup or with LLVM_BINARY_DIR set as discussed above.

You're setting it wrong if you're referring to this:

 -DLLVM_BINARY_DIR=/usr/lib/llvm/22/bin

You probably meant this unless I'm missing something, see usage https://github.com/llvm/llvm-project/blob/main/runtimes/CMakeLists.txt#L68

 -DLLVM_BINARY_DIR=/usr/lib/llvm/22

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

Okay, sorry about that. Now it builds but the majority of tests fails with the same kind of error:

FAIL: libomptarget :: aarch64-unknown-linux-gnu :: offloading/complex_reduction.cpp (859 of 864)
******************** TEST 'libomptarget :: aarch64-unknown-linux-gnu :: offloading/complex_reduction.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/usr/lib/llvm/22/bin/clang++    -I /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test -I  -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /usr/lib/llvm/22/lib64  -nogpulib -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath, -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath,/usr/lib/llvm/22/lib64  -fopenmp-targets=aarch64-unknown-linux-gnu /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test/offloading/complex_reduction.cpp -o /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp -O3 && /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp
# executed command: /usr/lib/llvm/22/bin/clang++ -I /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test -I -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /usr/lib/llvm/22/lib64 -nogpulib -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath, -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath,/usr/lib/llvm/22/lib64 -fopenmp-targets=aarch64-unknown-linux-gnu /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test/offloading/complex_reduction.cpp -o /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp -O3
# .---command stderr------------
# | /usr/bin/aarch64-unknown-linux-gnu-ld.bfd: read in flex scanner failed
# | clang++: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

They pass with the same CMake parameters, without the patch.

@Meinersbur
Copy link
Member

Meinersbur commented Jan 7, 2026

The only significant difference is that the first only requires the openmp directory while the other requires an LLVM checkout. I think it's reasonable to require an LLVM checkout for these always.

We have shared code third-party/ and cmake/. The former is used by openmp since #147381. The latter since at least https://reviews.llvm.org/D148798. Checking out only openmp/ does not work since at least 2023 and nobody complained.

I recommend removing standalone build for libomptarget, and still keep libomp as it is. libomp doesn't depend on LLVM anyway, except those very limited feature(s) that are rarely used.

The primary motivation is reducing build complexity. We have 4 modes how to build OpenMP:

  • cmake <llvm-project>/llvm -DLLVM_ENABLE_PROJECTS=openmp ([OpenMP] Remove LLVM_ENABLE_PROJECTS=openmp build mode #152189)
  • cmake <llvm-project>/llvm -DLLVM_ENABLE_RUNTIMES=openmp (bootstrapping build)
  • cmake <llvm-project>/openmp (standalone build)
  • cmake <llvm-project>/runtimes -DLLVM_ENABLE_RUNTIMES=openmp (runtimes default build)

The bootstrapping build serves the same purpose as the LLVM_ENABLE_PROJECTS=openmp build, but also considers cross-compilation workflows.

The runtimes default build serves the same purpose as the standalone build. Just replace -S <llvm-project>/openmp with -S <llvm-project>/runtimes -DLLVM_ENABLE_RUNTIMES=openmp in your cmake line; NOTHING ELSE NEEDS TO BE CHANGED, specifically all the cmake options remain the same.

We should not have to maintain build modes which are redundant, not tested with out CI infrastructures, different in subtle ways, constantly break when touch a CMakeLists.txt and thus must be tested manually. Few contributors actually do which means openmp/offload is broken in most modes (such as observed in this very PR). In the past LLVM already had to maintain two build redundant systems: and autoconf-based and a cmake-based one and everyone was glad when the requirement to maintain two build systems was gone. See https://discourse.llvm.org/t/rfc-llvm-build-system-future-direction/53430 for a previous effort on reducing the combinatorial explosion of build configurations. I am often thinking about cleaning up openmp's CMake code, but having to keep so many build modes working stops me from doing it.

Btw, the original RFC for LLVM_ENABLE_RUNTIMES explicitly states

  1. Deprecate the old individual Standalone builds for this new "Unified Standalone build".

@Meinersbur
Copy link
Member

How is it supposed to work? FWICS llvm_gtest target requires find_package(LLVM) to succeed but the runtimes CMakeLists has only:

find_package(LLVM PATHS "${LLVM_BINARY_DIR}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

which cannot succeed because LLVM_BINARY_DIR is empty and NO_DEFAULT_PATH suppresses any way to specify the correct path.

For llvm_gtest specifically, it should use default_gtest instead. It either uses llvm_gtest if the find_package(LLVM) has found a build tree, an install tree if LLVM_INSTALL_GTREST=ON, or runtimes_gtest in an LLVM_ENABLE_RUNTIMES build, which adds thirdparty/googletest itself. Also see #159416.

@jhuber6
Copy link
Contributor

jhuber6 commented Jan 7, 2026

Okay, sorry about that. Now it builds but the majority of tests fails with the same kind of error:

FAIL: libomptarget :: aarch64-unknown-linux-gnu :: offloading/complex_reduction.cpp (859 of 864)
******************** TEST 'libomptarget :: aarch64-unknown-linux-gnu :: offloading/complex_reduction.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/usr/lib/llvm/22/bin/clang++    -I /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test -I  -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /usr/lib/llvm/22/lib64  -nogpulib -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath, -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath,/usr/lib/llvm/22/lib64  -fopenmp-targets=aarch64-unknown-linux-gnu /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test/offloading/complex_reduction.cpp -o /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp -O3 && /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp
# executed command: /usr/lib/llvm/22/bin/clang++ -I /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test -I -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -L /usr/lib/llvm/22/lib64 -nogpulib -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath, -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload -Wl,-rpath,/usr/lib/llvm/22/lib64 -fopenmp-targets=aarch64-unknown-linux-gnu /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test/offloading/complex_reduction.cpp -o /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp -O3
# .---command stderr------------
# | /usr/bin/aarch64-unknown-linux-gnu-ld.bfd: read in flex scanner failed
# | clang++: error: linker command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

They pass with the same CMake parameters, without the patch.

That's weird, can you reproduce it if you invoke the compiler command manually? We use lld for a lot of things as well which hid a few issues.

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

Comparing the command without (-) and with (+) the patch (spaces replaced with newlines):

-/usr/lib/ccache/bin/aarch64-unknown-linux-gnu-clang++
--fopenmp
+/usr/lib/llvm/22/bin/clang++
 
 
 
 -I
 /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/offload/test
 -I
-/usr/include
+
 -L
 /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload
 -L
-/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/./lib64
+/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload
 -L
 /usr/lib/llvm/22/lib64
--L
-/usr/lib64
 
 -nogpulib
 -Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload
--Wl,-rpath,/usr/lib64
--Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/./lib64
+-Wl,-rpath,
+-Wl,-rpath,/var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload
 -Wl,-rpath,/usr/lib/llvm/22/lib64
 
 -fopenmp-targets=aarch64-unknown-linux-gnu
@@ -29,5 +26,3 @@
 -O3
 &&
 /var/tmp/portage/llvm-runtimes/offload-22.0.0.9999/work/runtimes_build/offload/test/aarch64-unknown-linux-gnu/offloading/Output/complex_reduction.cpp.tmp

So, it's missing -fopenmp and getting a bunch of empty paths that are messing up options.

@mgorny
Copy link
Member

mgorny commented Jan 7, 2026

…and that would be because all the logic for finding installed openmp library/headers is removed.

@jhuber6
Copy link
Contributor

jhuber6 commented Jan 7, 2026

…and that would be because all the logic for finding installed openmp library/headers is removed.

That'd do it, I suppose we still want to use DetectTestCompiler in this case? It could be either in a default runtimes build.

@Meinersbur
Copy link
Member

Should we maybe split then OpenMP part and the Offload part? The OpenMP runtimes default build does work with #149878 while the Offload runtimes default build is being fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

offload openmp:libomp OpenMP host runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants