Как мне создать правила сборки в cmake для предварительной обработки ленивых файлов C++ .lzz, которые генерируют файлы.h и.cpp?
Я хотел бы написать только файлы Lazy C++ .lzz, а затем запустить lzz перед сборкой, чтобы сгенерировать файлы.cpp и.h, которые будут встроены в конечное приложение, что-то вроде того, как moc работает с Qt.
Есть какой-либо способ сделать это?
3 ответа
Вот пример того, как это сделать... Сначала вам нужно найти lzz
программа, для этого используйте find_program
команда:
find_program(LZZ_COMMAND lzz)
Это устанавливает LZZ_COMMAND
к пути компилятора. Затем используйте пользовательскую команду 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, это будет немного чище. Но это основная идея.
Я просто хотел поделиться своим CMakeLists.txt, который основан на скрипте richq. Файлы *.cpp и *.hpp теперь должным образом зависят от файлов *.lzz. Файлы *.lzz добавляются в проект (который отвечает на отсутствующий вопрос выше), но хранятся отдельно от сгенерированных файлов с помощью команды 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})
Для изготовления:
sourcecode.h sourcecode.cpp: sourcecode.lzz
<TAB>lazy-cpp sourcecode.lzz
заполните sourcecode.h, sourcecode.cpp и lazy-cpp правильными значениями. Я их не знаю