Building simple c++ MLIR program with local LLVM build

Hi! I’m trying to build a simple MLIR program using C++ API using locally build LLVM.

I build my LLVM instance with:

cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="mlir;llvm;clang;lld" -DLLVM_TARGETS_TO_BUILD="Native" -DCMAKE_BUILD_TYPE=Release -DMLIR_ENABLE_BINDINGS_PYTHON=ON -DPython3_EXECUTABLE="..." -DLLVM_INSTALL_UTILS=ON -DMLIR_INCLUDE_INTEGRATION_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON

And installed with:

cmake -DCMAKE_INSTALL_PREFIX=../build-install -P cmake_install.cmake

Here’s a example.ccp file that I have:

#include "mlir/IR/MLIRContext.h"

int main() {
  mlir::MLIRContext context;
  return 0;
}

And here’s CMakeLists.txt file:

cmake_minimum_required(VERSION 3.30)
project(MLIR_example)
set(CMAKE_CXX_STANDARD 17)

include_directories(${LLVM_PROJECT_DIR}/build-install/include)
link_directories(${LLVM_PROJECT_DIR}/build-install/lib)

add_executable(example example.cpp)
target_link_libraries(example PUBLIC mlir_c_runner_utils LLVMSupport)

But running cmake -G Ninja ../ and ninja results in error:

[1/1] Linking CXX executable example
FAILED: example
: && /usr/bin/c++   CMakeFiles/example.dir/example.cpp.o -o example -L/home/mtsokol/llvm-project-main/build/lib -Wl,-rpath,/home/mtsokol/llvm-project-main/build/lib  -lmlir_c_runner_utils  -lLLVMSupport && :
/usr/bin/ld: CMakeFiles/example.dir/example.cpp.o: in function `main':
example.cpp:(.text+0x29): undefined reference to `mlir::MLIRContext::MLIRContext(mlir::MLIRContext::Threading)'
/usr/bin/ld: example.cpp:(.text+0x3a): undefined reference to `mlir::MLIRContext::~MLIRContext()'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Thank you for any beginners tips on what I have missed in my setup!

target_link_libraries(example PUBLIC mlir_c_runner_utils LLVMSupport)

I don’t know how you selected this list?
In general you need to look at the header you include in your .cpp file, and include the corresponding libraries.
Here you have a single one: #include "mlir/IR/MLIRContext.h"

So the library providing the implementation for this header is MLIRIR.

If you have a doubt, you can check in the mlir/lib/IR/CMakeLists.txt file the name of the library.

@mehdi_amini Thank you for help!

MLIRIR was required indeed - I managed to get my example up and running. Here’s a list of link libraries that I needed:

target_link_libraries(
    example
    MLIRIR
    LLVMSupport
    LLVMDemangle
    MLIRSupport
)

What surprised me was the fact that the order of elements in the list matters.

I’m surprised you needed more than MLIRIR, CMake is supposed to handle the transitive dependencies itself.

@mehdi_amini Hmm, then I think something might be broken with transitive dependencies.

If anyone is interested in the future here’s a small repository that reproduces this issue: GitHub - mtsokol/example-mlir-cpp


Here’s a folder with working example: example-mlir-cpp/case_running at main · mtsokol/example-mlir-cpp · GitHub
And passing CI job: Initial commit · mtsokol/example-mlir-cpp@0506c10 · GitHub
with CMakeLists libs:

target_link_libraries(
    example
    MLIRIR
    LLVMSupport
    LLVMDemangle
    MLIRSupport
    )

Here’s a folder with failing example: example-mlir-cpp/case_failing at main · mtsokol/example-mlir-cpp · GitHub
And failing CI job: Initial commit · mtsokol/example-mlir-cpp@0506c10 · GitHub
with CMakeLists libs:

target_link_libraries(
    example
    MLIRIR
    )

Looks that the other option is to build LLVM with:

-DLLVM_BUILD_LLVM_DYLIB=ON

And then there’s a libLLVM.so and libMLIR.so and it’s sufficient to link just them.

It may be worth taking at look at the standalone example:
https://github.com/llvm/llvm-project/tree/main/mlir/examples/standalone

There’s been a related talk at FOSDEM 2023, “How to Build your own MLIR Dialect”, which also goes through setting up CMakeLists.txt: