Have you ever noticed a flaky build with missing dependency errors like this?
D:\dev\projects\llvm-project\mlir\include\mlir/Dialect/Arith/IR/Arith.h(40): fatal error C1083: Cannot open include file: 'mlir/Dialect/Arith/IR/ArithOpsInterfaces.h.inc': No such file or directory ninja: build stopped: subcommand failed.
As of Ninja version 1.11+, the ninja -t missingdeps
tool can be used to find cases where generated source files (i.e. *.h.inc
files produced by tablegen) were not added correctly to dependencies. Similar issues and tools for spotting them have been discussed on GitHub here: Method for detecting missing dependency graph edges · Issue #1660 · ninja-build/ninja · GitHub.
- Certain missing generated file dependencies aren’t usually an issue since some other part of the build generates the files before they are needed. However, if you build on a smaller machine without much parallelism or you build leaf targets directly, these can cause flaky builds.
I ran Ninja’s missingdeps
tool on LLVM and MLIR and I’m quite happy with the workflow and findings (and other LLVM subprojects could also find this useful):
-
Configure
D:\dev\projects\llvm-project (main -> upstream) λ cmake -G Ninja -S llvm -B ./build-mlir/ \ -DLLVM_ENABLE_PROJECTS=mlir \ -DCMAKE_BUILD_TYPE=RelWithDebInfo
-
Build
D:\dev\projects\llvm-project (main -> upstream) λ ninja -C build-mlir all
-
Check missing deps
D:\dev\projects\llvm-project (main -> upstream) λ ninja -C build-mlir -t missingdeps Missing dep: tools/mlir/lib/Dialect/ArmNeon/CMakeFiles/obj.MLIRArmNeonDialect.dir/IR/ArmNeonDialect.cpp.obj uses tools/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Target/LLVMIR/CMakeFiles/obj.MLIRTargetLLVMIRExport.dir/LoopAnnotationTranslation.cpp.obj uses include/llvm/Frontend/OpenMP/OMP.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Target/LLVMIR/CMakeFiles/obj.MLIRTargetLLVMIRExport.dir/ModuleTranslation.cpp.obj uses include/llvm/Frontend/OpenMP/OMP.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Target/LLVMIR/CMakeFiles/obj.MLIRTargetLLVMIRExport.dir/Dialect/OpenMPCommon.cpp.obj uses include/llvm/Frontend/OpenMP/OMP.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Interfaces/CMakeFiles/obj.MLIRTilingInterface.dir/TilingInterface.cpp.obj uses tools/mlir/include/mlir/Dialect/Utils/DialectUtilsEnums.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Conversion/MemRefToLLVM/CMakeFiles/obj.MLIRMemRefToLLVM.dir/MemRefToLLVM.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Conversion/MemRefToLLVM/CMakeFiles/obj.MLIRMemRefToLLVM.dir/MemRefToLLVM.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Conversion/LinalgToStandard/CMakeFiles/obj.MLIRLinalgToStandard.dir/LinalgToStandard.cpp.obj uses tools/mlir/include/mlir/Dialect/Vector/Transforms/VectorTransformsEnums.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Conversion/NVVMToLLVM/CMakeFiles/obj.MLIRNVVMToLLVM.dir/NVVMToLLVM.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Conversion/NVVMToLLVM/CMakeFiles/obj.MLIRNVVMToLLVM.dir/NVVMToLLVM.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/OpenMP/CMakeFiles/obj.MLIROpenMPDialect.dir/IR/OpenMPDialect.cpp.obj uses include/llvm/Frontend/OpenMP/OMP.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/MLProgram/Transforms/CMakeFiles/obj.MLIRMLProgramTransforms.dir/PipelineGlobalOps.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/MLProgram/Transforms/CMakeFiles/obj.MLIRMLProgramTransforms.dir/PipelineGlobalOps.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/Bufferize.cpp.obj uses tools/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/Bufferize.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/Bufferize.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/OutlineShapeComputation.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/OutlineShapeComputation.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/RemoveShapeConstraints.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/RemoveShapeConstraints.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/ShapeToShapeLowering.cpp.obj uses tools/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/ShapeToShapeLowering.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOpsDialect.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/lib/Dialect/Shape/Transforms/CMakeFiles/obj.MLIRShapeOpsTransforms.dir/ShapeToShapeLowering.cpp.obj uses tools/mlir/include/mlir/Dialect/Func/IR/FuncOps.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/test/lib/Dialect/NVGPU/CMakeFiles/MLIRNVGPUTestPasses.dir/TestNVGPUTransforms.cpp.obj uses tools/mlir/include/mlir/Dialect/Linalg/Passes.h.inc (generated by CUSTOM_COMMAND) Missing dep: tools/mlir/test/lib/Dialect/NVGPU/CMakeFiles/MLIRNVGPUTestPasses.dir/TestNVGPUTransforms.cpp.obj uses tools/mlir/include/mlir/Dialect/Vector/Transforms/VectorTransformsEnums.h.inc (generated by CUSTOM_COMMAND) Processed 8259 nodes. Error: There are 15 missing dependency paths. 15 targets had depfile dependencies on 7 distinct generated inputs (from 1 rules) without a non-depfile dep path to the generator. There might be build flakiness if any of the targets listed above are built alone, or not late enough, in a clean output directory.
Sure enough, if I try building any of those targets in isolation from a clean build, I hit errors like the one above:
D:\dev\projects\llvm-project (main -> upstream)
λ cmake -G Ninja -S llvm -B ./build-mlir-broken/ \
-DLLVM_ENABLE_PROJECTS=mlir \
-DCMAKE_BUILD_TYPE=RelWithDebInfo
D:\dev\projects\llvm-project (main -> upstream)
λ ninja -C build-mlir-broken MLIRArmNeonDialect
ninja: Entering directory `build-mlir-broken'
...
[882/883] Building CXX object tools\mlir\lib\Dia...MLIRArmNeonDialect.dir\IR\ArmNeonDialect.cpp.obj FAILED: tools/mlir/lib/Dialect/ArmNeon/CMakeFiles/obj.MLIRArmNeonDialect.dir/IR/ArmNeonDialect.cpp.obj
D:\dev\projects\llvm-project\mlir\include\mlir/Dialect/Arith/IR/Arith.h(40): fatal error C1083: Cannot open include file: 'mlir/Dialect/Arith/IR/ArithOpsInterfaces.h.inc': No such file or directory
ninja: build stopped: subcommand failed.
In that case I can see that llvm-project\mlir\lib\Dialect\ArmNeon\IR\ArmNeonDialect.cpp
has #include "mlir/Dialect/Vector/IR/VectorOps.h"
but llvm-project\mlir\lib\Dialect\ArmNeon\CMakeLists.txt
is missing a dependency on MLIRVectorDialect
. Adding the missing dep and re-running the build (and missingdeps
) confirms the fix worked.
Would anyone like to help fix these and perhaps include this check in a CI build so the changes stick?