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

后端 未结 3 1451
粉色の甜心
粉色の甜心 2020-12-31 19:05

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

相关标签:
3条回答
  • 2020-12-31 19:43

    For make:

    sourcecode.h sourcecode.cpp: sourcecode.lzz
    <TAB>lazy-cpp sourcecode.lzz
    

    fill in sourcecode.h, sourcecode.cpp, and lazy-cpp with the correct values. I don't know them.

    0 讨论(0)
  • 2020-12-31 19:51

    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.

    0 讨论(0)
  • 2020-12-31 20:00

    I just wanted to share my CMakeLists.txt, which builds upon richq's script. The *.cpp and *.hpp files now properly depend on the *.lzz files. The *.lzz files are added to the project (which answers absense's question above) but kept separate from the generated files using the source_group command.

    The only remaining dealbreaker for me is the inability to compile the current file for *.lzz files.

    cmake_minimum_required(VERSION 2.8)
    
    PROJECT(LzzTest)
    
    find_program(LZZ_COMMAND lzz.exe)
    
    # Syntax: 
    #   add_lzz_file(<output> <lzz file>)
    # Adds a build rule for the specified lzz file. The absolute paths of the generated 
    # files are added to the <output> list. The files are generated in the binary dir.
    # 
    # TODO: Support for generating template files etc.
    function(add_lzz_file output filename)
      # Only process *.lzz files
      get_filename_component(ext ${filename} EXT)
      if(NOT ext STREQUAL ".lzz")
        return()
      endif()
    
      set(header_extension "hpp")
      get_filename_component(base ${filename} NAME_WE)
      set(base_abs ${CMAKE_CURRENT_BINARY_DIR}/${base})
      set(outfiles ${base_abs}.cpp ${base_abs}.${header_extension})
      set(${output} ${${output}} ${outfiles} PARENT_SCOPE)
    
      #message("outfiles=${outfiles}, DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${filename}")
      add_custom_command(
        OUTPUT ${outfiles}
        COMMAND ${LZZ_COMMAND} 
          -o ${CMAKE_CURRENT_BINARY_DIR} # output dir
          -hx ${header_extension}
          -sl -hl -il -tl -nl -x # insert #line commands w/ absolute paths
          -sd -hd -id -td -nd # don't output files that didn't change
          ${CMAKE_CURRENT_SOURCE_DIR}/${filename}
        DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${filename}"
      )
    
      set_source_files_properties(${outfiles} PROPERTIES GENERATED TRUE)
    endfunction()
    
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    
    set(SOURCES
      A.lzz
      B.lzz
      main.cpp
    )
    
    foreach(file ${SOURCES})
      add_lzz_file(GENERATED_SOURCES ${file})
    endforeach()
    
    source_group("" FILES ${SOURCES})
    source_group(generated FILES ${GENERATED_SOURCES})
    
    add_executable(LzzTest ${SOURCES} ${GENERATED_SOURCES})
    
    0 讨论(0)
提交回复
热议问题