Skip to content

Build fails with Ninja multi-config generator #3314

@jonasehrlich

Description

@jonasehrlich

Problem Description

onnx-mlir fails building with the Ninja Multi-Config generator on macOS (though this should not be related). Configuration and build with the normal Ninja generator works.

MLIR_DIR=$(pwd)/../llvm-project/build/lib/cmake/mlir
cmake -G "Ninja Multi-Config" -B build \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DONNX_MLIR_ENABLE_JAVA=OFF \
  -DMLIR_DIR="$MLIR_DIR"
Build log
FAILED: [code=1] src/Compiler/CMakeFiles/OMCompilerOptions.dir/Debug/CompilerOptions.cpp.o
/usr/bin/c++ -DONNX_MLIR_ENABLE_STABLEHLO -D_DEBUG -D_GLIBCXX_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MA
CROS -D__STDC_LIMIT_MACROS -DCMAKE_INTDIR=\"Debug\" -I/Users/jonas/projects/gh/llvm-project/llvm/include -I/
Users/jonas/projects/gh/llvm-project/build/include -I/Users/jonas/projects/gh/llvm-project/mlir/incl
ude -I/Users/jonas/projects/gh/llvm-project/build/tools/mlir/include -I"/Users/jonas/projects/gh/onn
x-mlir/build/src/Compiler/\${CONFIGURATION}" -I/Users/jonas/projects/gh/onnx-mlir/include -I/Users/jonas/pro
jects/gh/onnx-mlir -I/Users/jonas/projects/gh/onnx-mlir/build -isystem /opt/homebrew/include -fPIC -
fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexce
pt-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation
 -Wctad-maybe-unsupported -fdiagnostics-color -DSUPPRESS_THIRD_PARTY_WARNINGS -g -std=gnu++17 -arch arm64   -D_DEBUG
 -D_GLIBCXX_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MT src/Compiler/CM
akeFiles/OMCompilerOptions.dir/Debug/CompilerOptions.cpp.o -MF src/Compiler/CMakeFiles/OMCompilerOptions.dir/Debug/C
ompilerOptions.cpp.o.d -o src/Compiler/CMakeFiles/OMCompilerOptions.dir/Debug/CompilerOptions.cpp.o -c /Users/jonas/
projects/gh/onnx-mlir/src/Compiler/CompilerOptions.cpp
/Users/jonas/projects/gh/onnx-mlir/src/Compiler/CompilerOptions.cpp:18:10: fatal error: 'ExternalUtil.hpp' f
ile not found
   18 | #include "ExternalUtil.hpp"
      |          ^~~~~~~~~~~~~~~~~~
1 error generated.

when configuring with

MLIR_DIR=$(pwd)/../llvm-project/build/lib/cmake/mlir
cmake -G "Ninja Multi-Config" -B build \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DONNX_MLIR_ENABLE_JAVA=OFF \
  -DMLIR_DIR="$MLIR_DIR"

The problem seems to be these lines:

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/ExternalUtil.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/ExternalUtil.hpp.cfg
@ONLY
)
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/ExternalUtil.hpp
INPUT ${CMAKE_CURRENT_BINARY_DIR}/ExternalUtil.hpp.cfg
)
# CMAKE_CFG_INTDIR is . for single-config generators such as make, and
# it has a value (e.g. $(Configuration)) otherwise, so we can use it to
# determine whether we are dealing with a multi-config generator.
if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
set(FILE_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
else()
set(FILE_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()
add_custom_target(ExternalUtil DEPENDS ${FILE_GENERATE_DIR}/ExternalUtil.hpp)

At this point the following variable values will be set:

${FILE_GENERATE_DIR}: /Users/jonas/projects/onnx-mlir/build/src/Compiler/${CONFIGURATION}
${CMAKE_BUILD_TYPE}: Debug
${CMAKE_CFG_INTDIR}: ${CONFIGURATION}

The CMAKE_BUILD_TYPE which is not expected to be set for the configuration of multi-config generators is automatically set by:

onnx-mlir/CMakeLists.txt

Lines 28 to 31 in 96197cb

if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type (default Debug)" FORCE)
endif()

And for the Ninja Multi-Config generator CMAKE_CFG_INTDIR is set to ${CONFIGURATION}. Thus we enter the else branch and FILE_GENERATE_DIR will get the value /Users/jonas/projects/gh/onnx-mlir/build/src/Compiler/\${CONFIGURATION}.

While the a separate ExternalUtil.hpp is generated for each CMAKE_CONFIGURATION_TYPE.

Proposed Solutions

Unfortunately I am new to work with onnx-mlir, so please excuse any missing knowledge about the build system.

Generate single ExternalUtil.hpp

At least for multi-config generators there seems to be no use-case of different ExternalUtil.hpp files as (I think?)
the variables cannot differ between configurations. This might obviously be different for single-config generators.

Fix include paths and multi-config detection

  • target_include_directories supports generator expressions in arguments
  • Unfortunately the DEPENDS argument of add_custom_target does not support generator expressions

So my suggestion would be to iterate over CMAKE_CONFIGURATION_TYPES and add all files as a dependency for the ExternalUtil target.

I also checked the different variables for different generators:

-- CMAKE_GENERATOR: Ninja Multi-Config
-- CMAKE_CONFIGURATION_TYPES: Debug;Release;RelWithDebInfo
-- CMAKE_BUILD_TYPE:
-- CMAKE_CFG_INTDIR: ${CONFIGURATION}
-- CMAKE_GENERATOR: Xcode
-- CMAKE_CONFIGURATION_TYPES: Debug;Release;MinSizeRel;RelWithDebInfo
-- CMAKE_BUILD_TYPE:
-- CMAKE_CFG_INTDIR: $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
-- CMAKE_GENERATOR: Unix Makefiles
-- CMAKE_CONFIGURATION_TYPES:
-- CMAKE_BUILD_TYPE:
-- CMAKE_CFG_INTDIR: .
-- CMAKE_GENERATOR: Ninja
-- CMAKE_CONFIGURATION_TYPES:
-- CMAKE_BUILD_TYPE:
-- CMAKE_CFG_INTDIR: .

Unfortunately I do not have a Windows system to test the Visual Studio generator, but it seems to me that the CMAKE_CFG_INTDIR variable is not the right one to check for multi-config generators, instead we should check for CMAKE_CONFIGURATION_TYPES.

So something along these lines should work:

configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/ExternalUtil.hpp.in
  ${CMAKE_CURRENT_BINARY_DIR}/ExternalUtil.hpp.cfg
  @ONLY
  )

file(GENERATE
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/ExternalUtil.hpp
  INPUT ${CMAKE_CURRENT_BINARY_DIR}/ExternalUtil.hpp.cfg
  )

# Files to generate for the ExternalUtil custom target
set(EXTERNAL_UTIL_GENERATED_FILES)
# ExternalUtil.hpp is generator with the $<CONFIG> generator expression. This
# will create a separate file for each configuration. Collect all generated
# files as a dependency for the ExternalUtil custom target. For multi-config
# generators CMAKE_CONFIGURATION_TYPES lists the enabled generator
# configurations.
foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES})
  list(APPEND EXTERNAL_UTIL_GENERATED_FILES ${CONFIG}/ExternalUtil.hpp)
  set(FILE_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>)
endforeach()

# Single config generator, ExternalUtil.hpp will be created in the
# CMAKE_BUILD_TYPE directory
if(NOT CMAKE_CONFIGURATION_TYPES)
  list(APPEND EXTERNAL_UTIL_GENERATED_FILES ${CMAKE_BUILD_TYPE}/ExternalUtil.hpp)
  set(FILE_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()

add_custom_target(ExternalUtil DEPENDS ${EXTERNAL_UTIL_GENERATED_FILES})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions