Search code examples
c++llvmlibclanglibtooling

How to use cmake build config to run llvm libclang tool that is not a plugin over my whole code base?


I have written a llvm plugin and made a cmake object library that runs the plugin over each source file, but I need to have data from the whole compilation, whereas a plugin is run again for each compilation unit.

My build environment is fairly complex, however, and I don't want to manage a second representation of the configuration just for running this tool.

How can I use my existing CMakeLists.txt to send things like #define's and include paths to a tool that can run over my entire code base in one run?

I've considered trying to use Coliru's unity build on a plugin, since it would be a single compilation unit, but was hoping for something built in to cmake (maybe combined with a few command line tools) that could get the information that I need. I could also do a multi-pass run where I build up a bunch of data files and then make a different tool to combine those, but that's not ideal, either.

Thank you.


Solution

  • I ended up using the cotire module (https://github.com/sakra/cotire) and configuring its unity build feature (where it bundles up all your source into a single file to compile) and running over that.

    While unity builds aren't 100% compatible with c++, as they break file-level boundaries, it worked for me.

    It was a little tricky to set it up and I'm not sure I did it the best way, but what I did was I put the following in a subdirectory and put add_subdirectory(my_directory_name) in my main CMakeLists.txt file:

    MACRO(ADD_CXX_FLAGS)
      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGN}")
    #  MESSAGE(${CMAKE_CXX_FLAGS})
    ENDMACRO(ADD_CXX_FLAGS)
    
    
    # target_compile_options is the "better" way to do this but it dedupes flags,
    #   so the multiple -Xclang flags after the first one get lost.  There is a cmake bug on this but no one
    #   is working on it at this time
    ADD_CXX_FLAGS(-Xclang)
    ADD_CXX_FLAGS(-load)
    ADD_CXX_FLAGS(-Xclang)
    ADD_CXX_FLAGS(my_plugin.dylib) <== substitute yours here
    ADD_CXX_FLAGS(-Xclang)
    ADD_CXX_FLAGS(-plugin)
    ADD_CXX_FLAGS(-Xclang)
    ADD_CXX_FLAGS(MyPluginRegisteredName) <== substitute yours here
    
    
    #
    add_library(apb-js-api-template OBJECT ${APB_SOURCE_FILES})
    set_target_properties(some-project-name-template PROPERTIES COTIRE_UNITY_TARGET_NAME "some-project-name")
    cotire(some-project-name-template)