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)