我有一个包含一堆数据的文件。我想将其转换为C ++字符串文字,因为我需要将此数据编译为二进制文件-无法从磁盘读取它。
执行此操作的一种方法是仅生成一个C ++源文件,该文件声明具有已知名称的字符串文字。 CMake代码很简单,即使有些糟糕:
function(make_literal_from_file dest_file source_file literal_name)
add_custom_command(
OUTPUT ${dest_file}
COMMAND printf \'char const* ${literal_name} = R\"\#\(\' > ${dest_file}
COMMAND cat ${source_file} >> ${dest_file}
COMMAND printf \'\)\#\"\;\' >> ${dest_file}
DEPENDS ${source_file})
endfunction()
这有效并且可以完成我想要的操作(printf
是必需的,以避免在原始字符串介绍器之后出现新行)。但是,这里发生的大量转义使得很难看到正在发生的事情。有没有一种方法可以编写此函数使其真正可读?
请注意,此处不能使用file(READ ...)
/ configure_file(...)
组合,因为source_file
可能是CMake在构建时生成的,因此在配置时可能不存在。 / p>
答案 0 :(得分:2)
我建议编写脚本来执行此操作。您可以用CMake编写它,但是我个人更喜欢更好的语言,例如Python:
# Untested, just to show roughly how to do it
import sys
dest_file, source_file, literal_name = sys.argv[1:]
with open(dest_file) as dest, open(source_file) as source:
literal_contents = source.read()
dest.write(f'char const* {literal_name} = R"({literal_contents})";\n')
对应的CMake代码:
# String interpolation came in Python 3.6, thus the requirement on 3.6.
# If using CMake < 3.12, use find_package(PythonInterp) instead.
find_package(Python3 3.6 COMPONENTS Interpreter)
# Make sure this resolves correctly. ${CMAKE_CURRENT_LIST_DIR} is helpful;
# it's the directory containing the current file (this cmake file)
set(make_literal_from_file_script "path/to/make_literal_from_file.py")
function(make_literal_from_file dest_file source_file literal_name)
add_custom_command(
OUTPUT "${dest_file}"
COMMAND
"${Python3_EXECUTABLE}" "${make_literal_from_file_script}"
"${dest_file}"
"${source_file}"
"${literal_name}"
DEPENDS "${source_file}")
endfunction()
如果您不希望依赖于Python,则可以使用C ++(仅显示CMake代码):
add_executable(make_literal_from_file_exe
path/to/cpp/file.cpp
)
function(make_literal_from_file dest_file source_file literal_name)
add_custom_command(
OUTPUT "${dest_file}"
COMMAND
make_literal_from_file_exe
"${dest_file}"
"${source_file}"
"${literal_name}"
DEPENDS "${source_file}")
endfunction()