# # This file is distributed under the MIT License. See LICENSE.md for details. # # Extracts definitions and generates C++ headers and implementations from the # given header files. # The definitions must be embedded as described in the docs for # tuple_tree_generator_extract_definitions_from_headers. function(tuple_tree_generator_cpp_from_headers # Name of the target to generate the code TARGET_NAME # List of C++ headers HEADERS # Delimiter used to mark comments embedding type schemas DELIMITER NAMESPACE # Output directory OUTPUT_DIR # Include path prefix INCLUDE_PATH_PREFIX # Variable will be filled with the list of generated C++ headers GENERATED_HEADERS_VARIABLE # Variable will be filled with the list of generated C++ source files GENERATED_IMPLS_VARIABLE ) set(COLLECTED_YAML_PATH "${OUTPUT_DIR}/schema.yml") tuple_tree_generator_extract_definitions_from_headers( "${HEADERS}" "${DELIMITER}" "${COLLECTED_YAML_PATH}" ) tuple_tree_generator_compute_generated_cpp_files( "${HEADERS}" "${OUTPUT_DIR}" LOCAL_GENERATED_HEADERS LOCAL_GENERATED_IMPLS ) tuple_tree_generator_generate_cpp( "${COLLECTED_YAML_PATH}" "${NAMESPACE}" "${OUTPUT_DIR}" "${INCLUDE_PATH_PREFIX}" "${LOCAL_GENERATED_HEADERS}" "${LOCAL_GENERATED_IMPLS}" ) set("${GENERATED_HEADERS_VARIABLE}" ${LOCAL_GENERATED_HEADERS} PARENT_SCOPE) set("${GENERATED_IMPLS_VARIABLE}" ${LOCAL_GENERATED_IMPLS} PARENT_SCOPE) add_custom_target( "${TARGET_NAME}" DEPENDS ${LOCAL_GENERATED_HEADERS} ${LOCAL_GENERATED_IMPLS} ) endfunction() # Extracts tuple_tree_generator YAML definitions from the given header files # # The definitions have to be embedded in a c-style comment marked with the given # delimiter, like so: # # /* DELIMITER # # DELIMITER */ function(tuple_tree_generator_extract_definitions_from_headers HEADERS DELIMITER OUTPUT_FILE) add_custom_command( OUTPUT "${OUTPUT_FILE}" COMMAND "${CMAKE_SOURCE_DIR}/scripts/tuple_tree_generator/extract_yaml.py" --output "${OUTPUT_FILE}" "${DELIMITER}" ${HEADERS} DEPENDS ${HEADERS} ) endfunction() # Computes the list of headers and C++ source files that will be generated by # tuple_tree_generator. # Note: the output variables will be overwritten function(tuple_tree_generator_compute_generated_cpp_files SOURCE_HEADERS OUTPUT_DIR GENERATED_HEADERS_VARIABLE GENERATED_IMPLS_VARIABLE ) # Empty output variables set(LOCAL_GENERATED_HEADERS_VARIABLE "${OUTPUT_DIR}/ForwardDecls.h") set(LOCAL_GENERATED_IMPLS_VARIABLE) foreach(HEADER ${SOURCE_HEADERS}) get_filename_component(HEADER_FILENAME "${HEADER}" NAME) get_filename_component(HEADER_FILENAME_WE "${HEADER}" NAME_WE) set(EARLY_OUTPUT "${OUTPUT_DIR}/Early/${HEADER_FILENAME}") set(LATE_OUTPUT "${OUTPUT_DIR}/Late/${HEADER_FILENAME}") set(IMPL_OUTPUT "${OUTPUT_DIR}/Impl/${HEADER_FILENAME_WE}.cpp") list(APPEND LOCAL_GENERATED_HEADERS_VARIABLE "${EARLY_OUTPUT}") list(APPEND LOCAL_GENERATED_HEADERS_VARIABLE "${LATE_OUTPUT}") list(APPEND LOCAL_GENERATED_IMPLS_VARIABLE "${IMPL_OUTPUT}") endforeach() set("${GENERATED_HEADERS_VARIABLE}" ${LOCAL_GENERATED_HEADERS_VARIABLE} PARENT_SCOPE) set("${GENERATED_IMPLS_VARIABLE}" ${LOCAL_GENERATED_IMPLS_VARIABLE} PARENT_SCOPE) endfunction() set(TEMPLATES_DIR "${CMAKE_SOURCE_DIR}/scripts/tuple_tree_generator/tuple_tree_generator/templates") set(TEMPLATES "${TEMPLATES_DIR}/class_forward_decls.h.tpl" "${TEMPLATES_DIR}/enum.h.tpl" "${TEMPLATES_DIR}/struct.h.tpl" "${TEMPLATES_DIR}/struct_forward_decls.h.tpl" "${TEMPLATES_DIR}/struct_late.h.tpl" "${TEMPLATES_DIR}/struct_impl.cpp.tpl" ) # Generates headers and implementation C++ files function(tuple_tree_generator_generate_cpp # Path to the yaml definitions YAML_DEFINITIONS # Base namespace of the generated classes (e.g. model) NAMESPACE # Output directory OUTPUT_DIR # Include path prefix INCLUDE_PATH_PREFIX # List of headers that are expected to be generated EXPECTED_GENERATED_HEADERS # List of implementation files expected to be generated EXPECTED_GENERATED_IMPLS ) set(SCRIPTS_ROOT_DIR "${CMAKE_SOURCE_DIR}/scripts/tuple_tree_generator") # The list of Python scripts is build as follows: # # find scripts/tuple_tree_generator -name "*.py" | sort | sed 's|scripts/tuple_tree_generator|"\${SCRIPTS_ROOT_DIR}|; s/$/"/ # # TODO: detect and warn about extra files in those directories add_custom_command( COMMAND "${SCRIPTS_ROOT_DIR}/main.py" --namespace "${NAMESPACE}" --cpp-headers --include-path-prefix "${INCLUDE_PATH_PREFIX}" "${YAML_DEFINITIONS}" "${OUTPUT_DIR}" OUTPUT ${EXPECTED_GENERATED_HEADERS} ${EXPECTED_GENERATED_IMPLS} DEPENDS "${YAML_DEFINITIONS}" ${TEMPLATES} "${SCRIPTS_ROOT_DIR}/extract_yaml.py" "${SCRIPTS_ROOT_DIR}/main.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/__init__.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/definition/__init__.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/definition/definition.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/definition/enum.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/definition/struct.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/generators/__init__.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/generators/cppheaders.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/generators/generator.py" "${SCRIPTS_ROOT_DIR}/tuple_tree_generator/generators/jinja_utils.py" ) endfunction()