# FindFLEX

Finds the Fast Lexical Analyzer (Flex) command-line generator and its library, and provides CMake commands to create custom build rules for using Flex:

    find_package(FLEX [<version>] [...])

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`

  Boolean indicating whether (the requested version of) Flex was 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.

## Commands

This module provides the following commands if `flex` is found:

### Generating Scanners

flex_target

  Creates a custom build rule to generate a scanner file from a lex file using Flex:

      flex_target(
        <name>
        <input-lex-file>
        <output-scanner-file>
        [DEFINES_FILE <header>]
        [OPTIONS <options>...]
        [COMPILE_FLAGS <string>] # Deprecated
      )

  Changed in version 3.17: When policy `CMP0098` is set to `NEW`, `flex` runs in the `CMAKE_CURRENT_BINARY_DIR` directory.

  `<name>`

    String used as an identifier for this command invocation.

  `<input-lex-file>`

    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 (`CMAKE_CURRENT_SOURCE_DIR`).

  `<output-scanner-file>`

    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.

  `DEFINES_FILE <header>`

    Added in version 3.5.

    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.

  `OPTIONS <options>...`

    Added in version 4.0.

    A semicolon-separated list of extra options added to the `flex` command line.

  `COMPILE_FLAGS <string>`

    Deprecated since version 4.0: Superseded by `OPTIONS <options>...`.

    A string of space-separated extra options added to the `flex` command line. A semicolon-separated list will not work.

  Command variables

  This command also defines the following variables:

  `FLEX_<name>_DEFINED`

    Boolean indicating whether this command was successfully invoked.

  `FLEX_<name>_INPUT`

    The Flex source file, an alias for `<input-lex-file>`.

  `FLEX_<name>_OUTPUT_HEADER`

    Added in version 3.5.

    The header file generated by `flex`, if any.

  `FLEX_<name>_OUTPUTS`

    A list of files generated by `flex`, including the output scanner file, and the header file.

  `FLEX_<name>_OPTIONS`

    Added in version 4.0.

    A list of command-line options used for the `flex` command.

### Adding Dependency Between Scanner and Parser

add_flex_bison_dependency

  Adds the required dependency between a scanner and a parser:

      add_flex_bison_dependency(<flex-name> <bison-name>)

  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 `<flex-name>` and `<bison-name>` are the first parameters of respectively `flex_target(<name> ...)` and `bison_target(<name> ...)` commands.

## Examples

### Examples: Finding Flex

Finding Flex:

    find_package(FLEX)

Finding Flex and specifying its minimum required version:

    find_package(FLEX 2.5.13)

Finding Flex and making it required (if Flex is not found, processing stops with an error message):

    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:

    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.

    find_package(FLEX)

    if(FLEX_FOUND)
      flex_target(MyScanner lexer.l lexer.cpp OPTIONS --warn --noline)
    endif()

`Generator expressions` can be used in the `OPTIONS <options>...` argument. For example, to add the `--debug` (`-d`) option only for the `Debug` build type:

    find_package(FLEX)

    if(FLEX_FOUND)
      flex_target(MyScanner lexer.l lexer.cpp OPTIONS $<$<CONFIG:Debug>:--debug>)
    endif()

### Example: Using Flex Library

Finding Flex and creating an interface imported target that encapsulates its library usage requirements for linking to a project target:

    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 `Bison` in 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 `FindBISON` module to find Bison parser generator.