[Mlir-commits] [mlir] [mlir][cmake] Respect MLIR_TABLEGEN_EXE overrides in MLIRConfig.cmake (PR #189918)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Apr 1 02:02:18 PDT 2026


https://github.com/Acture created https://github.com/llvm/llvm-project/pull/189918

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.


>From 2b62ec760f7c8859d96eda12375779bafaa280cf Mon Sep 17 00:00:00 2001
From: acture <acturea at gmail.com>
Date: Tue, 29 Jul 2025 00:11:25 +0800
Subject: [PATCH] [mlir][cmake] Respect MLIR_TABLEGEN_EXE overrides in
 MLIRConfig.cmake

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 #150986
---
 mlir/cmake/modules/MLIRConfig.cmake.in | 36 +++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

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.



More information about the Mlir-commits mailing list