I just start learning LLVM and follow the start-up website quick-start-writing-hello-world to write my first HelloPass.
However, it doesn't work as expected.
The llvm version is 16.0.6
Here are my steps.
The cmakelist is a bit different from the doc, because I don't include my project into the LLVM source. And I follow Developing LLVM passes out of source.
The project structure: . ├── CMakeLists.txt ├── helloPass │ ├── CMakeLists.txt │ └── hello.cpp
In CMakeLists.txt:
cmake_minimum_required(VERSION 3.25)
project(llvm_kernel CXX C)
set(CMAKE_CXX_STANDARD 17)
set(LLVM_PATH /usr/lib/llvm-16)
set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
find_package(LLVM REQUIRED CONFIG)
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
include_directories(${LLVM_PATH}/include)
add_subdirectory(helloPass)
In helloPass/CMakeLists.txt:
cmake_minimum_required(VERSION 3.25)
add_library(HelloPass MODULE hello.cpp)
set_target_properties(HelloPass PROPERTIES
COMPILE_FLAGS "-fno-rtti"
)
In helloPass/hello.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
And the following is just to build the project like :
mkdir build && cd build
cmake ..
make
Now the libHelloPass.so is generated. It works fine till here. But it fails in the invocation.
I try to use opt to load the helloPass as the documentation Running a pass with opt¶ said but it fails with "opt: unknown pass name 'hello'". The opt command is like: opt -load build/helloPass/libHelloPass.so -p hello test.bc > /dev/null. I do a bit modification here followed the doc Invoking opt.
I also tried just list all passes but not found a pass called "hello" but only a "helloworld", which is not defined by me. opt -load build/helloPass/libHelloPass.so --print-passes | grep hello
Anyone can help me about this?
I have checked the paths of llvm-related tools like opt, clang, clang++, which are all located at /usr/lib/llvm-16/bin
opt -load-pass-plugin build/helloPass/libHelloPass.so -passes="hello"?