Note

You are not reading the most recent version of this documentation. 1.4.7 is the latest version available.

Build System Integration

XXXX

Bazel

CMake

The following example shows how CMake could be used to generate code from Coco models as part of the build.

find_package(Threads REQUIRED)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# The path to the Coco command-line tool; set this to a suitable path.
set(COCO_PATH "coco")

# Calculate the output files based on the .coco file names
#
# This assumes that the Coco.toml file contains the following:
#
#   [package]
#   sources = ["src"]
#
# with no customisation to the [generator.cpp] settings. If this is not the case,
# COCO_SOURCES, and the REGEXs below will need to be altered.
file(GLOB_RECURSE COCO_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.coco")
set(COCO_GENERATED_HEADERS)
set(COCO_GENERATED_SOURCES)

foreach(file ${COCO_SOURCES})
    string(REGEX REPLACE "^src/(.*)[.]coco$" "${PROJECT_BINARY_DIR}/generated/\\1.h" hdr ${file})
    string(REGEX REPLACE "^src/(.*)[.]coco$" "${PROJECT_BINARY_DIR}/generated/\\1.cc" src ${file})
    list(APPEND COCO_GENERATED_HEADERS ${hdr})
    list(APPEND COCO_GENERATED_SOURCES ${src})
    # Make sure that CMake knows this is a generated file, so it doesn't expect it to exist
    set_source_files_properties(${hdr} PROPERTIES GENERATED TRUE)
    set_source_files_properties(${src} PROPERTIES GENERATED TRUE)
endforeach()

# Generate normal .cc/.h files and create a library for them
add_custom_command(
    OUTPUT coco_generate.stamp
    COMMAND cmake -E touch coco_generate.stamp
    COMMAND ${COCO_PATH}
      --package ${CMAKE_CURRENT_SOURCE_DIR}
      generate-cpp
      --output-empty-files
      --output-unchanged-files
      --output
      "${PROJECT_BINARY_DIR}/generated"
    COMMENT "Generating C++ files from Coco files"
    DEPENDS ${COCO_SOURCES}
)

# Use a custom command to ensure that parallel builds only generate code from Coco files once
add_custom_target(
  coco_generate ALL
  DEPENDS coco_generate.stamp
)

# Create a library to compile the generated code, plus any hand-written C++ files that are required
add_library(GeneratedCoco STATIC ${COCO_GENERATED_SOURCES})
add_dependencies(GeneratedCoco coco_generate)
# This exports the Coco-generated header files to any other library or executable that depends on this
target_include_directories(GeneratedCoco PUBLIC
  "${PROJECT_BINARY_DIR}/generated"
)

# Use the generated code as part of an executable
add_executable(Tutorial ${CC_SOURCES})
target_link_libraries(Tutorial PRIVATE Threads::Threads GeneratedCoco)