@@ -14,22 +14,9 @@ syntax, e.g. 'find_package(RE2C 0.15.3)'.
1414## Cache variables
1515
1616* `RE2C_EXECUTABLE` - Path to the re2c program. When RE2C is downloaded and
17- built from source as part of the built (using below ExternalProject), this
18- path will not exist until the built phase.
19-
20- Custom target:
21-
22- * `re2c_generate_files` - A custom target for generating lexer files:
23-
24- ```sh
25- cmake --build <dir> -t re2c_generate_files
26- ```
27-
28- or to add it as a dependency to other targets:
29-
30- ```cmake
31- add_dependencies(some_target re2c_generate_files)
32- ```
17+ built from source as part of the built (using the `ExternalProject` CMake
18+ module), this path will be autofilled to the built re2c and will not exist
19+ until the build phase.
3320
3421## Hints
3522
@@ -61,22 +48,82 @@ re2c_target(
6148 [DEPENDS <depends>...]
6249 [NO_DEFAULT_OPTIONS]
6350 [NO_COMPUTED_GOTOS]
51+ [CODEGEN]
6452)
6553```
6654
67- * `<name>` - Target name.
68- * `<input>` - The re2c template file input. Relative source file path is
69- interpreted as being relative to the current source directory.
70- * `<output>` - The output file. Relative output file path is interpreted as
71- being relative to the current binary directory.
72- * `HEADER` - Generate a <header> file. Relative header file path is interpreted
73- as being relative to the current binary directory.
74- * `OPTIONS` - List of additional options to pass to re2c command-line tool.
75- * `DEPENDS` - Optional list of dependent files to regenerate the output file.
55+ This will add a custom command and a custom target `<name>` that generates lexer
56+ file `<output>` from the given `<input>` re2c template file using the re2c
57+ utility. Relative source file path `<input> is interpreted as being relative to
58+ the current source directory. Relative `<output>` file path is interpreted as
59+ being relative to the current binary directory.
60+
61+ ### Options
62+
63+ * `HEADER <header>` - Generate a given `<header>` file. Relative header file
64+ path is interpreted as being relative to the current binary directory.
65+
66+ * `OPTIONS <options>...` - List of additional options to pass to re2c
67+ command-line tool.
68+
69+ * `DEPENDS <depends>...` - Optional list of dependent files to regenerate the
70+ output file.
71+
7672* `NO_DEFAULT_OPTIONS` - If specified, then the options from
7773 `RE2C_DEFAULT_OPTIONS` are not passed to the re2c invocation.
74+
7875* `NO_COMPUTED_GOTOS` - If specified when using the `RE2C_USE_COMPUTED_GOTOS`,
7976 then the computed gotos option is not passed to the re2c invocation.
77+
78+ * `CODEGEN` - adds the `CODEGEN` option to the re2c's `add_custom_command()`
79+ call. Works as of CMake 3.31 when policy `CMP0171` is set to `NEW`, which
80+ provides a global CMake `codegen` target for convenience to call only the
81+ code-generation-related targets and skips the majority of the build:
82+
83+ ```sh
84+ cmake --build <dir> --target codegen
85+ ```
86+
87+ ## Examples
88+
89+ The `re2c_target()` also creates a custom target called `<name>` that can be
90+ used in more complex scenarios, like defining dependencies to other targets:
91+
92+ ```cmake
93+ # CMakeLists.txt
94+
95+ find_package(RE2C)
96+
97+ if(RE2C_FOUND)
98+ re2c_target(foo_lexer lexer.re lexer.c)
99+ add_dependencies(some_target foo_lexer)
100+ endif()
101+ ```
102+
103+ Or to run only the specific `foo_lexer` target, which generates the lexer.
104+
105+ ```sh
106+ cmake --build <dir> --target foo_lexer
107+ ```
108+
109+ When running in script mode:
110+
111+ ```sh
112+ cmake -P script.cmake
113+ ```
114+
115+ The generated file is created right away for convenience and custom target is
116+ not created:
117+
118+ ```cmake
119+ # script.cmake
120+
121+ find_package(RE2C)
122+
123+ if(RE2C_FOUND)
124+ re2c_target(foo_lexer lexer.re lexer.c)
125+ endif()
126+ ```
80127#]=============================================================================]
81128
82129include (CheckSourceCompiles)
@@ -91,10 +138,6 @@ set_package_properties(
91138 DESCRIPTION "Free and open-source lexer generator"
92139)
93140
94- if (NOT TARGET re2c_generate_files)
95- add_custom_target (re2c_generate_files)
96- endif ()
97-
98141find_program (
99142 RE2C_EXECUTABLE
100143 NAMES re2c
@@ -103,12 +146,12 @@ find_program(
103146mark_as_advanced (RE2C_EXECUTABLE)
104147
105148if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.29)
106- set (_re2cCondition IS_EXECUTABLE ${RE2C_EXECUTABLE} )
149+ set (_re2cTest IS_EXECUTABLE)
107150else ()
108- set (_re2cCondition EXISTS ${RE2C_EXECUTABLE} )
151+ set (_re2cTest EXISTS )
109152endif ()
110153
111- if (${_re2cCondition } )
154+ if (${_re2cTest} ${RE2C_EXECUTABLE } )
112155 execute_process (
113156 COMMAND ${RE2C_EXECUTABLE} --vernum
114157 OUTPUT_VARIABLE RE2C_VERSION_NUM
@@ -201,9 +244,9 @@ find_package_handle_standard_args(
201244 REASON_FAILURE_MESSAGE "re2c not found. Please install re2c."
202245)
203246
204- unset (_re2cCondition)
205247unset (_re2cMsg)
206248unset (_re2cRequiredVars)
249+ unset (_re2cTest)
207250unset (_re2cVersionValid)
208251
209252if (NOT RE2C_FOUND)
@@ -241,10 +284,10 @@ function(re2c_target)
241284 cmake_parse_arguments (
242285 PARSE_ARGV
243286 3
244- parsed # prefix
245- "NO_DEFAULT_OPTIONS;NO_COMPUTED_GOTOS" # options
246- "HEADER" # one-value keywords
247- "OPTIONS;DEPENDS" # multi-value keywords
287+ parsed # prefix
288+ "NO_DEFAULT_OPTIONS;NO_COMPUTED_GOTOS;CODEGEN " # options
289+ "HEADER" # one-value keywords
290+ "OPTIONS;DEPENDS" # multi-value keywords
248291 )
249292
250293 if (parsed_UNPARSED_ARGUMENTS)
@@ -289,31 +332,52 @@ function(re2c_target)
289332
290333 list (APPEND outputs ${header} )
291334
292- # When header option is used before version 1.2, also the '-c' option is
293- # required. Before 1.1 -c long variant is '--start-conditions' and after 1.1
294- # '--conditions'.
335+ # When header option is used before re2c version 1.2, also the '-c' option
336+ # is required. Before 1.1 '-c' long variant is '--start-conditions' and
337+ # after 1.1 '--conditions'.
295338 if (RE2C_VERSION VERSION_LESS_EQUAL 1.2)
296339 list (APPEND options -c)
297340 endif ()
298341
299- # Since version 3.0, --header is the new alias option for --type-header.
342+ # Since re2c version 3.0, '--header' is the new alias option for the
343+ # '--type-header' option.
300344 if (RE2C_VERSION VERSION_GREATER_EQUAL 3.0)
301345 list (APPEND options --header ${header} )
302346 else ()
303347 list (APPEND options --type -header ${header} )
304348 endif ()
305349 endif ()
306350
351+ set (message "[RE2C][${ARGV0} ] Generating lexer with re2c ${RE2C_VERSION} " )
352+ set (command ${RE2C_EXECUTABLE} ${options} --output ${output} ${input} )
353+
354+ if (CMAKE_SCRIPT_MODE_FILE )
355+ message (STATUS "${message} " )
356+ execute_process (COMMAND ${command} )
357+ return ()
358+ endif ()
359+
360+ set (codegen "" )
361+ if (
362+ parsed_CODEGEN
363+ AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.31
364+ AND POLICY CMP0171
365+ )
366+ cmake_policy (GET CMP0171 cmp0171)
367+
368+ if (cmp0171 STREQUAL "NEW" )
369+ set (codegen CODEGEN)
370+ endif ()
371+ endif ()
372+
307373 add_custom_command (
308374 OUTPUT ${outputs}
309- COMMAND ${RE2C_EXECUTABLE}
310- ${options}
311- --output ${output}
312- ${input}
375+ COMMAND ${command}
313376 DEPENDS ${input} ${parsed_DEPENDS} $<TARGET_NAME_IF_EXISTS:RE2C::RE2C>
314- COMMENT "[RE2C][ ${ARGV0} ] Building lexer with re2c ${RE2C_VERSION } "
377+ COMMENT "${message } "
315378 VERBATIM
316379 COMMAND_EXPAND_LISTS
380+ ${codegen}
317381 )
318382
319383 add_custom_target (
@@ -322,6 +386,4 @@ function(re2c_target)
322386 DEPENDS ${outputs}
323387 COMMENT "[RE2C] Building lexer with re2c ${RE2C_VERSION} "
324388 )
325-
326- add_dependencies (re2c_generate_files ${ARGV0} )
327389endfunction ()
0 commit comments