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