Building External Project: target "mlir_runner_utils" links to target "Terminfo::terminfo" but the target was not found

I wanted to generate mlir_runner_utils lib myself, which is static and risc-v, but something is going wrong.

CMake Error at /llvm/build/lib/cmake/llvm/AddLLVM.cmake:588 (add_library):
  Target "mlir_runner_utils" links to target "Terminfo::terminfo" but the
  target was not found.  Perhaps a find_package() call is missing for an
  IMPORTED target, or an ALIAS target is missing?
Call Stack (most recent call first):
/llvm/build/lib/cmake/mlir/AddMLIR.cmake:303 (llvm_add_library)
  mlir/ExecutionEngine/CMakeLists.txt:3 (add_mlir_library)

I don’t know how to solve this problem. I looked for the answer on Google, but I couldn’t find it, and I don’t know where to download Terminfo.

I don’t know how you configured LLVM, but Terminfo is only supposed to come with the LLVMSupport library, and CMake is supposed to detect it and configure it automatically.
What are the steps that got you to this point?

You can also try to build LLVM explicitly disabling it: -DLLVM_ENABLE_TERMINFO=OFF when configuring it.

The first step.Here i build clang.

cmake -G Ninja ../../llvm/llvm \
    -DLLVM_TARGETS_TO_BUILD="host;RISCV" \
    -DLLVM_ENABLE_PROJECTS="clang" \
    -DCMAKE_BUILD_TYPE=RELEASE
  ninja

The second step.The cmake command to build mlir_runner_utils library.The location of zlib must be specified here, otherwise the same problem will occur as with "Terminfo::terminfo",

cmake -G Ninja $PWD/.. \
    -DMLIR_DIR=$PWD/../../../llvm/build/lib/cmake/mlir \
    -DLLVM_DIR=$PWD/../../../llvm/build/lib/cmake/llvm \
    -DLLVM_HOST_TRIPLE=riscv64-unknown-linux-gnu \
    -DCMAKE_C_COMPILER=$PWD/../../build-local-clang/bin/clang \
    -DCMAKE_CXX_COMPILER=$PWD/../../build-local-clang/bin/clang++ \
    -DCMAKE_C_FLAGS="--target=riscv64-unknown-linux-gnu --sysroot=$PWD/../../build-riscv-gnu-toolchain/sysroot --gcc-toolchain=$PWD/../../build-riscv-gnu-toolchain" \
    -DCMAKE_CXX_FLAGS="--target=riscv64-unknown-linux-gnu --sysroot=$PWD/../../build-riscv-gnu-toolchain/sysroot --gcc-toolchain=$PWD/../../build-riscv-gnu-toolchain" \
    -DZLIB_INCLUDE_DIR=$PWD/../../zlib -DZLIB_LIBRARY=$PWD/../../zlib 

CMakeLists.txt about the project.

cmake_minimum_required(VERSION 3.10)

if(POLICY CMP0077)
  cmake_policy(SET CMP0077 NEW)
endif()

if(POLICY CMP0116)
  cmake_policy(SET CMP0116 OLD)
endif()

project(rv-lib LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(LLVM_PROJECT_SOURCE_DIR ${MLIR_DIR}/../../../../)
#-------------------------------------------------------------------------------
# MLIR/LLVM Configuration
#-------------------------------------------------------------------------------

find_package(MLIR REQUIRED CONFIG)
find_package(ZLIB)

message(STATUS "${MLIR_CMAKE_DIR}")
message(STATUS "${LLVM_CMAKE_DIR}")
message(STATUS "${LLVM_PROJECT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(TableGen)
include(AddMLIR)
include(AddLLVM)
include(HandleLLVMOptions)
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_subdirectory(mlir)

build mlir_runner_utils CMakeLists.txt

set(MLIR_EXECUTIONENGINE_LLVMIR_DIR ${LLVM_PROJECT_SOURCE_DIR}/mlir/lib/ExecutionEngine)

add_mlir_library(mlir_rv_runner_utils
  ${MLIR_EXECUTIONENGINE_LLVMIR_DIR}/RunnerUtils.cpp 
  EXCLUDE_FROM_LIBMLIR
)

Although -DLLVM_ENABLE_TERMINFO=OFF don’t work,thank you for your reply.

What is this prebuilt LLVM for? This is the one that you could try building with DLLVM_ENABLE_TERMINFO=OFF.
Alternatively, if you managed to build LLVM for your target with terminfo enabled, that means it is probably available somehow. LLVM is supposed to have configured it with find_package(Terminfo), something may be missing in the way it gets re-exports to build external project like you’re doing.
You’re also seem to assemble the project in some ways I don’t understand right now to be honest.

cmake -G Ninja $PWD/.. \
    -DMLIR_DIR=$PWD/../../../llvm/build/lib/cmake/mlir \
    -DLLVM_DIR=$PWD/../../../llvm/build/lib/cmake/llvm \

$PWD/.. has the following CMakeLists.txt.

cmake_minimum_required(VERSION 3.10)

if(POLICY CMP0077)
  cmake_policy(SET CMP0077 NEW)
endif()

if(POLICY CMP0116)
  cmake_policy(SET CMP0116 OLD)
endif()

project(rv-lib LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(LLVM_PROJECT_SOURCE_DIR ${MLIR_DIR}/../../../../)
#-------------------------------------------------------------------------------
# MLIR/LLVM Configuration
#-------------------------------------------------------------------------------

find_package(MLIR REQUIRED CONFIG)
find_package(ZLIB)

message(STATUS "${MLIR_CMAKE_DIR}")
message(STATUS "${LLVM_CMAKE_DIR}")
message(STATUS "${LLVM_PROJECT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(TableGen)
include(AddMLIR)
include(AddLLVM)
include(HandleLLVMOptions)
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_subdirectory(mlir)

add_subdirectory(mlir)
mlir directory has the following CMakeLists.txt.

set(MLIR_EXECUTIONENGINE_LLVMIR_DIR ${LLVM_PROJECT_SOURCE_DIR}/mlir/lib/ExecutionEngine)

add_mlir_library(mlir_rv_runner_utils
  ${MLIR_EXECUTIONENGINE_LLVMIR_DIR}/RunnerUtils.cpp 
  EXCLUDE_FROM_LIBMLIR
)

I added DLLVM_ENABLE_TERMINFO=OFF in the following command really doesn’t work.

cmake -G Ninja $PWD/.. \
    -DMLIR_DIR=$PWD/../../../llvm/build/lib/cmake/mlir \
    -DLLVM_DIR=$PWD/../../../llvm/build/lib/cmake/llvm \
    -DLLVM_HOST_TRIPLE=riscv64-unknown-linux-gnu \
    -DCMAKE_C_COMPILER=$PWD/../../build-local-clang/bin/clang \
    -DCMAKE_CXX_COMPILER=$PWD/../../build-local-clang/bin/clang++ \
    -DCMAKE_C_FLAGS="--target=riscv64-unknown-linux-gnu --sysroot=$PWD/../../build-riscv-gnu-toolchain/sysroot --gcc-toolchain=$PWD/../../build-riscv-gnu-toolchain" \
    -DCMAKE_CXX_FLAGS="--target=riscv64-unknown-linux-gnu --sysroot=$PWD/../../build-riscv-gnu-toolchain/sysroot --gcc-toolchain=$PWD/../../build-riscv-gnu-toolchain" \
    -DZLIB_INCLUDE_DIR=$PWD/../../zlib -DZLIB_LIBRARY=$PWD/../../zlib 

As I mentioned, this should be added when configuring and building your prebuilt LLVM, that is the code you seem to have built at: $PWD/../../../llvm/build.

Actually I don’t want add it in prebuild LLVM. I think it may have an impact on other parts of the project.I came up with a good idea, actually I want to print the contents of memref in spike( risc-v simulator,), I can refer to toy.print op(printf is in the standard library),I think it’s for the best.Finally, thank you for your reply.

It sucks that I seem to be having problems again.It doesn’t look like it found the definition of the printf function.

ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::PreservedAnalyses::AllAnalysesType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AtLeastNOperands<1>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::AtLeastNOperands<1>::Impl]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::CallOpInterface::Trait]::Empty>)
configSt.mlir:6:3: error: 'func.call' op 'printf' does not reference a valid function
  gemmini.Print %arrayA : memref<16x16xi8>
  ^
configSt.mlir:6:3: note: see current operation: %27 = "func.call"(%9) {callee = @printf} : (!llvm.ptr<i8>) -> i32
mlir-asm-printer: Verifying operation: func.func
'scf.yield' op must be the last operation in the parent block
mlir-asm-printer: 'func.func' failed to verify and will be printed in generic form
"func.func"() ({
  %0 = "arith.constant"() {value = 16 : i64} : () -> i64
  %1 = "arith.constant"() {value = 0 : i64} : () -> i64
  %2 = "memref.alloc"() {operand_segment_sizes = array<i32: 0, 0>} : () -> memref<16x16xi8>
  %3 = "memref.alloc"() {operand_segment_sizes = array<i32: 0, 0>} : () -> memref<16x16xi8>
  %4 = "llvm.mlir.addressof"() {global_name = @frmt_spec} : () -> !llvm.ptr<array<4 x i8>>
  %5 = "llvm.mlir.constant"() {value = 0 : index} : () -> i64
  %6 = "llvm.getelementptr"(%4, %5, %5) {rawConstantIndices = array<i32: -2147483648, -2147483648>} : (!llvm.ptr<array<4 x i8>>, i64, i64) -> !llvm.ptr<i8>
  %7 = "llvm.mlir.addressof"() {global_name = @nl} : () -> !llvm.ptr<array<2 x i8>>
  %8 = "llvm.mlir.constant"() {value = 0 : index} : () -> i64
  %9 = "llvm.getelementptr"(%7, %8, %8) {rawConstantIndices = array<i32: -2147483648, -2147483648>} : (!llvm.ptr<array<2 x i8>>, i64, i64) -> !llvm.ptr<i8>
  %10 = "arith.constant"() {value = 0 : index} : () -> index
  %11 = "arith.constant"() {value = 16 : index} : () -> index
  %12 = "arith.constant"() {value = 1 : index} : () -> index
  "scf.for"(%10, %11, %12) ({
  ^bb0(%arg0: index):
    %24 = "arith.constant"() {value = 0 : index} : () -> index
    %25 = "arith.constant"() {value = 16 : index} : () -> index
    %26 = "arith.constant"() {value = 1 : index} : () -> index
    "scf.for"(%24, %25, %26) ({
    ^bb0(%arg1: index):
      %28 = "memref.load"(%2, %arg0, %arg1) : (memref<16x16xi8>, index, index) -> i8
      %29 = "func.call"(%6, %28) {callee = @printf} : (!llvm.ptr<i8>, i8) -> i32
      "scf.yield"() : () -> ()
      "scf.yield"() : () -> ()
    }) : (index, index, index) -> ()
    "scf.yield"() : () -> ()
    %27 = "func.call"(%9) {callee = @printf} : (!llvm.ptr<i8>) -> i32
    "scf.yield"() : () -> ()
  }) : (index, index, index) -> ()
  "gemmini.Print"(%2) : (memref<16x16xi8>) -> ()
  %13 = "memref.cast"(%2) : (memref<16x16xi8>) -> memref<*xi8>
  %14 = "memref.extract_aligned_pointer_as_index"(%2) : (memref<16x16xi8>) -> index
  %15 = "arith.index_cast"(%14) : (index) -> i64
  %16 = "memref.extract_aligned_pointer_as_index"(%3) : (memref<16x16xi8>) -> index
  %17 = "arith.index_cast"(%16) : (index) -> i64
  %18 = "arith.constant"() {value = 2 : i64} : () -> i64
  %19 = "arith.constant"() {value = 4575657221408423952 : i64} : () -> i64
  "gemmini.intr.configSt"(%18, %19) : (i64, i64) -> ()
  "gemmini.ConfigSt"(%0) {activation = 0 : i64} : (i64) -> ()
  %20 = "arith.constant"() {value = 4575657221409472769 : i64} : () -> i64
  "gemmini.intr.configLd"(%20, %0) : (i64, i64) -> ()
  "gemmini.ConfigLd"(%0) : (i64) -> ()
  %21 = "arith.constant"() {value = 4503668346847232 : i64} : () -> i64
  "gemmini.intr.mvin"(%15, %21) : (i64, i64) -> ()
  "gemmini.Mvin"(%15, %1) : (i64, i64) -> ()
  %22 = "memref.cast"(%3) : (memref<16x16xi8>) -> memref<*xi8>
  %23 = "arith.constant"() {value = 4503668346847232 : i64} : () -> i64
  "gemmini.intr.mvout"(%17, %23) : (i64, i64) -> ()
  "gemmini.Mvout"(%17, %1) : (i64, i64) -> ()
  "func.return"() : () -> ()
}) {function_type = () -> (), sym_name = "main"} : () -> ()


} -> SUCCESS
//===-------------------------------------------===//

//===-------------------------------------------===//
Legalizing operation : 'func.return'(0x5623b1b3b720) {
  "func.return"() : () -> ()

} -> SUCCESS : operation marked legal by the target
//===-------------------------------------------===//
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::PreservedAnalyses::AllAnalysesType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AtLeastNOperands<1>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::AtLeastNOperands<1>::Impl]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::CallOpInterface::Trait]::Empty>)
configSt.mlir:6:3: error: 'func.call' op 'printf' does not reference a valid function
  gemmini.Print %arrayA : memref<16x16xi8>
  ^
configSt.mlir:6:3: note: see current operation: %27 = "func.call"(%9) {callee = @printf} : (!llvm.ptr<i8>) -> i32

I don’t quite see this related to the build issue with TermInfo, maybe I’m missing the connection here?

Since I didn’t think it was necessary to create new topic, I sent the message under this topic.Sorry, this issue is not related to TermInfo, because I don’t intend to build mlir_runner_utils lib, and I think the current approach is a better one.

I don’t think the code inserted into the printf function declaration is running, I’ll go debug it.

I have solved this problem.This gave me a deeper understanding of the toy language lower process.