1 # - Find flex executable and provides a macro to generate custom build rules
3 # The module defines the following variables:
4 # FLEX_FOUND - true is flex executable is found
5 # FLEX_EXECUTABLE - the path to the flex executable
6 # FLEX_VERSION - the version of flex
7 # FLEX_LIBRARIES - The flex libraries
8 # FLEX_INCLUDE_DIRS - The path to the flex headers
10 # The minimum required version of flex can be specified using the
11 # standard syntax, e.g. find_package(FLEX 2.5.13)
14 # If flex is found on the system, the module provides the macro:
15 # FLEX_TARGET(Name FlexInput FlexOutput [COMPILE_FLAGS <string>])
16 # which creates a custom command to generate the <FlexOutput> file from
17 # the <FlexInput> file. If COMPILE_FLAGS option is specified, the next
18 # parameter is added to the flex command line. Name is an alias used to
19 # get details of this custom command. Indeed the macro defines the
20 # following variables:
21 # FLEX_${Name}_DEFINED - true is the macro ran successfully
22 # FLEX_${Name}_OUTPUTS - the source file generated by the custom rule, an
23 # alias for FlexOutput
24 # FLEX_${Name}_INPUT - the flex source file, an alias for ${FlexInput}
26 # Flex scanners oftenly use tokens defined by Bison: the code generated
27 # by Flex depends of the header generated by Bison. This module also
29 # ADD_FLEX_BISON_DEPENDENCY(FlexTarget BisonTarget)
30 # which adds the required dependency between a scanner and a parser
31 # where <FlexTarget> and <BisonTarget> are the first parameters of
32 # respectively FLEX_TARGET and BISON_TARGET macros.
34 # ====================================================================
40 # BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
41 # FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
42 # ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
44 # include_directories(${CMAKE_CURRENT_BINARY_DIR})
47 # ${BISON_MyParser_OUTPUTS}
48 # ${FLEX_MyScanner_OUTPUTS}
50 # ====================================================================
52 #=============================================================================
53 # Copyright 2009 Kitware, Inc.
54 # Copyright 2006 Tristan Carel
56 # Distributed under the OSI-approved BSD License (the "License");
57 # see accompanying file Copyright.txt for details.
59 # This software is distributed WITHOUT ANY WARRANTY; without even the
60 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
61 # See the License for more information.
62 #=============================================================================
63 # (To distribute this file outside of CMake, substitute the full
64 # License text for the above reference.)
66 find_program(FLEX_EXECUTABLE flex DOC "path to the flex executable")
67 mark_as_advanced(FLEX_EXECUTABLE)
69 find_library(FL_LIBRARY NAMES fl
70 DOC "Path to the fl library")
72 find_path(FLEX_INCLUDE_DIR FlexLexer.h
73 DOC "Path to the flex headers")
75 mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR)
77 set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
78 set(FLEX_LIBRARIES ${FL_LIBRARY})
82 execute_process(COMMAND ${FLEX_EXECUTABLE} --version
83 OUTPUT_VARIABLE FLEX_version_output
84 ERROR_VARIABLE FLEX_version_error
85 RESULT_VARIABLE FLEX_version_result
86 OUTPUT_STRIP_TRAILING_WHITESPACE)
87 if(NOT ${FLEX_version_result} EQUAL 0)
88 if(FLEX_FIND_REQUIRED)
89 message(SEND_ERROR "Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}")
91 message("Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available")
94 # older versions of flex printed "/full/path/to/executable version X.Y"
95 # newer versions use "basename(executable) X.Y"
96 get_filename_component(FLEX_EXE_NAME "${FLEX_EXECUTABLE}" NAME)
97 string(REGEX REPLACE "^.*${FLEX_EXE_NAME}\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\2"
98 FLEX_VERSION "${FLEX_version_output}")
102 #============================================================
103 # FLEX_TARGET (public macro)
104 #============================================================
106 macro(FLEX_TARGET Name Input Output)
107 set(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]")
108 if(${ARGC} GREATER 3)
110 if("${ARGV3}" STREQUAL "COMPILE_FLAGS")
111 set(FLEX_EXECUTABLE_opts "${ARGV4}")
112 separate_arguments(FLEX_EXECUTABLE_opts)
114 message(SEND_ERROR ${FLEX_TARGET_usage})
117 message(SEND_ERROR ${FLEX_TARGET_usage})
121 add_custom_command(OUTPUT ${Output}
122 COMMAND ${FLEX_EXECUTABLE}
123 ARGS ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
125 COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
126 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
128 set(FLEX_${Name}_DEFINED TRUE)
129 set(FLEX_${Name}_OUTPUTS ${Output})
130 set(FLEX_${Name}_INPUT ${Input})
131 set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
133 #============================================================
136 #============================================================
137 # ADD_FLEX_BISON_DEPENDENCY (public macro)
138 #============================================================
140 macro(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)
142 if(NOT FLEX_${FlexTarget}_OUTPUTS)
143 message(SEND_ERROR "Flex target `${FlexTarget}' does not exists.")
146 if(NOT BISON_${BisonTarget}_OUTPUT_HEADER)
147 message(SEND_ERROR "Bison target `${BisonTarget}' does not exists.")
150 set_source_files_properties(${FLEX_${FlexTarget}_OUTPUTS}
151 PROPERTIES OBJECT_DEPENDS ${BISON_${BisonTarget}_OUTPUT_HEADER})
153 #============================================================
157 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
158 FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLEX REQUIRED_VARS FLEX_EXECUTABLE
159 VERSION_VAR FLEX_VERSION)
161 # FindFLEX.cmake ends here