LLVM Discussion Forums

How to create pass independently on Windows?

I’m trying to develop tranforms pass out-of-source. I create the Project folder out of the llvm source, and link the cmake to the llvm include header. After I compile the pass to DLL successfully , I found I can’t load it to the clang or opt.exe.
How can I make the pass as a DLL to let clang load on Windows platform? (I just want to make the pass project out of source to separate), tks


This is quite non-trivial thing on Windows as DLL needs to import lots of things from the executable which is not what Windows binaries are designed for. You try to compile LLVM into DLL, but still there are lots of issues on the way.

1 Like


Making this work on Windows is much tricker than on Linux or Mac OS. My suggestion would be to try on either Linux or Mac OS first.

This should in principle work on Windows too. I don’t have a Windows machine so I can’t really verify myself, but this patch: https://reviews.llvm.org/D18826 added LLVM_EXPORT_SYMBOLS_FOR_PLUGINS. You need to use that flag when building LLVM (yes, you need to build from sources) and hopefully that will be enough for the build system to export all the symbols that you may need.

I haven’t really tested this myself, so I would be really interested to hear if you get it to work :slight_smile:

Kind regards,

1 Like

I suddenly find the loadable modules don’t support my Windows when I cmake

And I check the AddLLVM.cmake again, find that I should define ARG_PLUGIN_TOOL as well adapted to LLVM_EXPORT_SYMBOLS_FOR_PLUGINS

Thanks a lot. In a nutshell, IT WORKS!!!
After a long time struggling to compile and test, finally I successfully load the pass dll to opt, LLVM_EXPORT_SYMBOLS_FOR_PLUGINS really works. Thanks again.

Anyway, I write and build code under the llvm source code following the llvm documents. But each time I build the pass with VisualStudio or Clion on either Linux or Windows costs a lot of time.
I wonder whether I can build the pass out-of-source. I have follow some articles about out-of-source-tree build, the tips are quite rare, and I always fail to build. Because If build out-of-source, I can’t use llvm cmake command like add_llvm_loadable_module. I wonder whether there are some tips to notice when build pass out-of-source ( i just upload my pass project here https://github.com/pcy190/tmp_pass

[ 93%] Building CXX object CMakeFiles/LLVMObfuscation.dir/src/AddPasses/Register_Passes.cpp.obj
[100%] Linking CXX shared library libLLVMObfuscation.dll
CMakeFiles\LLVMObfuscation.dir/objects.a(Register_Passes.cpp.obj): In function `llvm::RegisterStandardPasses::RegisterStandardPasses(llvm::PassManagerBuilder::ExtensionPointTy, std::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>)':
I:/llvm_research/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h:212: undefined reference to `llvm::PassManagerBuilder::addGlobalExtension(llvm::PassManagerBuilder::ExtensionPointTy, std::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>)'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `initializeObfuscationPassOnce':
I:/llvm_research/HikariCore/src/PassScheduler.cpp:225: undefined reference to `llvm::PassRegistry::registerPass(llvm::PassInfo const&, bool)'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `llvm::Value::assertModuleIsMaterialized() const':
I:/llvm_research/llvm/include/llvm/IR/Value.h:318: undefined reference to `llvm::Value::assertModuleIsMaterializedImpl() const'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `llvm::raw_ostream::operator<<(llvm::StringRef)':
I:/llvm_research/llvm/include/llvm/Support/raw_ostream.h:174: undefined reference to `llvm::raw_ostream::write(char const*, unsigned long long)'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `llvm::cl::parser<bool>::parser(llvm::cl::Option&)':
I:/llvm_research/llvm/include/llvm/Support/CommandLine.h:865: undefined reference to `llvm::cl::basic_parser<bool>::basic_parser(llvm::cl::Option&)'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `llvm::cl::parser<unsigned long long>::parser(llvm::cl::Option&)':
I:/llvm_research/llvm/include/llvm/Support/CommandLine.h:965: undefined reference to `llvm::cl::basic_parser<unsigned long long>::basic_parser(llvm::cl::Option&)'
libLLVMObfuscationCommon.a(PassScheduler.cpp.obj): In function `llvm::Obfuscation::runOnModule(llvm::Module&)':
I:/llvm_research/HikariCore/src/PassScheduler.cpp:123: undefined reference to `llvm::GlobalValue::isDeclaration() const'
I:/llvm_research/HikariCore/src/PassScheduler.cpp:146: undefined reference to `llvm::GlobalValue::isDeclaration() const'
I:/llvm_research/HikariCore/src/PassScheduler.cpp:164: undefined reference to `llvm::errs()'

Hello @HAPPY,

I’m glad that it has worked! Could you please share your CMake command for building LLVM?

As for out-of-tree pass development, I’ve tried my best to document it here (it’s up-to-date):

As you’ll notice, I don’t cover Windows. I have no access to any Windows machines ATM, but I would be very keen to learn what the additional requirements are.

Btw, in your GitHub project you don’t seem to use add_llvm_loadable_module - is that the latest version of your pass? And yes, you do get access to that CMake method even when working out-of-tree. It’s made available by calling find_package(LLVM REQUIRED CONFIG), which you already do.

I hope that this helps!

Thanks for reply.

After set LLVM_EXPORT_SYMBOLS_FOR_PLUGINS ON in HandleLLVMOptions.cmake file, I build with the following cmake command.