VTK  9.1.0
vtkEncodeString.cmake
Go to the documentation of this file.
1#[==[
2@file vtkEncodeString.cmake
3
4This module contains the @ref vtk_encode_string function which may be used to
5turn a file into a C string. This is primarily used within a program so that
6the content does not need to be retrieved from the filesystem at runtime, but
7can still be developed as a standalone file.
8#]==]
9
10set(_vtkEncodeString_script_file "${CMAKE_CURRENT_LIST_FILE}")
11
12#[==[
13@brief Encode a file as a C string at build time
14
15Adds a rule to turn a file into a C string. Note that any Unicode characters
16will not be replaced with escaping, so it is recommended to avoid their usage
17in the input.
18
19~~~
20vtk_encode_string
21 INPUT <input>
22 [NAME <name>]
23 [EXPORT_SYMBOL <symbol>]
24 [EXPORT_HEADER <header>]
25 [HEADER_OUTPUT <variable>]
26 [SOURCE_OUTPUT <variable>]
27 [BINARY] [NUL_TERMINATE])
28~~~
29
30The only required variable is `INPUT`, however, it is likely that at least one
31of `HEADER_OUTPUT` or `SOURCE_OUTPUT` will be required to add them to a
32library.
33
34 * `INPUT`: (Required) The path to the file to be embedded. If a relative path
35 is given, it will be interpreted as being relative to
36 `CMAKE_CURRENT_SOURCE_DIR`.
37 * `NAME`: This is the base name of the files that will be generated as well
38 as the variable name for the C string. It defaults to the basename of the
39 input without extensions.
40 * `EXPORT_SYMBOL`: The symbol to use for exporting the variable. By default,
41 it will not be exported. If set, `EXPORT_HEADER` must also be set.
42 * `EXPORT_HEADER`: The header to include for providing the given export
43 symbol. If set, `EXPORT_SYMBOL` should also be set.
44 * `HEADER_OUTPUT`: The variable to store the generated header path.
45 * `SOURCE_OUTPUT`: The variable to store the generated source path.
46 * `BINARY`: If given, the data will be written as an array of `unsigned char`
47 bytes.
48 * `NUL_TERMINATE`: If given, the binary data will be `NUL`-terminated. Only
49 makes sense with the `BINARY` flag. This is intended to be used if
50 embedding a file as a C string exceeds compiler limits on string literals
51 in various compilers.
52#]==]
54 cmake_parse_arguments(PARSE_ARGV 0 _vtk_encode_string
55 "BINARY;NUL_TERMINATE"
56 "INPUT;NAME;EXPORT_SYMBOL;EXPORT_HEADER;HEADER_OUTPUT;SOURCE_OUTPUT"
57 "")
58
59 if (_vtk_encode_string_UNPARSED_ARGUMENTS)
60 message(FATAL_ERROR
61 "Unrecognized arguments to vtk_encode_string: "
62 "${_vtk_encode_string_UNPARSED_ARGUMENTS}")
63 endif ()
64
65 if (NOT DEFINED _vtk_encode_string_INPUT)
66 message(FATAL_ERROR
67 "Missing `INPUT` for vtk_encode_string.")
68 endif ()
69
70 if (NOT DEFINED _vtk_encode_string_NAME)
71 get_filename_component(_vtk_encode_string_NAME
72 "${_vtk_encode_string_INPUT}" NAME_WE)
73 endif ()
74
75 if (DEFINED _vtk_encode_string_EXPORT_SYMBOL AND
76 NOT DEFINED _vtk_encode_string_EXPORT_HEADER)
77 message(FATAL_ERROR
78 "Missing `EXPORT_HEADER` when using `EXPORT_SYMBOL`.")
79 endif ()
80
81 if (DEFINED _vtk_encode_string_EXPORT_HEADER AND
82 NOT DEFINED _vtk_encode_string_EXPORT_SYMBOL)
83 message(WARNING
84 "Missing `EXPORT_SYMBOL` when using `EXPORT_HEADER`.")
85 endif ()
86
87 if (NOT _vtk_encode_string_BINARY AND _vtk_encode_string_NUL_TERMINATE)
88 message(FATAL_ERROR
89 "The `NUL_TERMINATE` flag only makes sense with the `BINARY` flag.")
90 endif ()
91
92 set(_vtk_encode_string_header
93 "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.h")
94 set(_vtk_encode_string_source
95 "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.cxx")
96
97 if (IS_ABSOLUTE "${_vtk_encode_string_INPUT}")
98 set(_vtk_encode_string_input
99 "${_vtk_encode_string_INPUT}")
100 else ()
101 set(_vtk_encode_string_input
102 "${CMAKE_CURRENT_SOURCE_DIR}/${_vtk_encode_string_INPUT}")
103 endif ()
104
105 add_custom_command(
106 OUTPUT ${_vtk_encode_string_header}
107 ${_vtk_encode_string_source}
108 DEPENDS "${_vtkEncodeString_script_file}"
109 "${_vtk_encode_string_input}"
110 COMMAND "${CMAKE_COMMAND}"
111 "-Dsource_dir=${CMAKE_CURRENT_SOURCE_DIR}"
112 "-Dbinary_dir=${CMAKE_CURRENT_BINARY_DIR}"
113 "-Dsource_file=${_vtk_encode_string_input}"
114 "-Doutput_name=${_vtk_encode_string_NAME}"
115 "-Dexport_symbol=${_vtk_encode_string_EXPORT_SYMBOL}"
116 "-Dexport_header=${_vtk_encode_string_EXPORT_HEADER}"
117 "-Dbinary=${_vtk_encode_string_BINARY}"
118 "-Dnul_terminate=${_vtk_encode_string_NUL_TERMINATE}"
119 "-D_vtk_encode_string_run=ON"
120 -P "${_vtkEncodeString_script_file}")
121
122 if (DEFINED _vtk_encode_string_SOURCE_OUTPUT)
123 set("${_vtk_encode_string_SOURCE_OUTPUT}"
124 "${_vtk_encode_string_source}"
125 PARENT_SCOPE)
126 endif ()
127
128 if (DEFINED _vtk_encode_string_HEADER_OUTPUT)
129 set("${_vtk_encode_string_HEADER_OUTPUT}"
130 "${_vtk_encode_string_header}"
131 PARENT_SCOPE)
132 endif ()
133endfunction ()
134
135if (_vtk_encode_string_run AND CMAKE_SCRIPT_MODE_FILE)
136 set(output_header "${binary_dir}/${output_name}.h")
137 set(output_source "${binary_dir}/${output_name}.cxx")
138
139 file(WRITE "${output_header}" "")
140 file(WRITE "${output_source}" "")
141
142 file(APPEND "${output_header}"
143 "#ifndef ${output_name}_h\n#define ${output_name}_h\n\n")
144 if (export_symbol)
145 file(APPEND "${output_header}"
146 "#include \"${export_header}\"\n\n${export_symbol} ")
147 endif ()
148
149 if (IS_ABSOLUTE "${source_file}")
150 set(source_file_full "${source_file}")
151 else ()
152 set(source_file_full "${source_dir}/${source_file}")
153 endif ()
154 set(hex_arg)
155 if (binary)
156 set(hex_arg HEX)
157 endif ()
158 file(READ "${source_file_full}" original_content ${hex_arg})
159
160 if (binary)
161 if (nul_terminate)
162 string(APPEND original_content "00")
163 endif ()
164 string(LENGTH "${original_content}" output_size)
165 math(EXPR output_size "${output_size} / 2")
166 file(APPEND "${output_header}"
167 "extern const unsigned char ${output_name}[${output_size}];\n\n#endif\n")
168
169 file(APPEND "${output_source}"
170 "#include \"${output_name}.h\"\n\nconst unsigned char ${output_name}[${output_size}] = {\n")
171 string(REGEX REPLACE "\‍([0-9a-f][0-9a-f]\‍)" ",0x\\1" escaped_content "${original_content}")
172 # Hard line wrap the file.
173 string(REGEX REPLACE "\‍(..........................................................................,\‍)" "\\1\n" escaped_content "${escaped_content}")
174 # Remove the leading comma.
175 string(REGEX REPLACE "^," "" escaped_content "${escaped_content}")
176 file(APPEND "${output_source}"
177 "${escaped_content}\n")
178 file(APPEND "${output_source}"
179 "};\n")
180 else ()
181 file(APPEND "${output_header}"
182 "extern const char *${output_name};\n\n#endif\n")
183
184 # Escape literal backslashes.
185 string(REPLACE "\\" "\\\\" escaped_content "${original_content}")
186 # Escape literal double quotes.
187 string(REPLACE "\"" "\\\"" escaped_content "${escaped_content}")
188 # Turn newlines into newlines in the C string.
189 string(REPLACE "\n" "\\n\"\n\"" escaped_content "${escaped_content}")
190
191 file(APPEND "${output_source}"
192 "#include \"${output_name}.h\"\n\nconst char *${output_name} =\n")
193 file(APPEND "${output_source}"
194 "\"${escaped_content}\";\n")
195 endif ()
196endif ()
@ on
Definition: vtkX3D.h:445
@ function
Definition: vtkX3D.h:255
@ time
Definition: vtkX3D.h:503
@ content
Definition: vtkX3D.h:308
@ name
Definition: vtkX3D.h:225
@ data
Definition: vtkX3D.h:321
@ string
Definition: vtkX3D.h:496
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
function vtk_encode_string()
Encode a file as a C string at build time.