cmakelazy-c++

How do I make build rules in cmake to preprocess lazy C++ .lzz files that generate .h and .cpp files?


What I'd like to do is write just Lazy C++ .lzz files and then have lzz run before a build to generate .cpp and .h files that will be built into the final application, sort of like how moc works with Qt.

Is there any way to do this?


Solution

  • Here is an example of how to do this... First you need to find the lzz program, for that use the find_program command:

    find_program(LZZ_COMMAND lzz)
    

    This sets LZZ_COMMAND to the path of the compiler. Then use a CMake custom command to compile the LZZ file to their C++ header/implementation files:

    add_custom_command(
        OUTPUT ${output}
        COMMAND ${LZZ_COMMAND} -o ${CMAKE_CURRENT_BINARY_DIR} ${filename})
    

    That generates the files in the current build directory, in case you do out-of-source builds. You will also need to specify that the outputs are generated files:

    set_source_files_properties(${output} PROPERTIES GENERATED TRUE)
    

    Put that all together and you get a CMakeLists.txt file something like this:

    cmake_minimum_required(VERSION 2.8)
    project(lazy_test)
    find_program(LZZ_COMMAND lzz)
    function(lazy_compile filename)
        get_filename_component(base ${filename} NAME_WE)
        set(base_abs ${CMAKE_CURRENT_BINARY_DIR}/${base})
        set(output ${base_abs}.cpp ${base_abs}.h)
        add_custom_command(
            OUTPUT ${output}
            COMMAND ${LZZ_COMMAND} -o ${CMAKE_CURRENT_BINARY_DIR} ${filename})
        set_source_files_properties(${output} PROPERTIES GENERATED TRUE)
    endfunction()
    lazy_compile(${CMAKE_CURRENT_SOURCE_DIR}/example.lzz)
    add_executable(test example.cpp example.h)
    

    You would probably also want to add include path and other options to lzz eventually. If you placed all the Lazy C++ stuff into a module file and included that from the CMakeLists.txt it would be a bit cleaner. But this is the basic idea.