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 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.

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
)

在 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>

自 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.