The previous article LLVM & Clang Getting Started covered how to write a Clang plug-in and compile it into a.dylib dynamic link library. You can see the effect (correct results) when you integrate it into Xcode.

An essential step in getting the right result is debugging, and no program can do that overnight unless you print a “Hello, World!” Maybe your world is written in Word.

In Plugin mode we can’t break the point to Debug, but we can add a log to the code, and then run the command in the terminal to see the log to Debug. Is this Low efficiency what you want? Obviously not.

We can break point debug simply by turning the.dylib dynamic library into an executable file. LibTooling may be a good choice. With LibTooling, we only need to change a few parts of the code.

LibTooling introduction:

LibTooling is a stand-alone library that allows users to easily build their own compiler front end tool. It is based on the C++ interface and provides users with powerful AST parsing and control capabilities. At the same time, its version compatibility is much worse than that of libclang because it is too close to the Clang kernel. Changes in Clang are likely to affect LibTooling. LibTooling also provides a complete parameter resolution scheme, making it easy to build a stand-alone command line tool.

Create the LibTooling project and code adjustments

For convenience, we will directly create an executable LibTooling project. We can create a project named QTPluginTooling.

  1. The creation process is similar to that of plug-in. The first 3 steps are the same. Only QTPlugin needs to be replaced with QTPluginTooling.

  2. However, in step 4, the contents of the cmakelists. TXT file in QTPluginTooling directory are slightly different

    set(LLVM_LINK_COMPONENTS
        Support
    )
    
    add_clang_executable(QTPluginTooling
        QTPluginTooling.cpp
    )
    
    target_link_libraries(QTPluginTooling
        PRIVATE
        clangAST
        clangBasic
        clangDriver
        clangFormat
        clangLex
        clangParse
        clangSema
        clangFrontend
        clangTooling
        clangToolingCore
        clangRewrite
        clangRewriteFrontend
    )
    
    if (UNIX)
        set(CLANGXX__LING_OR_COPY create_symlink)
    else(a)set(CLANGXX_LINK_OR_COPY copy)
    endif()
    Copy the code

  3. $cmake -g Xcode.. / LLVM, regenerate the Xcode project. Tooling project can be found in Xcode’s Clang Executables directory.

  4. Copy the code from the previous Plugin and add three header files

    #include "clang/Tooling/CommonOptionsParser.h"
    #include "clang/Frontend/FrontendActions.h"
    #include "clang/Tooling/Tooling.h"
    Copy the code
  5. Add a new namespace

    using namespace clang::tooling;
    Copy the code
  6. Change the inheritance of QTASTAction to ASTFrontendAction.

  7. Annotate how FrontendPluginRegistry registers plug-ins. Change to the main() function

    static llvm::cl::OptionCategory OptsCategory("QTPlugin");
    int main(int argc, const char **argv) {
        CommonOptionsParser op(argc, argv, OptsCategory);
        ClangTool Tool(op.getCompilations(), op.getSourcePathList());
        return Tool.run(newFrontendActionFactory<QTPlugin::QTASTAction>().get());
    }
    Copy the code

Finally the entire contents of the file can be inQTPluginTooling.cppSee it.

The input source

If you run at this point, you’ll just quit. This is because there is no “input source”. We can add in the Scheme of QTPluginTooling.

/Users/laiyoung_/Desktop/Plugin/ViewController.m -- -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk - isystem - I/Applications/Xcode. The app/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/lib/clang 10.0.0 / include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/i nclude -F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/Syste m/Library/FrameworksCopy the code

Parameter description:

The arguments following the — above are passed to the CI Compilation DataBase, not to the command-line tool itself. For example, our viewController.m, because of the statement #import

, and the inheritance from UIViewController, So when the Sema reads this, it needs to know where the definition of UIViewController is coming from, in other words it needs to find where the definition of UIViewController is. How do I find it? You can search for the directory specified by the specified -i and -f parameters. If you want to compile viewController. m, you need to pass the arguments to our QTPlugin. Otherwise, you will see an error in the Console stating that the XXX definition or the xxx.h file cannot be found. Of course, because of the usual compile instructions, there is a -c argument that specifies the source file, but — is not needed because we specified it before –. -extra-arg=” XXXX “is used to specify the compile parameter, so there is no need for –.

-extra-arg="-Ixxxxxx"
-extra-arg="-Fxxxxxx"
-extra-arg="-isysroot xxxxxx"XXXXXX indicates the pathCopy the code

Final result:

Reference article:

  • Build iOS CLAS System based on Clang LibTooling (ii)
  • Compilation databases for Clang-based tools

If there is any error in the content, you are welcome to issue correction.

Example

Reprint please indicate the source!