123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #[==[
- @file vtkEncodeString.cmake
- This module contains the @ref vtk_encode_string function which may be used to
- turn a file into a C string. This is primarily used within a program so that
- the content does not need to be retrieved from the filesystem at runtime, but
- can still be developed as a standalone file.
- #]==]
- set(_vtkEncodeString_script_file "${CMAKE_CURRENT_LIST_FILE}")
- include(CMakeParseArguments)
- #[==[
- @brief Encode a file as a C string at build time
- Adds a rule to turn a file into a C string. Note that any Unicode characters
- will not be replaced with escaping, so it is recommended to avoid their usage
- in the input.
- ~~~
- vtk_encode_string
- INPUT <input>
- [NAME <name>]
- [EXPORT_SYMBOL <symbol>]
- [EXPORT_HEADER <header>]
- [HEADER_OUTPUT <variable>]
- [SOURCE_OUTPUT <variable>]
- [BINARY] [NUL_TERMINATE])
- ~~~
- The only required variable is `INPUT`, however, it is likely that at least one
- of `HEADER_OUTPUT` or `SOURCE_OUTPUT` will be required to add them to a
- library.
- * `INPUT`: (Required) The path to the file to be embedded. If a relative path
- is given, it will be interpreted as being relative to
- `CMAKE_CURRENT_SOURCE_DIR`.
- * `NAME`: This is the base name of the files that will be generated as well
- as the variable name for the C string. It defaults to the basename of the
- input without extensions.
- * `EXPORT_SYMBOL`: The symbol to use for exporting the variable. By default,
- it will not be exported. If set, `EXPORT_HEADER` must also be set.
- * `EXPORT_HEADER`: The header to include for providing the given export
- symbol. If set, `EXPORT_SYMBOL` should also be set.
- * `HEADER_OUTPUT`: The variable to store the generated header path.
- * `SOURCE_OUTPUT`: The variable to store the generated source path.
- * `BINARY`: If given, the data will be written as an array of `unsigned char`
- bytes.
- * `NUL_TERMINATE`: If given, the binary data will be `NUL`-terminated. Only
- makes sense with the `BINARY` flag. This is intended to be used if
- embedding a file as a C string exceeds compiler limits on string literals
- in various compilers.
- #]==]
- function (vtk_encode_string)
- cmake_parse_arguments(_vtk_encode_string
- "BINARY;NUL_TERMINATE"
- "INPUT;NAME;EXPORT_SYMBOL;EXPORT_HEADER;HEADER_OUTPUT;SOURCE_OUTPUT"
- ""
- ${ARGN})
- if (_vtk_encode_string_UNPARSED_ARGUMENTS)
- message(FATAL_ERROR
- "Unrecognized arguments to vtk_encode_string: "
- "${_vtk_encode_string_UNPARSED_ARGUMENTS}")
- endif ()
- if (NOT DEFINED _vtk_encode_string_INPUT)
- message(FATAL_ERROR
- "Missing `INPUT` for vtk_encode_string.")
- endif ()
- if (NOT DEFINED _vtk_encode_string_NAME)
- get_filename_component(_vtk_encode_string_NAME
- "${_vtk_encode_string_INPUT}" NAME_WE)
- endif ()
- if (DEFINED _vtk_encode_string_EXPORT_SYMBOL AND
- NOT DEFINED _vtk_encode_string_EXPORT_HEADER)
- message(FATAL_ERROR
- "Missing `EXPORT_HEADER` when using `EXPORT_SYMBOL`.")
- endif ()
- if (DEFINED _vtk_encode_string_EXPORT_HEADER AND
- NOT DEFINED _vtk_encode_string_EXPORT_SYMBOL)
- message(WARNING
- "Missing `EXPORT_SYMBOL` when using `EXPORT_HEADER`.")
- endif ()
- if (NOT _vtk_encode_string_BINARY AND _vtk_encode_string_NUL_TERMINATE)
- message(FATAL_ERROR
- "The `NUL_TERMINATE` flag only makes sense with the `BINARY` flag.")
- endif ()
- set(_vtk_encode_string_header
- "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.h")
- set(_vtk_encode_string_source
- "${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.cxx")
- if (IS_ABSOLUTE "${_vtk_encode_string_INPUT}")
- set(_vtk_encode_string_input
- "${_vtk_encode_string_INPUT}")
- else ()
- set(_vtk_encode_string_input
- "${CMAKE_CURRENT_SOURCE_DIR}/${_vtk_encode_string_INPUT}")
- endif ()
- add_custom_command(
- OUTPUT ${_vtk_encode_string_header}
- ${_vtk_encode_string_source}
- DEPENDS "${_vtkEncodeString_script_file}"
- "${_vtk_encode_string_input}"
- COMMAND "${CMAKE_COMMAND}"
- "-Dsource_dir=${CMAKE_CURRENT_SOURCE_DIR}"
- "-Dbinary_dir=${CMAKE_CURRENT_BINARY_DIR}"
- "-Dsource_file=${_vtk_encode_string_input}"
- "-Doutput_name=${_vtk_encode_string_NAME}"
- "-Dexport_symbol=${_vtk_encode_string_EXPORT_SYMBOL}"
- "-Dexport_header=${_vtk_encode_string_EXPORT_HEADER}"
- "-Dbinary=${_vtk_encode_string_BINARY}"
- "-Dnul_terminate=${_vtk_encode_string_NUL_TERMINATE}"
- "-D_vtk_encode_string_run=ON"
- -P "${_vtkEncodeString_script_file}")
- if (DEFINED _vtk_encode_string_SOURCE_OUTPUT)
- set("${_vtk_encode_string_SOURCE_OUTPUT}"
- "${_vtk_encode_string_source}"
- PARENT_SCOPE)
- endif ()
- if (DEFINED _vtk_encode_string_HEADER_OUTPUT)
- set("${_vtk_encode_string_HEADER_OUTPUT}"
- "${_vtk_encode_string_header}"
- PARENT_SCOPE)
- endif ()
- endfunction ()
- if (_vtk_encode_string_run AND CMAKE_SCRIPT_MODE_FILE)
- set(output_header "${binary_dir}/${output_name}.h")
- set(output_source "${binary_dir}/${output_name}.cxx")
- file(WRITE "${output_header}" "")
- file(WRITE "${output_source}" "")
- file(APPEND "${output_header}"
- "#ifndef ${output_name}_h\n#define ${output_name}_h\n\n")
- if (export_symbol)
- file(APPEND "${output_header}"
- "#include \"${export_header}\"\n\n${export_symbol} ")
- endif ()
- if (IS_ABSOLUTE "${source_file}")
- set(source_file_full "${source_file}")
- else ()
- set(source_file_full "${source_dir}/${source_file}")
- endif ()
- set(hex_arg)
- if (binary)
- set(hex_arg HEX)
- endif ()
- file(READ "${source_file_full}" original_content ${hex_arg})
- if (binary)
- if (nul_terminate)
- string(APPEND original_content "00")
- endif ()
- string(LENGTH "${original_content}" output_size)
- math(EXPR output_size "${output_size} / 2")
- file(APPEND "${output_header}"
- "extern const unsigned char ${output_name}[${output_size}];\n\n#endif\n")
- file(APPEND "${output_source}"
- "#include \"${output_name}.h\"\n\nconst unsigned char ${output_name}[${output_size}] = {\n")
- string(REGEX REPLACE "\([0-9a-f][0-9a-f]\)" ",0x\\1" escaped_content "${original_content}")
- # Hard line wrap the file.
- string(REGEX REPLACE "\(..........................................................................,\)" "\\1\n" escaped_content "${escaped_content}")
- # Remove the leading comma.
- string(REGEX REPLACE "^," "" escaped_content "${escaped_content}")
- file(APPEND "${output_source}"
- "${escaped_content}\n")
- file(APPEND "${output_source}"
- "};\n")
- else ()
- file(APPEND "${output_header}"
- "extern const char *${output_name};\n\n#endif\n")
- # Escape literal backslashes.
- string(REPLACE "\\" "\\\\" escaped_content "${original_content}")
- # Escape literal double quotes.
- string(REPLACE "\"" "\\\"" escaped_content "${escaped_content}")
- # Turn newlines into newlines in the C string.
- string(REPLACE "\n" "\\n\"\n\"" escaped_content "${escaped_content}")
- file(APPEND "${output_source}"
- "#include \"${output_name}.h\"\n\nconst char *${output_name} =\n")
- file(APPEND "${output_source}"
- "\"${escaped_content}\";\n")
- endif ()
- endif ()
|