Problem while compiling AST Matcher

Hi guys, I was recently trying to write my own Clang AST Matcher. I tried to compile and run the tutorial file from the Clang website first on my machine (the one that identifies the n::m::C variables in the target cpp file, you can see the source code on here → How to write RecursiveASTVisitor based ASTFrontendActions. — Clang 17.0.0git documentation (llvm.org) ).

However, when I run command clang++ -I /usr/local/include -L /usr/local/lib -fno-rtti -o matcher matcher.cpp in the terminal, I get this error report:

/usr/bin/ld: /tmp/matcher-6f1978.o: in function `main':
matcher.cpp:(.text+0x93): undefined reference to `clang::tooling::runToolOnCode(std::unique_ptr<clang::FrontendAction, std::default_delete<clang::FrontendAction> >, llvm::Twine const&, llvm::Twine const&, std::shared_ptr<clang::PCHContainerOperations>)'
...
/usr/bin/ld: /tmp/matcher-6f1978.o:(.data.rel.ro._ZTV20FindNamedClassAction[_ZTV20FindNamedClassAction]+0x90): undefined reference to `clang::FrontendAction::EndSourceFile()'
/usr/bin/ld: /tmp/matcher-6f1978.o:(.data.rel.ro._ZTV22FindNamedClassConsumer[_ZTV22FindNamedClassConsumer]+0x28): undefined reference to `clang::ASTConsumer::HandleTopLevelDecl(clang::DeclGroupRef)'
/usr/bin/ld: /tmp/matcher-6f1978.o:(.data.rel.ro._ZTV22FindNamedClassConsumer[_ZTV22FindNamedClassConsumer]+0x38): undefined reference to `clang::ASTConsumer::HandleInterestingDecl(clang::DeclGroupRef)'
/usr/bin/ld: /tmp/matcher-6f1978.o:(.data.rel.ro._ZTV22FindNamedClassConsumer[_ZTV22FindNamedClassConsumer]+0x60): undefined reference to `clang::ASTConsumer::HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef)'
/usr/bin/ld: /tmp/matcher-6f1978.o:(.data.rel.ro._ZTV22FindNamedClassConsumer[_ZTV22FindNamedClassConsumer]+0x68): undefined reference to `clang::ASTConsumer::HandleImplicitImportDecl(clang::ImportDecl*)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

The report is super long, all the errors are related to undefined reference to xxx. My inchoate guess is that the virtual functions of some base classes are not implemented.

Here is some background on the problem that might help:

  • Environment

    • Ubuntu 18.04

    • clang version 17.0.0
      Target: x86_64-unknown-linux-gnu
      Thread model: posix
      InstalledDir: /usr/local/bin
      Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
      Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
      Candidate multilib: .;@m64
      Selected multilib: .;@m64

    • gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)

  • I followed the instructions on Clang - Getting Started (llvm.org) to build the llvm project from the source code, and Clang was able to compile other simple .c and .cpp files as well. The problem seems to only happen when I need to use the Clang / LLVM library functions, because when I try to write AST traversal functions in other files, those files don’t compile properly either.

  • After checking, folder /usr/local/... does contain the header files needed for compilation, that’s the reason why I use the command mentioned before to compile.

I have no idea how to solve this problem, hope someone can help… Thank you very much! :sob:

You also need the libraries to link against; that’s the most likely cause of the undefined reference errors. If the libraries are in /usr/local/lib then you need to add the relevant -l options so the linker knows which libraries to look for.

Thanks for your reply! :heart:

I’ve tried to import only the parent folder ( /usr/local/include ) of the headers introduced in the source code, but it still raise the same error… I have taken a few screenshot pictures of the possibly related folders and put them in the following (Their sibling folders are unrelated to Clang or LLVM ) . Could you give me some suggestions to modify the compilation command?

Then these are the headers I imported:

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Tooling.h"

using namespace clang;

// ...

Anyway, thank you so much for your help! :sob:

The compiler is finding the headers just fine. That’s not the problem. The problem is that when then compiler runs the linker (/usr/bin/ld) it is unable to find the Clang libraries that your matcher program is trying to call. You are telling it a directory to search (/usr/local/lib) but not the names of the library files themselves. You need to find the names of the libraries and add them to your command line with the -l option.