Skip to content

[mlir][cmake] Respect MLIR_TABLEGEN_EXE overrides in MLIRConfig.cmake#189918

Open
Acture wants to merge 1 commit into
llvm:mainfrom
Acture:fix/mlir-tablegen-exe-override
Open

[mlir][cmake] Respect MLIR_TABLEGEN_EXE overrides in MLIRConfig.cmake#189918
Acture wants to merge 1 commit into
llvm:mainfrom
Acture:fix/mlir-tablegen-exe-override

Conversation

@Acture
Copy link
Copy Markdown
Contributor

@Acture Acture commented Apr 1, 2026

Fixes #150986. Supersedes #150987.

Problem

MLIRConfig.cmake.in unconditionally overwrites MLIR_TABLEGEN_EXE (line 12), discarding user-provided -DMLIR_TABLEGEN_EXE=... overrides. For the install tree, the value becomes the bare name mlir-tblgen (not an absolute path). When MLIRTargets.cmake fails to define the corresponding imported target — as happens in Nix sandboxed builds where the binary is in a separate store path — TableGen.cmake passes the bare string into add_custom_command(DEPENDS ...), where CMake treats it as a relative file path:

ninja: error: 'include/flang/Optimizer/Dialect/CUF/Attributes/mlir-tblgen',
needed by '...CUFEnumAttr.h.inc', missing and no known rule to make it

Additionally, MLIR_TABLEGEN_TARGET is never exported by MLIRConfig.cmake, so TableGen.cmake has no target to track for dependency rebuilds.

Fix

All changes are in mlir/cmake/modules/MLIRConfig.cmake.in:

  1. Make MLIR_TABLEGEN_EXE (and siblings) conditional — respect user overrides
  2. Resolve bare names to full paths via find_program with HINTS "${LLVM_TOOLS_BINARY_DIR}"
  3. Create an imported mlir-tblgen target as fallback when MLIRTargets.cmake doesn't provide one
  4. Set MLIR_TABLEGEN_TARGET so TableGen.cmake has a proper target for DEPENDS

This replaces the previous workaround in flang/CMakeLists.txt (#150987) with a fix at the source — any downstream project using find_package(MLIR) benefits.

Reproduction

No Nix required. Configure LLVM+MLIR (no build needed), assemble a fake install tree, then run a minimal test project with -DMLIR_TABLEGEN_EXE=/some/path:

-- >>> Before find_package(MLIR):
-- >>>   MLIR_TABLEGEN_EXE = '/nix/store/fake/bin/mlir-tblgen'

-- >>> After find_package(MLIR):
-- >>>   MLIR_TABLEGEN_EXE    = 'mlir-tblgen'        ← override lost!
-- >>>   MLIR_TABLEGEN_TARGET = ''                    ← never set!

CMake Error: BUG REPRODUCED!
  MLIR_TABLEGEN_EXE = 'mlir-tblgen' — bare name, not absolute, not a target.
  The user-provided override was silently discarded by MLIRConfig.cmake.

Full reproduction steps in #150986.

MLIRConfig.cmake.in unconditionally overwrites MLIR_TABLEGEN_EXE,
discarding user-provided overrides. For the install tree, it sets the
value to the bare name "mlir-tblgen", which CMake then misinterprets
as a relative file path in add_custom_command(DEPENDS).

This patch:
- Makes MLIR_TABLEGEN_EXE (and siblings) conditional, respecting overrides
- Resolves bare names to full paths via find_program
- Creates an imported mlir-tblgen target as fallback for TableGen.cmake
- Sets MLIR_TABLEGEN_TARGET (never previously exported)
- Removes the previous workaround from flang/CMakeLists.txt

Fixes llvm#150986
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 1, 2026

@llvm/pr-subscribers-mlir

Author: acture (Acture)

Changes

Fixes #150986. Supersedes #150987.

Problem

MLIRConfig.cmake.in unconditionally overwrites MLIR_TABLEGEN_EXE (line 12), discarding user-provided -DMLIR_TABLEGEN_EXE=... overrides. For the install tree, the value becomes the bare name mlir-tblgen (not an absolute path). When MLIRTargets.cmake fails to define the corresponding imported target — as happens in Nix sandboxed builds where the binary is in a separate store path — TableGen.cmake passes the bare string into add_custom_command(DEPENDS ...), where CMake treats it as a relative file path:

ninja: error: 'include/flang/Optimizer/Dialect/CUF/Attributes/mlir-tblgen',
needed by '...CUFEnumAttr.h.inc', missing and no known rule to make it

Additionally, MLIR_TABLEGEN_TARGET is never exported by MLIRConfig.cmake, so TableGen.cmake has no target to track for dependency rebuilds.

Fix

All changes are in mlir/cmake/modules/MLIRConfig.cmake.in:

  1. Make MLIR_TABLEGEN_EXE (and siblings) conditional — respect user overrides
  2. Resolve bare names to full paths via find_program with HINTS "${LLVM_TOOLS_BINARY_DIR}"
  3. Create an imported mlir-tblgen target as fallback when MLIRTargets.cmake doesn't provide one
  4. Set MLIR_TABLEGEN_TARGET so TableGen.cmake has a proper target for DEPENDS

This replaces the previous workaround in flang/CMakeLists.txt (#150987) with a fix at the source — any downstream project using find_package(MLIR) benefits.

Reproduction

No Nix required. Configure LLVM+MLIR (no build needed), assemble a fake install tree, then run a minimal test project with -DMLIR_TABLEGEN_EXE=/some/path:

-- >>> Before find_package(MLIR):
-- >>>   MLIR_TABLEGEN_EXE = '/nix/store/fake/bin/mlir-tblgen'

-- >>> After find_package(MLIR):
-- >>>   MLIR_TABLEGEN_EXE    = 'mlir-tblgen'        ← override lost!
-- >>>   MLIR_TABLEGEN_TARGET = ''                    ← never set!

CMake Error: BUG REPRODUCED!
  MLIR_TABLEGEN_EXE = 'mlir-tblgen' — bare name, not absolute, not a target.
  The user-provided override was silently discarded by MLIRConfig.cmake.

Full reproduction steps in #150986.


Full diff: https://github.com/llvm/llvm-project/pull/189918.diff

1 Files Affected:

  • (modified) mlir/cmake/modules/MLIRConfig.cmake.in (+33-3)
diff --git a/mlir/cmake/modules/MLIRConfig.cmake.in b/mlir/cmake/modules/MLIRConfig.cmake.in
index 71f3e028b1e88..b30b6cdc0de16 100644
--- a/mlir/cmake/modules/MLIRConfig.cmake.in
+++ b/mlir/cmake/modules/MLIRConfig.cmake.in
@@ -9,9 +9,16 @@ find_package(LLVM ${LLVM_VERSION} EXACT REQUIRED CONFIG
 set(MLIR_EXPORTED_TARGETS "@MLIR_EXPORTS@")
 set(MLIR_CMAKE_DIR "@MLIR_CONFIG_CMAKE_DIR@")
 set(MLIR_INCLUDE_DIRS "@MLIR_CONFIG_INCLUDE_DIRS@")
-set(MLIR_TABLEGEN_EXE "@MLIR_CONFIG_TABLEGEN_EXE@")
-set(MLIR_PDLL_TABLEGEN_EXE "@MLIR_CONFIG_PDLL_TABLEGEN_EXE@")
-set(MLIR_SRC_SHARDER_TABLEGEN_EXE "@MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE@")
+# Allow users to override tablegen executables (e.g. for sandboxed builds).
+if(NOT MLIR_TABLEGEN_EXE)
+  set(MLIR_TABLEGEN_EXE "@MLIR_CONFIG_TABLEGEN_EXE@")
+endif()
+if(NOT MLIR_PDLL_TABLEGEN_EXE)
+  set(MLIR_PDLL_TABLEGEN_EXE "@MLIR_CONFIG_PDLL_TABLEGEN_EXE@")
+endif()
+if(NOT MLIR_SRC_SHARDER_TABLEGEN_EXE)
+  set(MLIR_SRC_SHARDER_TABLEGEN_EXE "@MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE@")
+endif()
 set(MLIR_IRDL_TO_CPP_EXE "@MLIR_CONFIG_IRDL_TO_CPP_EXE@")
 set(MLIR_INSTALL_AGGREGATE_OBJECTS "@MLIR_INSTALL_AGGREGATE_OBJECTS@")
 set(MLIR_ENABLE_BINDINGS_PYTHON "@MLIR_ENABLE_BINDINGS_PYTHON@")
@@ -32,6 +39,29 @@ if(NOT TARGET MLIRSupport)
   @MLIR_CONFIG_INCLUDE_EXPORTS@
 endif()
 
+# Ensure MLIR_TABLEGEN_EXE is a full path and has a corresponding imported
+# target. In install trees, MLIR_TABLEGEN_EXE may be a bare name
+# ("mlir-tblgen") rather than an absolute path. Resolve it so that
+# TableGen.cmake can use it as both a COMMAND and a DEPENDS entry.
+if(MLIR_TABLEGEN_EXE AND NOT IS_ABSOLUTE "${MLIR_TABLEGEN_EXE}"
+    AND NOT TARGET "${MLIR_TABLEGEN_EXE}")
+  find_program(_mlir_tblgen_exe "${MLIR_TABLEGEN_EXE}"
+    HINTS "${LLVM_TOOLS_BINARY_DIR}")
+  if(_mlir_tblgen_exe)
+    set(MLIR_TABLEGEN_EXE "${_mlir_tblgen_exe}")
+  endif()
+  unset(_mlir_tblgen_exe)
+endif()
+
+if(NOT TARGET mlir-tblgen AND MLIR_TABLEGEN_EXE)
+  add_executable(mlir-tblgen IMPORTED GLOBAL)
+  set_target_properties(mlir-tblgen PROPERTIES
+    IMPORTED_LOCATION "${MLIR_TABLEGEN_EXE}")
+endif()
+if(NOT DEFINED MLIR_TABLEGEN_TARGET)
+  set(MLIR_TABLEGEN_TARGET mlir-tblgen)
+endif()
+
 # By creating these targets here, subprojects that depend on MLIR's
 # tablegen-generated headers can always depend on these targets whether building
 # in-tree with MLIR or not.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flang][mlir] MLIRConfig.cmake overrides MLIR_TABLEGEN_EXE and breaks external/flang builds

2 participants