diff --git a/Help/policy/CMP0098.rst b/Help/policy/CMP0098.rst index 631cb4eb51..d81dde4f7e 100644 --- a/Help/policy/CMP0098.rst +++ b/Help/policy/CMP0098.rst @@ -6,8 +6,8 @@ CMP0098 :module:`FindFLEX` runs ``flex`` in directory :variable:`CMAKE_CURRENT_BINARY_DIR` when executing. -The module provides a ``FLEX_TARGET`` macro which generates FLEX output. -In CMake 3.16 and below the macro would generate a custom command that runs +The module provides a ``flex_target()`` command which generates FLEX output. +In CMake 3.16 and below the command would generate a custom build rule that runs ``flex`` in the current source directory. CMake 3.17 and later prefer to run it in the build directory and use :variable:`CMAKE_CURRENT_BINARY_DIR` as the ``WORKING_DIRECTORY`` of its :command:`add_custom_command` invocation. @@ -18,7 +18,7 @@ provided as absolute path. This policy provides compatibility for projects that have not been updated to expect the new behavior. -The ``OLD`` behavior for this policy is for ``FLEX_TARGET`` to use +The ``OLD`` behavior for this policy is for ``flex_target()`` to use the current source directory for the ``WORKING_DIRECTORY`` and where to generate implicit files. The ``NEW`` behavior of this policy is to use the current binary directory for the ``WORKING_DIRECTORY`` relative to diff --git a/Help/release/3.17.rst b/Help/release/3.17.rst index 63ec423cf5..3808e0b5a7 100644 --- a/Help/release/3.17.rst +++ b/Help/release/3.17.rst @@ -170,7 +170,7 @@ Modules CURL's cmake buildsystem. It also gained a new ``CURL_NO_CURL_CMAKE`` option to disable this behavior. -* The :module:`FindFLEX` module's ``FLEX_TARGET`` command now runs ``flex`` +* The :module:`FindFLEX` module's ``flex_target()`` command now runs ``flex`` with :variable:`CMAKE_CURRENT_BINARY_DIR` as the working directory. See policy :policy:`CMP0098`. diff --git a/Help/release/3.5.rst b/Help/release/3.5.rst index e87716401c..31a4b535f7 100644 --- a/Help/release/3.5.rst +++ b/Help/release/3.5.rst @@ -73,7 +73,7 @@ Modules * The :module:`FindBoost` module now provides imported targets such as ``Boost::boost`` and ``Boost::filesystem``. -* The :module:`FindFLEX` module ``FLEX_TARGET`` macro learned a +* The :module:`FindFLEX` module ``flex_target()`` command learned a new ``DEFINES_FILE`` option to specify a custom output header to be generated. diff --git a/Help/release/3.6.rst b/Help/release/3.6.rst index e12c392ade..982fe9ca82 100644 --- a/Help/release/3.6.rst +++ b/Help/release/3.6.rst @@ -288,7 +288,7 @@ Other Changes :command:`add_custom_command` calls. This may break clients that added escaping manually to work around the bug. -* The :module:`FindFLEX` module ``FLEX_TARGET`` macro now supports +* The :module:`FindFLEX` module ``flex_target()`` command now supports special characters by passing the ``VERBATIM`` option to internal :command:`add_custom_command` calls. This may break clients that added escaping manually to work around the bug. diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake index b7a6e5fb1a..bf00fed94e 100644 --- a/Modules/FindFLEX.cmake +++ b/Modules/FindFLEX.cmake @@ -5,126 +5,194 @@ FindFLEX -------- -Find Fast Lexical Analyzer (Flex) executable and provide a macro -to generate custom build rules. +Finds the Fast Lexical Analyzer (Flex) command-line generator and its library, +and provides CMake commands to create custom build rules for using Flex: -The module defines the following variables: +.. code-block:: cmake + + find_package(FLEX [] ...) + +Flex generates lexical analyzers, also known as *scanners* or *lexers*. It also +includes a runtime library (``fl``) that supplies support functions for the +generated scanners, such as input handling, buffer management, and error +reporting. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: ``FLEX_FOUND`` - True if ``flex`` executable is found. + Boolean indicating whether (the requested version of) Flex is found. + +``FLEX_VERSION`` + The version of Flex found. + +``FLEX_INCLUDE_DIRS`` + The include directories containing headers for using Flex library. + +``FLEX_LIBRARIES`` + The libraries needed to link against to use Flex library. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: ``FLEX_EXECUTABLE`` The path to the ``flex`` executable. -``FLEX_VERSION`` - The version of ``flex``. +Commands +^^^^^^^^ -``FLEX_LIBRARIES`` - The ``flex`` libraries. +This module provides the following commands if ``flex`` is found: -``FLEX_INCLUDE_DIRS`` - The path to the ``flex`` headers. - -The minimum required version of ``flex`` can be specified using the -standard CMake syntax, e.g. :command:`find_package(FLEX 2.5.13)`. - -If ``flex`` is found on the system, the module defines the macro: +Generating Scanners +""""""""""""""""""" .. command:: flex_target + Creates a custom build rule to generate a scanner file from a lex file using + Flex: + .. code-block:: cmake - flex_target( - [OPTIONS ...] - [COMPILE_FLAGS ] - [DEFINES_FILE ] - ) + flex_target( + + + + [DEFINES_FILE
] + [OPTIONS ...] + [COMPILE_FLAGS ] # Deprecated + ) -which creates a custom command to generate the ```` file from -the ```` file. ```` is an alias used to get details of this -custom command. + .. versionchanged:: 3.17 + When policy :policy:`CMP0098` is set to ``NEW``, ``flex`` runs in the + :variable:`CMAKE_CURRENT_BINARY_DIR` directory. -The options are: + ```` + String used as an identifier for this command invocation. -``OPTIONS ...`` - .. versionadded:: 4.0 + ```` + The path to an input Flex source file (``.l``). If given as a relative + path, it will be interpreted relative to the current source directory + (:variable:`CMAKE_CURRENT_SOURCE_DIR`). - A :ref:`semicolon-separated list ` of flex options added - to the ``flex`` command line. + ```` + The path of the output file to be generated by Flex. If given as a relative + path, it will be interpreted relative to the current Flex working directory. -``COMPILE_FLAGS `` - .. deprecated:: 4.0 + ``DEFINES_FILE
`` + .. versionadded:: 3.5 - Space-separated flex options added to the ``flex`` command line. - A :ref:`;-list ` will not work. - This option is deprecated in favor of ``OPTIONS ...``. + If Flex is configured to output a header file, this option may be used to + specify its name. If given as a relative path, it will be interpreted + relative to the current Flex working directory. -``DEFINES_FILE `` - .. versionadded:: 3.5 + ``OPTIONS ...`` + .. versionadded:: 4.0 - If flex is configured to output a header file, this option may be used to - specify its name. + A :ref:`semicolon-separated list ` of extra options + added to the ``flex`` command line. -.. versionchanged:: 3.17 - When :policy:`CMP0098` is set to ``NEW``, ``flex`` runs in the - :variable:`CMAKE_CURRENT_BINARY_DIR` directory. + ``COMPILE_FLAGS `` + .. deprecated:: 4.0 + Superseded by ``OPTIONS ...``. -The macro defines the following variables: + A string of space-separated extra options added to the ``flex`` command + line. A :ref:`semicolon-separated list ` will not + work. -``FLEX__DEFINED`` - True if the macro ran successfully. + --------------------------------------------------------------------- -``FLEX__OUTPUTS`` - The source file generated by the custom rule, an alias for ````. + This command also defines the following variables: -``FLEX__INPUT`` - The flex source file, an alias for ````. + ``FLEX__DEFINED`` + Boolean indicating whether this command was successfully invoked. -``FLEX__OUTPUT_HEADER`` - The header flex output, if any. + ``FLEX__INPUT`` + The Flex source file, an alias for ````. -``FLEX__OPTIONS`` - .. versionadded:: 4.0 + ``FLEX__OUTPUT_HEADER`` + .. versionadded:: 3.5 - Options used in the ``flex`` command line. + The header file generated by ``flex``, if any. -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: + ``FLEX__OUTPUTS`` + A list of files generated by ``flex``, including the output scanner file, + and the header file. + + ``FLEX__OPTIONS`` + .. versionadded:: 4.0 + + A list of command-line options used for the ``flex`` command. + +Adding Dependency Between Scanner and Parser +"""""""""""""""""""""""""""""""""""""""""""" .. command:: add_flex_bison_dependency + Adds the required dependency between a scanner and a parser: + .. code-block:: cmake - add_flex_bison_dependency( ) + add_flex_bison_dependency( ) -which adds the required dependency between a scanner and a parser -where ```` and ```` are the first parameters of -respectively ``flex_target`` and ``bison_target`` macros. + Flex scanners often rely on token definitions generated by Bison, meaning the + code produced by Flex depends on the header file created by Bison. + + This command adds the required dependency between a scanner and a parser + where ```` and ```` are the first parameters of + respectively ``flex_target( ...)`` and + :command:`bison_target( ...)` commands. Examples ^^^^^^^^ +Examples: Finding Flex +"""""""""""""""""""""" + +Finding Flex: + .. code-block:: cmake - find_package(BISON) find_package(FLEX) - bison_target(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp) - flex_target(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp) - add_flex_bison_dependency(MyScanner MyParser) +Finding Flex and specifying its minimum required version: - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - add_executable(Foo - Foo.cc - ${BISON_MyParser_OUTPUTS} - ${FLEX_MyScanner_OUTPUTS} - ) - target_link_libraries(Foo ${FLEX_LIBRARIES}) +.. code-block:: cmake + + find_package(FLEX 2.5.13) + +Finding Flex and making it required (if Flex is not found, processing stops +with an error message): + +.. code-block:: cmake + + find_package(FLEX 2.5.13 REQUIRED) + +Example: Generating Scanner +""""""""""""""""""""""""""" + +Finding Flex and generating scanner source file in the current binary directory +from the lex source file in the current source directory: + +.. code-block:: cmake + + find_package(FLEX) + + if(FLEX_FOUND) + flex_target(MyScanner lexer.l lexer.cpp) + endif() + + add_executable(foo foo.cc ${FLEX_MyScanner_OUTPUTS}) + +Example: Command-line Options +""""""""""""""""""""""""""""" 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. +as a list. For example, adding the ``--warn`` option to report warnings, and +the ``--noline`` (``-L``) to not generate ``#line`` directives. .. code-block:: cmake @@ -134,8 +202,9 @@ as a list. For example, adding the ``--warn`` option to report warnings, and the flex_target(MyScanner lexer.l lexer.cpp OPTIONS --warn --noline) endif() -Generator expressions can be used in ``OPTIONS ` can be used in +the ``OPTIONS ...`` argument. For example, to add the ``--debug`` +(``-d``) option only for the ``Debug`` build type: .. code-block:: cmake @@ -144,6 +213,60 @@ add the ``--debug`` (``-d``) option only for the ``Debug`` build type: if(FLEX_FOUND) flex_target(MyScanner lexer.l lexer.cpp OPTIONS $<$:--debug>) endif() + +Example: Using Flex Library +""""""""""""""""""""""""""" + +Finding Flex and creating an interface :ref:`imported target ` +that encapsulates its library usage requirements for linking to a project +target: + +.. code-block:: cmake + + find_package(FLEX) + + if(FLEX_FOUND AND NOT TARGET FLEX::fl) + add_library(FLEX::fl INTERFACE IMPORTED) + set_target_properties( + FLEX::fl + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${FLEX_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FLEX_LIBRARIES}" + ) + endif() + + if(FLEX_FOUND) + flex_target(MyScanner lexer.l lexer.cpp) + endif() + + add_executable(Foo foo.cc ${FLEX_MyScanner_OUTPUTS}) + target_link_libraries(Foo PRIVATE FLEX::fl) + +Example: Using Flex and Bison +""""""""""""""""""""""""""""" + +The following example demonstrates, how to use Flex and :module:`Bison +` in CMake: + +.. code-block:: cmake + + find_package(BISON) + find_package(FLEX) + + if(BISON_FOUND AND FLEX_FOUND) + bison_target(MyParser parser.y parser.cpp) + flex_target(MyScanner lexer.l lexer.cpp) + add_flex_bison_dependency(MyScanner MyParser) + endif() + + add_executable(Foo foo.cc ${BISON_MyParser_OUTPUTS} ${FLEX_MyScanner_OUTPUTS}) + + # ... + +See Also +^^^^^^^^ + +* The :module:`FindBISON` module to find Bison parser generator. #]=======================================================================] find_program(FLEX_EXECUTABLE NAMES flex win-flex win_flex DOC "path to the flex executable") @@ -185,7 +308,7 @@ if(FLEX_EXECUTABLE) endif() #============================================================ - # FLEX_TARGET (public macro) + # flex_target() public macro #============================================================ # macro(FLEX_TARGET Name Input Output) @@ -209,12 +332,12 @@ if(FLEX_EXECUTABLE) JOIN "\n" FLEX_TARGET_usage "Usage:" " flex_target(" - " " - " " - " " + " " + " " + " " + " [DEFINES_FILE
]" " [OPTIONS ...]" " [COMPILE_FLAGS ]" - " [DEFINES_FILE ]" " )" ) @@ -319,7 +442,7 @@ if(FLEX_EXECUTABLE) #============================================================ - # ADD_FLEX_BISON_DEPENDENCY (public macro) + # add_flex_bison_dependency() public macro #============================================================ # macro(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)