2023-11-01 06:11:15 +08:00
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
F i n d F L E X
- - - - - - - -
2023-11-01 06:20:22 +08:00
F i n d F a s t L e x i c a l Analyzer ( Flex ) e x e c u t a b l e a n d p r o v i d e s a m a c r o
t o g e n e r a t e c u s t o m b u i l d r u l e s
2023-11-01 06:11:15 +08:00
T h e m o d u l e d e f i n e s t h e f o l l o w i n g v a r i a b l e s :
: :
2023-11-01 06:20:22 +08:00
F L E X _ F O U N D - T r u e i s f l e x e x e c u t a b l e i s f o u n d
2023-11-01 06:11:15 +08:00
F L E X _ E X E C U T A B L E - t h e p a t h t o t h e f l e x e x e c u t a b l e
F L E X _ V E R S I O N - t h e v e r s i o n o f f l e x
F L E X _ L I B R A R I E S - T h e f l e x l i b r a r i e s
F L E X _ I N C L U D E _ D I R S - T h e p a t h t o t h e f l e x h e a d e r s
T h e m i n i m u m r e q u i r e d v e r s i o n o f f l e x c a n b e s p e c i f i e d u s i n g t h e
2023-11-01 06:20:22 +08:00
s t a n d a r d s y n t a x , e . g . : c o m m a n d : ` find_package ( FLEX 2.5.13 ) `
2023-11-01 06:11:15 +08:00
I f f l e x i s f o u n d o n t h e s y s t e m , t h e m o d u l e p r o v i d e s t h e m a c r o :
: :
FLEX_TARGET ( Name FlexInput FlexOutput
[ C O M P I L E _ F L A G S < s t r i n g > ]
[ D E F I N E S _ F I L E < s t r i n g > ]
)
2023-11-01 06:20:22 +08:00
w h i c h c r e a t e s a c u s t o m c o m m a n d t o g e n e r a t e t h e ` ` F l e x O u t p u t ` ` f i l e f r o m
t h e ` ` F l e x I n p u t ` ` f i l e . I f ` ` C O M P I L E _ F L A G S ` ` o p t i o n i s s p e c i f i e d , t h e n e x t
2023-11-01 06:11:15 +08:00
p a r a m e t e r i s a d d e d t o t h e f l e x c o m m a n d l i n e . I f f l e x i s c o n f i g u r e d t o
2023-11-01 06:20:22 +08:00
o u t p u t a h e a d e r f i l e , t h e ` ` D E F I N E S _ F I L E ` ` o p t i o n m a y b e u s e d t o s p e c i f y i t s
2023-11-01 06:11:15 +08:00
n a m e . N a m e i s a n a l i a s u s e d t o g e t d e t a i l s o f t h i s c u s t o m c o m m a n d .
I n d e e d t h e m a c r o d e f i n e s t h e f o l l o w i n g v a r i a b l e s :
: :
F L E X _ $ { N a m e } _ D E F I N E D - t r u e i s t h e m a c r o r a n s u c c e s s f u l l y
F L E X _ $ { N a m e } _ O U T P U T S - t h e s o u r c e f i l e g e n e r a t e d b y t h e c u s t o m r u l e , a n
a l i a s f o r F l e x O u t p u t
F L E X _ $ { N a m e } _ I N P U T - t h e f l e x s o u r c e f i l e , a n a l i a s f o r $ { F l e x I n p u t }
F L E X _ $ { N a m e } _ O U T P U T _ H E A D E R - t h e h e a d e r f l e x o u t p u t , i f a n y .
F l e x s c a n n e r s o f t e n u s e t o k e n s d e f i n e d b y B i s o n : t h e c o d e g e n e r a t e d
b y F l e x d e p e n d s o f t h e h e a d e r g e n e r a t e d b y B i s o n . T h i s m o d u l e a l s o
d e f i n e s a m a c r o :
: :
ADD_FLEX_BISON_DEPENDENCY ( FlexTarget BisonTarget )
w h i c h a d d s t h e r e q u i r e d d e p e n d e n c y b e t w e e n a s c a n n e r a n d a p a r s e r
2023-11-01 06:20:22 +08:00
w h e r e ` ` F l e x T a r g e t ` ` a n d ` ` B i s o n T a r g e t ` ` a r e t h e f i r s t p a r a m e t e r s o f
r e s p e c t i v e l y ` ` F L E X _ T A R G E T ` ` a n d ` ` B I S O N _ T A R G E T ` ` m a c r o s .
2023-11-01 06:11:15 +08:00
: :
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
E x a m p l e :
: :
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 )
: :
include_directories ( ${ CMAKE_CURRENT_BINARY_DIR } )
add_executable ( Foo
F o o . c c
$ { B I S O N _ M y P a r s e r _ O U T P U T S }
$ { F L E X _ M y S c a n n e r _ O U T P U T S }
)
2023-11-01 06:20:22 +08:00
target_link_libraries ( Foo ${ FLEX_LIBRARIES } )
2023-11-01 06:11:15 +08:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#]=======================================================================]
find_program ( FLEX_EXECUTABLE NAMES flex win_flex DOC "path to the flex executable" )
mark_as_advanced ( FLEX_EXECUTABLE )
find_library ( FL_LIBRARY NAMES fl
D O C " P a t h t o t h e f l l i b r a r y " )
find_path ( FLEX_INCLUDE_DIR FlexLexer.h
D O C " P a t h t o t h e f l e x h e a d e r s " )
mark_as_advanced ( FL_LIBRARY FLEX_INCLUDE_DIR )
set ( FLEX_INCLUDE_DIRS ${ FLEX_INCLUDE_DIR } )
set ( FLEX_LIBRARIES ${ FL_LIBRARY } )
if ( FLEX_EXECUTABLE )
execute_process ( COMMAND ${ FLEX_EXECUTABLE } --version
O U T P U T _ V A R I A B L E F L E X _ v e r s i o n _ o u t p u t
E R R O R _ V A R I A B L E F L E X _ v e r s i o n _ e r r o r
R E S U L T _ V A R I A B L E F L E X _ v e r s i o n _ r e s u l t
O U T P U T _ S T R I P _ T R A I L I N G _ W H I T E S P A C E )
if ( NOT ${ FLEX_version_result } EQUAL 0 )
if ( FLEX_FIND_REQUIRED )
message ( SEND_ERROR "Command \" ${ FLEX_EXECUTABLE } --version\ " failed with output:\n${FLEX_version_output}\n${FLEX_version_error}" )
else ( )
message ( "Command \" ${ FLEX_EXECUTABLE } --version\ " failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available" )
endif ( )
else ( )
# older versions of flex printed "/full/path/to/executable version X.Y"
# newer versions use "basename(executable) X.Y"
get_filename_component ( FLEX_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE )
get_filename_component ( FLEX_EXE_EXT "${FLEX_EXECUTABLE}" EXT )
string ( REGEX REPLACE "^.*${FLEX_EXE_NAME_WE}(${FLEX_EXE_EXT})?\" ? ( version ) ?([0-9]+[^ ]* ) ( . * ) ? $ " " \ \ 3 "
F L E X _ V E R S I O N " $ { F L E X _ v e r s i o n _ o u t p u t } " )
unset ( FLEX_EXE_EXT )
unset ( FLEX_EXE_NAME_WE )
endif ( )
#============================================================
# FLEX_TARGET (public macro)
#============================================================
#
macro ( FLEX_TARGET Name Input Output )
set ( FLEX_TARGET_PARAM_OPTIONS )
set ( FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS
C O M P I L E _ F L A G S
D E F I N E S _ F I L E
)
set ( FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS )
cmake_parse_arguments (
F L E X _ T A R G E T _ A R G
" $ { F L E X _ T A R G E T _ P A R A M _ O P T I O N S } "
" $ { F L E X _ T A R G E T _ P A R A M _ O N E _ V A L U E _ K E Y W O R D S } "
" $ { F L E X _ T A R G E T _ M U L T I _ V A L U E _ K E Y W O R D S } "
$ { A R G N }
)
set ( FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>] [DEFINES_FILE <string>]" )
if ( NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "" )
message ( SEND_ERROR ${ FLEX_TARGET_usage } )
else ( )
2023-11-01 06:34:31 +08:00
cmake_policy ( GET CMP0098 _flex_CMP0098
P A R E N T _ S C O P E # undocumented, do not use outside of CMake
)
set ( _flex_INPUT "${Input}" )
if ( "x${_flex_CMP0098}x" STREQUAL "xNEWx" )
set ( _flex_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}" )
if ( NOT IS_ABSOLUTE "${_flex_INPUT}" )
set ( _flex_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_flex_INPUT}" )
endif ( )
else ( )
set ( _flex_WORKING_DIR "${CMAKE_CURRENT_SOURCE_DIR}" )
endif ( )
unset ( _flex_CMP0098 )
set ( _flex_OUTPUT "${Output}" )
if ( NOT IS_ABSOLUTE ${ _flex_OUTPUT } )
set ( _flex_OUTPUT "${_flex_WORKING_DIR}/${_flex_OUTPUT}" )
endif ( )
set ( _flex_TARGET_OUTPUTS "${_flex_OUTPUT}" )
set ( _flex_EXE_OPTS "" )
2023-11-01 06:11:15 +08:00
if ( NOT "${FLEX_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "" )
2023-11-01 06:34:31 +08:00
set ( _flex_EXE_OPTS "${FLEX_TARGET_ARG_COMPILE_FLAGS}" )
separate_arguments ( _flex_EXE_OPTS )
2023-11-01 06:11:15 +08:00
endif ( )
2023-11-01 06:34:31 +08:00
set ( _flex_OUTPUT_HEADER "" )
2023-11-01 06:11:15 +08:00
if ( NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "" )
2023-11-01 06:34:31 +08:00
set ( _flex_OUTPUT_HEADER "${FLEX_TARGET_ARG_DEFINES_FILE}" )
if ( IS_ABSOLUTE "${_flex_OUTPUT_HEADER}" )
set ( _flex_OUTPUT_HEADER_ABS "${_flex_OUTPUT_HEADER}" )
else ( )
set ( _flex_OUTPUT_HEADER_ABS "${_flex_WORKING_DIR}/${_flex_OUTPUT_HEADER}" )
endif ( )
list ( APPEND _flex_TARGET_OUTPUTS "${_flex_OUTPUT_HEADER_ABS}" )
list ( APPEND _flex_EXE_OPTS --header-file= ${ _flex_OUTPUT_HEADER_ABS } )
2023-11-01 06:11:15 +08:00
endif ( )
2023-11-01 06:34:31 +08:00
get_filename_component ( _flex_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE )
add_custom_command ( OUTPUT ${ _flex_TARGET_OUTPUTS }
C O M M A N D $ { F L E X _ E X E C U T A B L E } $ { _ f l e x _ E X E _ O P T S } - o $ { _ f l e x _ O U T P U T } $ { _ f l e x _ I N P U T }
2023-11-01 06:11:15 +08:00
V E R B A T I M
2023-11-01 06:34:31 +08:00
D E P E N D S $ { _ f l e x _ I N P U T }
C O M M E N T " [ F L E X ] [ $ { N a m e } ] B u i l d i n g s c a n n e r w i t h $ { _ f l e x _ E X E _ N A M E _ W E } $ { F L E X _ V E R S I O N } "
W O R K I N G _ D I R E C T O R Y $ { _ f l e x _ W O R K I N G _ D I R } )
2023-11-01 06:11:15 +08:00
set ( FLEX_ ${ Name } _DEFINED TRUE )
2023-11-01 06:34:31 +08:00
set ( FLEX_ ${ Name } _OUTPUTS ${ _flex_TARGET_OUTPUTS } )
set ( FLEX_ ${ Name } _INPUT ${ _flex_INPUT } )
set ( FLEX_ ${ Name } _COMPILE_FLAGS ${ _flex_EXE_OPTS } )
set ( FLEX_ ${ Name } _OUTPUT_HEADER ${ _flex_OUTPUT_HEADER } )
unset ( _flex_EXE_NAME_WE )
unset ( _flex_EXE_OPTS )
unset ( _flex_INPUT )
unset ( _flex_OUTPUT )
unset ( _flex_OUTPUT_HEADER )
unset ( _flex_OUTPUT_HEADER_ABS )
unset ( _flex_TARGET_OUTPUTS )
unset ( _flex_WORKING_DIR )
2023-11-01 06:11:15 +08:00
endif ( )
endmacro ( )
#============================================================
#============================================================
# ADD_FLEX_BISON_DEPENDENCY (public macro)
#============================================================
#
macro ( ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget )
if ( NOT FLEX_ ${ FlexTarget } _OUTPUTS )
message ( SEND_ERROR "Flex target `${FlexTarget}' does not exist." )
endif ( )
if ( NOT BISON_ ${ BisonTarget } _OUTPUT_HEADER )
message ( SEND_ERROR "Bison target `${BisonTarget}' does not exist." )
endif ( )
set_source_files_properties ( ${ FLEX_${FlexTarget } _OUTPUTS}
P R O P E R T I E S O B J E C T _ D E P E N D S $ { B I S O N _ $ { B i s o n T a r g e t } _ O U T P U T _ H E A D E R } )
endmacro ( )
#============================================================
endif ( )
include ( ${ CMAKE_CURRENT_LIST_DIR } /FindPackageHandleStandardArgs.cmake )
FIND_PACKAGE_HANDLE_STANDARD_ARGS ( FLEX REQUIRED_VARS FLEX_EXECUTABLE
V E R S I O N _ V A R F L E X _ V E R S I O N )