Skip to content

Commit fbd618f

Browse files
committed
[#560] Provide zserio_compiler.cmake helper in release
Use also internally for zserio tests
1 parent b95abcc commit fbd618f

File tree

79 files changed

+1777
-3963
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1777
-3963
lines changed

cmake/zserio_compiler.cmake

+266
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
# A function which allows to automatically generate C++ sources from zserio schemas.
2+
#
3+
# Prerequisites:
4+
# JAVA must be available - calls find_program(JAVA java).
5+
# ZSERIO_JAR_FILE must be set either as an environment or CMake variable
6+
#
7+
# Usage:
8+
# zserio_generate_cpp(
9+
# TARGET <target>
10+
# [SRC_DIR <directory>]
11+
# [MAIN_ZS <file>]
12+
# [GEN_DIR <directory>]
13+
# [GENERATED_SOURCES_VAR <variable>]
14+
# [OUTPUT_VAR <variable>]
15+
# [ERROR_VAR <variable>]
16+
# [RESULT_VAR <variable>]
17+
# [FORCE_REGENERATION]
18+
# [CLEAN_GEN_DIR]
19+
#
20+
# Arguments:
21+
# TARGET - Target to which the generated sources will be assigned.
22+
# SRC_DIR - Source directory for zserio schemas. Optional, defaults to CMAKE_CURRENT_SOURCE_DIR.
23+
# MAIN_ZS - Main zserio schema. Optional if the MAIN_ZS file is specified as a source for the given TARGET.
24+
# GEN_DIR - Directory where the C++ sources will be generated.
25+
# GENERATED_SOURCES_VAR - The variable will be set with a list of generated source files (full paths).
26+
# Optional.
27+
# OUTPUT_VAR - The variable will be set with the contents of the standard output pipe. Optional.
28+
# If not set, the standard output pipe is printed.
29+
# ERROR_VAR - The variable will be set with the contents of the standard error pipe. Optional.
30+
# If not set, the standard error pipe is printed.
31+
# RESULT_VAR - The variable will be set to contain the result of the zserio generator. Optional.
32+
# If not set, a FATAL_ERROR is raised in case of the zserio generator error.
33+
# FORCE_RECONFIGURE - Forces regeneration every time the CMake configure is run.
34+
# CLEAN_GEN_DIR - Cleans GEN_DIR when generation in CMake configure time is run.
35+
#
36+
# Note that OUTPUT_VAR and ERROR_VAR can be set to the same value and then both pipes will be merged.
37+
#
38+
# Note that OUTPUT_VAR, ERROR_VAR and RESULT_VAR are updated only when the generation is executed within
39+
# the configure-time - i.e. for the first time or when zserio schema sources are changed, etc.
40+
# See "How if works" for more info.
41+
#
42+
# Example:
43+
# set(CMAKE_MODULE_PATH "${ZSERIO_RELEASE}/cmake")
44+
# set(ZSERIO_JAR_FILE "${ZSERIO_RELEASE}/zserio.jar")
45+
# include(zserio_compiler)
46+
#
47+
# add_library(sample_zs sample.zs)
48+
# zserio_generate_cpp(
49+
# TARGET sample_zs
50+
# GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen)
51+
#
52+
# How it works:
53+
#
54+
# First time the CMake configure is run, the sources are generated using execute_process directly in
55+
# configure-time and auxilary information (timestamps, list of generated sources, etc.) is stored in the
56+
# CMake cache. The auxilary info is used to define a custom command which uses the same zserio command line
57+
# as the original execute_process and thus allows to re-generate sources when it's needed - e.g. after the
58+
# clean step.
59+
#
60+
# The custom command is sufficient as long as the generated sources remains unchanged. Otherwise the
61+
# execute_process must be re-run in configure-time to ensure that all generated sources are collected correctly.
62+
# This functionality is achieved using the auxilary information mentioned above.
63+
#
64+
# List of generated sources can change in following situations:
65+
#
66+
# - ZSERIO_JAR_FILE is changed
67+
# - zserio schema sources are changed
68+
# - EXTRA_ARGS are changed
69+
function(zserio_generate_cpp)
70+
find_program(JAVA java)
71+
if (NOT JAVA)
72+
message(FATAL_ERROR "Could not find java!")
73+
endif()
74+
if (DEFINED ENV{ZSERIO_JAR_FILE})
75+
set(ZSERIO_JAR_FILE $ENV{ZSERIO_JAR_FILE})
76+
endif ()
77+
if (NOT DEFINED ZSERIO_JAR_FILE OR NOT EXISTS ${ZSERIO_JAR_FILE})
78+
message(FATAL_ERROR "Could not find zserio.jar!")
79+
endif()
80+
81+
cmake_parse_arguments(ZSERIO_GENERATE
82+
"FORCE_REGENERATE;CLEAN_GEN_DIR"
83+
"TARGET;SRC_DIR;MAIN_ZS;GEN_DIR;GENERATED_SOURCES_VAR;OUTPUT_VAR;ERROR_VAR;RESULT_VAR"
84+
"EXTRA_ARGS"
85+
${ARGN})
86+
87+
if (ZSERIO_GENERATE_UNPARSED_ARGUMENTS)
88+
message(FATAL_ERROR "zserio_generate_cpp: Unkown arguments '${ZSERIO_GENERATE_UNPARSED_ARGUMENTS}'!")
89+
endif ()
90+
91+
# check required arguments
92+
foreach (ARG TARGET GEN_DIR)
93+
if (NOT DEFINED ZSERIO_GENERATE_${ARG})
94+
message(FATAL_ERROR "No value defined for required argument ${ARG}!")
95+
endif ()
96+
endforeach ()
97+
98+
# default values
99+
if (NOT DEFINED ZSERIO_GENERATE_SRC_DIR)
100+
set(ZSERIO_GENERATE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
101+
endif ()
102+
if (NOT DEFINED ZSERIO_GENERATE_MAIN_ZS)
103+
# try to get a single main zs
104+
get_target_property(ZS_SOURCES ${ZSERIO_GENERATE_TARGET} SOURCES)
105+
list(FILTER ZS_SOURCES INCLUDE REGEX "\\.zs$")
106+
list(LENGTH ZS_SOURCES ZS_SOURCES_LENGTH)
107+
if (${ZS_SOURCES_LENGTH} EQUAL 1)
108+
list(GET ZS_SOURCES 0 ZSERIO_GENERATE_MAIN_ZS)
109+
110+
# try to map the found source to ZSERIO_GENERATE_SRC_DIR
111+
if (NOT IS_ABSOLUTE ${ZSERIO_GENERATE_MAIN_ZS})
112+
set(ZSERIO_GENERATE_MAIN_ZS "${CMAKE_CURRENT_SOURCE_DIR}/${ZSERIO_GENERATE_MAIN_ZS}")
113+
endif ()
114+
file(RELATIVE_PATH ZSERIO_GENERATE_MAIN_ZS
115+
"${ZSERIO_GENERATE_SRC_DIR}" "${ZSERIO_GENERATE_MAIN_ZS}")
116+
else ()
117+
message(FATAL_ERROR "MAIN_ZS file not specifid and cannot be detected!")
118+
endif ()
119+
endif ()
120+
121+
# ensure cmake reconfigure when zserio sources are changed
122+
file(GLOB_RECURSE ZSERIO_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
123+
"${ZSERIO_GENERATE_SRC_DIR}/*.zs")
124+
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${ZSERIO_SOURCES} ${ZSERIO_JAR_FILE})
125+
126+
set(ZSERIO_COMMAND
127+
${JAVA} -jar ${ZSERIO_JAR_FILE}
128+
-src ${ZSERIO_GENERATE_SRC_DIR} ${ZSERIO_GENERATE_MAIN_ZS}
129+
-cpp ${ZSERIO_GENERATE_GEN_DIR}
130+
${ZSERIO_GENERATE_EXTRA_ARGS}
131+
)
132+
133+
_zserio_compiler_get_latest_timestamp(FILES ${ZSERIO_SOURCES} TIMESTAMP_VAR ZSERIO_SOURCES_TIMESTAMP)
134+
_zserio_compiler_get_latest_timestamp(FILES ${ZSERIO_JAR_FILE} TIMESTAMP_VAR ZSERIO_JAR_TIMESTAMP)
135+
136+
set(REGENERATE_SOURCES 1)
137+
if (NOT ZSERIO_GENERATE_FORCE_REGENERATE AND
138+
DEFINED ZSERIO_COMPILER_ZSERIO_JAR_TIMESTAMP AND
139+
DEFINED ZSERIO_COMPILER_SOURCES_TIMESTAMP_${ZSERIO_GENERATE_TARGET} AND
140+
DEFINED ZSERIO_COMPILER_SOURCES_${ZSERIO_GENERATE_TARGET} AND
141+
DEFINED ZSERIO_COMPILER_EXTRA_ARGS_${ZSERIO_GENERATE_TARGET} AND
142+
DEFINED ZSERIO_COMPILER_GENERATED_SOURCES_${ZSERIO_GENERATE_TARGET})
143+
if (${ZSERIO_COMPILER_ZSERIO_JAR_TIMESTAMP} EQUAL ${ZSERIO_JAR_TIMESTAMP} AND
144+
${ZSERIO_COMPILER_SOURCES_TIMESTAMP_${ZSERIO_GENERATE_TARGET}} EQUAL ${ZSERIO_SOURCES_TIMESTAMP} AND
145+
"${ZSERIO_COMPILER_EXTRA_ARGS_${ZSERIO_GENERATE_TARGET}}" STREQUAL
146+
"${ZSERIO_GENERATE_EXTRA_ARGS}" AND
147+
"${ZSERIO_COMPILER_SOURCES_${ZSERIO_GENERATE_TARGET}}" STREQUAL "${ZSERIO_SOURCES}")
148+
set(REGENERATE_SOURCES 0)
149+
endif ()
150+
endif ()
151+
152+
set(TOOL_COMMENT "Generating C++ sources from '${ZSERIO_GENERATE_MAIN_ZS}'.")
153+
154+
if (REGENERATE_SOURCES)
155+
if ("${ZSERIO_GENERATE_OUTPUT_VAR}" STREQUAL "${ZSERIO_GENERATE_ERROR_VAR}")
156+
set(SEPARATE_OUTPUT OFF)
157+
set(ZSERIO_OUTPUT_VAR ZSERIO_OUTPUT)
158+
set(ZSERIO_ERROR_VAR ZSERIO_OUTPUT)
159+
else ()
160+
set(SEPARATE_OUTPUT ON)
161+
set(ZSERIO_OUTPUT_VAR ZSERIO_OUTPUT)
162+
set(ZSERIO_ERROR_VAR ZSERIO_ERROR)
163+
endif ()
164+
165+
if (ZSERIO_GENERATE_CLEAN_GEN_DIR)
166+
file(REMOVE_RECURSE ${ZSERIO_GENERATE_GEN_DIR})
167+
file(MAKE_DIRECTORY ${ZSERIO_GENERATE_GEN_DIR})
168+
endif ()
169+
170+
message(STATUS ${TOOL_COMMENT})
171+
172+
# run the generator during configure phase for the first time
173+
execute_process(
174+
COMMAND ${ZSERIO_COMMAND}
175+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
176+
OUTPUT_VARIABLE ${ZSERIO_OUTPUT_VAR}
177+
ERROR_VARIABLE ${ZSERIO_ERROR_VAR}
178+
RESULT_VARIABLE ZSERIO_RESULT)
179+
180+
if (${SEPARATE_OUTPUT})
181+
if (DEFINED ZSERIO_GENERATE_OUTPUT_VAR)
182+
set(${ZSERIO_GENERATE_OUTPUT_VAR} ${ZSERIO_OUTPUT} PARENT_SCOPE)
183+
else ()
184+
message(STATUS ${ZSERIO_OUTPUT})
185+
endif ()
186+
187+
if (DEFINED ZSERIO_GENERATE_ERROR_VAR)
188+
set(${ZSERIO_GENERATE_ERROR_VAR} ${ZSERIO_ERROR} PARENT_SCOPE)
189+
else ()
190+
message(STATUS ${ZSERIO_ERROR})
191+
endif ()
192+
else ()
193+
# both OUTPUT_VAR and ERROR_VAR are either not set or set to the same value
194+
if (DEFINED ZSERIO_GENERATE_OUTPUT_VAR)
195+
set(${ZSERIO_GENERATE_OUTPUT_VAR} ${ZSERIO_OUTPUT} PARENT_SCOPE)
196+
else ()
197+
message(STATUS ${ZSERIO_ERROR})
198+
endif ()
199+
endif ()
200+
201+
if (DEFINED ZSERIO_GENERATE_RESULT_VAR)
202+
set(${ZSERIO_GENERATE_RESULT_VAR} ${ZSERIO_RESULT} PARENT_SCOPE)
203+
endif ()
204+
205+
file(GLOB_RECURSE GENERATED_SOURCES
206+
"${ZSERIO_GENERATE_GEN_DIR}/*.h"
207+
"${ZSERIO_GENERATE_GEN_DIR}/*.cpp")
208+
209+
set(ZSERIO_COMPILER_ZSERIO_JAR_TIMESTAMP "${ZSERIO_JAR_TIMESTAMP}"
210+
CACHE INTERNAL "Timestamp of the '${ZSERIO_JAR_FILE}'"
211+
FORCE)
212+
set(ZSERIO_COMPILER_SOURCES_TIMESTAMP_${ZSERIO_GENERATE_TARGET} "${ZSERIO_SOURCES_TIMESTAMP}"
213+
CACHE INTERNAL "Latest timestamp of the Zserio schema sources for ${ZSERIO_GENERATE_TARGET}."
214+
FORCE)
215+
set(ZSERIO_COMPILER_SOURCES_${ZSERIO_GENERATE_TARGET} "${ZSERIO_SOURCES}"
216+
CACHE INTERNAL "List of Zserio schema sources for ${ZSERIO_GENERATE_TARGET}."
217+
FORCE)
218+
set(ZSERIO_COMPILER_EXTRA_ARGS_${ZSERIO_GENERATE_TARGET} "${ZSERIO_GENERATE_EXTRA_ARGS}"
219+
CACHE INTERNAL "Extra arguments to Zserio tool used for ${ZSERIO_GENERATE_TARGET}."
220+
FORCE)
221+
set(ZSERIO_COMPILER_GENERATED_SOURCES_${ZSERIO_GENERATE_TARGET} "${GENERATED_SOURCES}"
222+
CACHE INTERNAL "List of sources files generated by Zserio for ${ZSERIO_GENERATE_TARGET}."
223+
FORCE)
224+
225+
if (NOT ${ZSERIO_RESULT} EQUAL 0 AND NOT DEFINED ZSERIO_GENERATE_RESULT_VAR)
226+
message(FATAL_ERROR "Zserio generator failed!")
227+
endif ()
228+
else ()
229+
set(GENERATED_SOURCES "${ZSERIO_COMPILER_GENERATED_SOURCES_${ZSERIO_GENERATE_TARGET}}")
230+
endif ()
231+
232+
if (NOT "${GENERATED_SOURCES}" STREQUAL "")
233+
if (DEFINED ZSERIO_GENERATE_GENERATED_SOURCES_VAR)
234+
set(${ZSERIO_GENERATE_GENERATED_SOURCES_VAR} "${GENERATED_SOURCES}" PARENT_SCOPE)
235+
endif ()
236+
237+
add_custom_command(OUTPUT ${GENERATED_SOURCES}
238+
COMMAND ${ZSERIO_COMMAND}
239+
DEPENDS ${ZSERIO_SOURCES}
240+
COMMENT ${TOOL_COMMENT})
241+
242+
target_sources(${ZSERIO_GENERATE_TARGET} PRIVATE ${GENERATED_SOURCES})
243+
set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
244+
target_include_directories(${ZSERIO_GENERATE_TARGET} PUBLIC ${ZSERIO_GENERATE_GEN_DIR})
245+
246+
set_target_properties(${ZSERIO_GENERATE_TARGET} PROPERTIES
247+
ADDITIONAL_CLEAN_FILES "${GENERATED_SOURCES}")
248+
endif ()
249+
endfunction()
250+
251+
function(_zserio_compiler_get_latest_timestamp)
252+
cmake_parse_arguments(GET_LATEST_TIMESTAMP "" "TIMESTAMP_VAR" "FILES" ${ARGN})
253+
254+
set(LATEST_TIMESTAMP 0)
255+
foreach(FILE ${GET_LATEST_TIMESTAMP_FILES})
256+
if (NOT IS_ABSOLUTE ${FILE})
257+
set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}")
258+
endif ()
259+
260+
file(TIMESTAMP ${FILE} FILE_TIMESTAMP "%s")
261+
if (${FILE_TIMESTAMP} GREATER ${LATEST_TIMESTAMP})
262+
set(LATEST_TIMESTAMP ${FILE_TIMESTAMP})
263+
endif ()
264+
endforeach()
265+
set(${GET_LATEST_TIMESTAMP_TIMESTAMP_VAR} ${LATEST_TIMESTAMP} PARENT_SCOPE)
266+
endfunction()

cmake/zserio_tool.cmake

-66
This file was deleted.

0 commit comments

Comments
 (0)