FindFLEX: Add new keyword OPTIONS

This adds a new keyword OPTIONS which is a semicolon-separated list of
command-line options added to flex command line. This enables adding
options more intuitively. It mainly adds options as quoted arguments
which among other things enables adding paths containing spaces and
similar.

Fixes:
- https://gitlab.kitware.com/cmake/cmake/-/issues/23301
This commit is contained in:
Peter Kokot
2025-01-02 01:43:42 +01:00
parent 90971c9188
commit d63ffb4116
2 changed files with 68 additions and 4 deletions

View File

@@ -0,0 +1,6 @@
FindFLEX
--------
* The :module:`FindFLEX` module :command:`flex_target` command has a new
``OPTIONS`` option to add Flex command-line options as a
:ref:`semicolon-separated list <CMake Language Lists>`.

View File

@@ -35,6 +35,7 @@ If ``flex`` is found on the system, the module defines the macro:
.. code-block:: cmake
flex_target(<Name> <FlexInput> <FlexOutput>
[OPTIONS <options>...]
[COMPILE_FLAGS <string>]
[DEFINES_FILE <string>]
)
@@ -45,9 +46,18 @@ custom command.
The options are:
``OPTIONS <options>...``
.. versionadded:: 3.32
A :ref:`semicolon-separated list <CMake Language Lists>` of flex options added
to the ``flex`` command line.
``COMPILE_FLAGS <string>``
.. deprecated:: 3.32
Space-separated flex options added to the ``flex`` command line.
A :ref:`;-list <CMake Language Lists>` will not work.
This option is deprecated in favor of ``OPTIONS <options>...``.
``DEFINES_FILE <string>``
.. versionadded:: 3.5
@@ -73,6 +83,11 @@ The macro defines the following variables:
``FLEX_<Name>_OUTPUT_HEADER``
The header flex output, if any.
``FLEX_<Name>_OPTIONS``
.. versionadded:: 3.32
Options used in the ``flex`` command line.
Flex scanners often use tokens defined by Bison: the code generated
by Flex depends of the header generated by Bison. This module also
defines a macro:
@@ -106,6 +121,29 @@ Examples
${FLEX_MyScanner_OUTPUTS}
)
target_link_libraries(Foo ${FLEX_LIBRARIES})
Adding additional command-line options to the ``flex`` executable can be passed
as a list. For example, adding the ``--warn`` option to report warnings, and the
``--noline`` (``-L``) to not generate ``#line`` directives.
.. code-block:: cmake
find_package(FLEX)
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp OPTIONS --warn --noline)
endif()
Generator expressions can be used in ``OPTIONS <options...``. For example, to
add the ``--debug`` (``-d``) option only for the ``Debug`` build type:
.. code-block:: cmake
find_package(FLEX)
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp OPTIONS $<$<CONFIG:Debug>:--debug>)
endif()
#]=======================================================================]
find_program(FLEX_EXECUTABLE NAMES flex win-flex win_flex DOC "path to the flex executable")
@@ -157,20 +195,35 @@ if(FLEX_EXECUTABLE)
COMPILE_FLAGS
DEFINES_FILE
)
set(FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS)
set(FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS OPTIONS)
cmake_parse_arguments(
FLEX_TARGET_ARG
"${FLEX_TARGET_PARAM_OPTIONS}"
"${FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS}"
"${FLEX_TARGET_MULTI_VALUE_KEYWORDS}"
"${FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS}"
${ARGN}
)
set(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>] [DEFINES_FILE <string>]")
string(
JOIN "\n" FLEX_TARGET_usage
"Usage:"
" flex_target("
" <Name>"
" <Input>"
" <Output>"
" [OPTIONS <options>...]"
" [COMPILE_FLAGS <string>]"
" [DEFINES_FILE <string>]"
" )"
)
if(NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(SEND_ERROR ${FLEX_TARGET_usage})
message(
SEND_ERROR
"Unrecognized arguments: ${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}\n"
"${FLEX_TARGET_usage}"
)
else()
cmake_policy(GET CMP0098 _flex_CMP0098
@@ -199,6 +252,10 @@ if(FLEX_EXECUTABLE)
separate_arguments(_flex_EXE_OPTS)
endif()
if(FLEX_TARGET_ARG_OPTIONS)
list(APPEND _flex_EXE_OPTS ${FLEX_TARGET_ARG_OPTIONS})
endif()
set(_flex_OUTPUT_HEADER "")
if(NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
set(_flex_OUTPUT_HEADER "${FLEX_TARGET_ARG_DEFINES_FILE}")
@@ -222,6 +279,7 @@ if(FLEX_EXECUTABLE)
set(FLEX_${Name}_DEFINED TRUE)
set(FLEX_${Name}_OUTPUTS ${_flex_TARGET_OUTPUTS})
set(FLEX_${Name}_INPUT ${_flex_INPUT})
set(FLEX_${Name}_OPTIONS ${_flex_EXE_OPTS})
set(FLEX_${Name}_COMPILE_FLAGS ${_flex_EXE_OPTS})
set(FLEX_${Name}_OUTPUT_HEADER ${_flex_OUTPUT_HEADER})