如何在 cmake 中制定构建规则来预处理惰性 C++生成 .h 和 .cpp 文件的 .lzz 文件?

发布于 2024-08-29 14:12:21 字数 118 浏览 2 评论 0原文

我想做的是只编写 Lazy C++ .lzz 文件,然后在构建之前运行 lzz 以生成将构建到最终应用程序中的 .cpp 和 .h 文件,有点像 moc 与 Qt 的配合方式。

有什么办法可以做到这一点吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

巷雨优美回忆 2024-09-05 14:12:21

以下是如何执行此操作的示例...首先,您需要找到 lzz 程序,为此请使用 find_program 命令:

find_program(LZZ_COMMAND lzz)

这会设置 LZZ_COMMAND code> 到编译器的路径。然后使用 CMake 自定义命令将 LZZ 文件编译为其 C++ 头文件/实现文件:

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

这会在当前构建目录中生成文件,以防您进行源外构建。您还需要指定输出是生成的文件:

set_source_files_properties(${output} PROPERTIES GENERATED TRUE)

将它们放在一起,您将得到一个 CMakeLists.txt 文件,如下所示:

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)

您可能还希望最终向 lzz 添加包含路径和其他选项。如果您将所有 Lazy C++ 内容放入一个模块文件中并包含 CMakeLists.txt 中的内容,那么它会更干净一些。但这是基本思想。

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.

疑心病 2024-09-05 14:12:21

我只是想分享我的 CMakeLists.txt,它基于 richq 的脚本构建。 *.cpp 和 *.hpp 文件现在正确依赖于 *.lzz 文件。 *.lzz 文件被添加到项目中(这回答了上面absense 的问题),但使用source_group 命令与生成的文件分开。

对我来说唯一剩下的问题是无法编译 *.lzz 文件的当前文件。

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})

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})
眼眸印温柔 2024-09-05 14:12:21

对于 make:

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

使用正确的值填写 sourcecode.h、sourcecode.cpp 和lazy-cpp。我不认识他们。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文