[clang] [llvm] [mlir] [CMake] Add dependent project mode for Flang's MLIR (PR #221724)
Mehdi Amini via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 15:50:57 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/221724
>From 9ef6e4c2fa761f6f4ef0f6bd78411e7a9231d8a3 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Mon, 7 Sep 2026 06:11:56 -0700
Subject: [PATCH] [CMake] Infer dependency-only projects from the cache
LLVM_ENABLE_PROJECTS historically treats projects enabled to satisfy another
project's dependency the same as projects selected by the user. Consequently,
implicit projects attach their complete build, install, and test suites to
LLVM's aggregate targets.
Keep the cache entry as the user-requested project roots and use the normal
LLVM_ENABLE_PROJECTS variable as the effective dependency closure. Projects in
the effective list but not the cache entry are configured with
EXCLUDE_FROM_ALL. Normalize the special all value before comparing the two
sets.
This makes Flang's MLIR and Clang dependencies dependency-only without a
second project collection. It also applies the same rule to Clang when it is
added for LLDB. Forward the cached roots to cross-compilation and bootstrap
configurations so implicit projects do not become explicit in nested builds.
Let MLIR own its dependency-only test policy: configure its complete test tree
so check-mlir remains available, but exclude MLIR test execution and build
dependencies from check-all. Explicitly enabling MLIR preserves the existing
behavior.
Validation:
- Configured Flang with implicit MLIR test support.
- Configured Flang and MLIR explicitly with tests enabled.
- Configured LLVM_ENABLE_PROJECTS=all with tests disabled.
- Verified implicit mode exposes check-flang and check-mlir while check-all
runs Flang but not MLIR.
- Verified explicit mode includes MLIR tests in check-all.
Assisted-by: Codex
---
clang/CMakeLists.txt | 5 ++++-
llvm/CMakeLists.txt | 22 ++++++++++++++++++----
llvm/cmake/modules/AddLLVM.cmake | 14 ++++++++++++--
llvm/cmake/modules/CrossCompile.cmake | 2 +-
mlir/CMakeLists.txt | 14 ++++++++++++++
mlir/test/CMakeLists.txt | 1 +
mlir/test/python/CMakeLists.txt | 1 +
7 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index fc71cf45dbb34..6977458da67e9 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -851,7 +851,10 @@ if (CLANG_ENABLE_BOOTSTRAP)
# Populate the passthrough variables
foreach(variableName ${CLANG_BOOTSTRAP_PASSTHROUGH} ${_BOOTSTRAP_DEFAULT_PASSTHROUGH})
if(DEFINED ${variableName})
- if("${${variableName}}" STREQUAL "")
+ if(variableName STREQUAL "LLVM_ENABLE_PROJECTS" AND
+ DEFINED CACHE{LLVM_ENABLE_PROJECTS})
+ string(REPLACE ";" "|" value "$CACHE{LLVM_ENABLE_PROJECTS}")
+ elseif("${${variableName}}" STREQUAL "")
set(value "")
else()
string(REPLACE ";" "|" value "${${variableName}}")
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 44299d51d784a..b4a99a60b97a5 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -270,6 +270,15 @@ if(LIBOMP_ENABLE_ARM64X)
set(RUNTIMES_arm64ec-pc-windows-msvc_LIBOMP_ENABLE_ARM64X ON)
endif()
+list(REMOVE_DUPLICATES LLVM_ENABLE_PROJECTS)
+
+# The cache entry contains the projects explicitly requested by the user, while
+# LLVM_ENABLE_PROJECTS may also contain projects added to satisfy dependencies.
+set(llvm_explicit_projects "$CACHE{LLVM_ENABLE_PROJECTS}")
+if(llvm_explicit_projects STREQUAL "all")
+ set(llvm_explicit_projects ${LLVM_ALL_PROJECTS})
+endif()
+
# LLVM_ENABLE_PROJECTS_USED is `ON` if the user has ever used the
# `LLVM_ENABLE_PROJECTS` CMake cache variable. This exists for
# several reasons:
@@ -293,7 +302,11 @@ if (LLVM_ENABLE_PROJECTS_USED OR NOT LLVM_ENABLE_PROJECTS STREQUAL "")
string(TOUPPER "${proj}" upper_proj)
string(REGEX REPLACE "-" "_" upper_proj ${upper_proj})
if ("${proj}" IN_LIST LLVM_ENABLE_PROJECTS)
- message(STATUS "${proj} project is enabled")
+ if ("${proj}" IN_LIST llvm_explicit_projects)
+ message(STATUS "${proj} project is enabled")
+ else()
+ message(STATUS "${proj} project is enabled as a dependency")
+ endif()
set(SHOULD_ENABLE_PROJECT TRUE)
set(PROJ_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${proj}")
if(NOT EXISTS "${PROJ_DIR}" OR NOT IS_DIRECTORY "${PROJ_DIR}")
@@ -312,9 +325,9 @@ if (LLVM_ENABLE_PROJECTS_USED OR NOT LLVM_ENABLE_PROJECTS STREQUAL "")
set(SHOULD_ENABLE_PROJECT FALSE)
endif()
# Force `LLVM_TOOL_${upper_proj}_BUILD` variables to have values that
- # corresponds with `LLVM_ENABLE_PROJECTS`. This prevents the user setting
- # `LLVM_TOOL_${upper_proj}_BUILD` variables externally. At some point
- # we should deprecate allowing users to set these variables by turning them
+ # correspond with `LLVM_ENABLE_PROJECTS`. This prevents the user setting
+ # `LLVM_TOOL_${upper_proj}_BUILD` variables externally. At some point we
+ # should deprecate allowing users to set these variables by turning them
# into normal CMake variables rather than cache variables.
set(LLVM_TOOL_${upper_proj}_BUILD
${SHOULD_ENABLE_PROJECT}
@@ -324,6 +337,7 @@ if (LLVM_ENABLE_PROJECTS_USED OR NOT LLVM_ENABLE_PROJECTS STREQUAL "")
endforeach()
endif()
unset(SHOULD_ENABLE_PROJECT)
+unset(llvm_explicit_projects)
# Build llvm with ccache if the package is present
set(LLVM_CCACHE_BUILD OFF CACHE BOOL "Set to ON for a ccache enabled build")
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index a267166eb6c2d..a35027cb9b884 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -1762,6 +1762,14 @@ function(add_llvm_subdirectory project type name)
if("${add_llvm_external_dir}" STREQUAL "")
set(add_llvm_external_dir ${name})
endif()
+ set(llvm_explicit_projects "$CACHE{LLVM_ENABLE_PROJECTS}")
+ if(llvm_explicit_projects STREQUAL "all")
+ set(llvm_explicit_projects ${LLVM_ALL_PROJECTS})
+ endif()
+ if("${name}" IN_LIST LLVM_ENABLE_PROJECTS AND
+ NOT "${name}" IN_LIST llvm_explicit_projects)
+ set(exclude_from_all EXCLUDE_FROM_ALL)
+ endif()
canonicalize_tool_name(${name} nameUPPER)
set(canonical_full_name ${project}_${type}_${nameUPPER})
get_property(already_processed GLOBAL PROPERTY ${canonical_full_name}_PROCESSED)
@@ -1776,7 +1784,8 @@ function(add_llvm_subdirectory project type name)
"Whether to build ${name} as part of ${project}" On)
mark_as_advanced(${project}_${type}_${name}_BUILD)
if(${canonical_full_name}_BUILD)
- add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir} ${add_llvm_external_dir})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}
+ ${add_llvm_external_dir} ${exclude_from_all})
endif()
else()
set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR
@@ -1794,7 +1803,8 @@ function(add_llvm_subdirectory project type name)
${${canonical_full_name}_BUILD_DEFAULT})
if (${canonical_full_name}_BUILD)
if(EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})
- add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})
+ add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}
+ ${add_llvm_external_dir} ${exclude_from_all})
elseif(NOT "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "")
message(WARNING "Nonexistent directory for ${name}: ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}")
endif()
diff --git a/llvm/cmake/modules/CrossCompile.cmake b/llvm/cmake/modules/CrossCompile.cmake
index 28fb430dc98e1..153d77e454d47 100644
--- a/llvm/cmake/modules/CrossCompile.cmake
+++ b/llvm/cmake/modules/CrossCompile.cmake
@@ -67,7 +67,7 @@ function(llvm_create_cross_target project_name target_name toolchain buildtype)
"${LLVM_EXPERIMENTAL_TARGETS_TO_BUILD}")
string(REPLACE ";" "$<SEMICOLON>" llvm_enable_projects_arg
- "${LLVM_ENABLE_PROJECTS}")
+ "$CACHE{LLVM_ENABLE_PROJECTS}")
string(REPLACE ";" "$<SEMICOLON>" llvm_external_projects_arg
"${LLVM_EXTERNAL_PROJECTS}")
string(REPLACE ";" "$<SEMICOLON>" llvm_enable_runtimes_arg
diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt
index 7bedfe09e798a..b8c6e24ac6291 100644
--- a/mlir/CMakeLists.txt
+++ b/mlir/CMakeLists.txt
@@ -263,6 +263,19 @@ add_subdirectory(lib/CAPI)
if (MLIR_INCLUDE_TESTS)
add_definitions(-DMLIR_INCLUDE_TESTS)
+ set(MLIR_TEST_EXCLUDE_FROM_CHECK_ALL)
+ set(mlir_explicit_projects "$CACHE{LLVM_ENABLE_PROJECTS}")
+ if(mlir_explicit_projects STREQUAL "all")
+ set(mlir_explicit_projects ${LLVM_ALL_PROJECTS})
+ endif()
+ if ("mlir" IN_LIST LLVM_ENABLE_PROJECTS AND
+ NOT "mlir" IN_LIST mlir_explicit_projects)
+ # Keep MLIR's test targets available to dependent projects without adding
+ # them to check-all.
+ set(MLIR_TEST_EXCLUDE_FROM_CHECK_ALL EXCLUDE_FROM_CHECK_ALL)
+ endif()
+ unset(mlir_explicit_projects)
+
add_custom_target(MLIRUnitTests)
set_target_properties(MLIRUnitTests PROPERTIES FOLDER "MLIR/Tests")
if (TARGET llvm_gtest)
@@ -271,6 +284,7 @@ if (MLIR_INCLUDE_TESTS)
message(WARNING "gtest not found, unittests will not be available")
endif()
add_subdirectory(test)
+ unset(MLIR_TEST_EXCLUDE_FROM_CHECK_ALL)
endif()
# Tools needs to come late to ensure that MLIR_ALL_LIBS is populated.
# Generally things after this point may depend on MLIR_ALL_LIBS or libMLIR.so.
diff --git a/mlir/test/CMakeLists.txt b/mlir/test/CMakeLists.txt
index 1603f03558ee7..9a10128379488 100644
--- a/mlir/test/CMakeLists.txt
+++ b/mlir/test/CMakeLists.txt
@@ -280,6 +280,7 @@ set_target_properties(check-mlir-build-only PROPERTIES FOLDER "MLIR/Tests")
add_lit_testsuite(check-mlir "Running the MLIR regression tests"
${CMAKE_CURRENT_BINARY_DIR}
+ ${MLIR_TEST_EXCLUDE_FROM_CHECK_ALL}
DEPENDS ${MLIR_TEST_DEPENDS}
)
diff --git a/mlir/test/python/CMakeLists.txt b/mlir/test/python/CMakeLists.txt
index c81f75fc6a1af..b91a7104004df 100644
--- a/mlir/test/python/CMakeLists.txt
+++ b/mlir/test/python/CMakeLists.txt
@@ -17,5 +17,6 @@ if(NOT MLIR_STANDALONE_BUILD)
endif()
add_lit_testsuite(check-mlir-python "Running the MLIR Python regression tests"
${CMAKE_CURRENT_BINARY_DIR}
+ ${MLIR_TEST_EXCLUDE_FROM_CHECK_ALL}
DEPENDS ${MLIR_PYTHON_TEST_DEPENDS}
)
More information about the cfe-commits
mailing list