I am converting my build system from configure/make to a cmake system
The system has some autogenerated files, from bison/flex. The original makefile commands are:
bison --defines=tokens.h --output=parser.cpp parser.y
flex --outfile=scanner.cpp scanner.l
I came across this ancient link which seems to explain how to do it, but when i run cmake with the following custom commands, nothing appears to happen (no error messages, no file generation)
FIND_PACKAGE(BISON REQUIRED)
IF(BISON_FOUND)
ADD_CUSTOM_COMMAND(
SOURCE ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMAND ${BISON_EXECUTABLE}
ARGS --defines=${CMAKE_SOURCE_DIR}/src/rcdgen/tokens.h
-o ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMENT "Generating parser.cpp"
OUTPUT ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
)
ENDIF(BISON_FOUND)
FIND_PACKAGE(FLEX REQUIRED)
IF(FLEX_FOUND)
ADD_CUSTOM_COMMAND(
SOURCE ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMAND ${FLEX_EXECUTABLE}
ARGS -o${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMENT "Generating scanner.cpp"
OUTPUT ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.cpp
)
ENDIF(FLEX_FOUND)
I am new to cmake, so it's a bit confusing to me. Does anyone have any idea what a working custom_command would be?
The new hotness for bison usage is actually documented in FindBison So for a simple parser project:
find_package(BISON)
BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h)
add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
is what you'd do. Likewise for Flex.
The format of your add_custom_command
s is not quite right, but they appear to be almost correct. There are two versions of add_custom_command
, and the one you want is the one which produces an output file (the parts inside square brackets are optional):
add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM] [APPEND])
The idea is that the custom command only executes if the file specified as the OUTPUT
of this command is used as an input elsewhere in the same CMakeLists.txt (e.g. in an add_library
or add_executable
call).
The custom command therefore will only run at build time (i.e. when you run make
), not at configure time (when you run CMake), and only if you're building a target which directly or indirectly needs the OUTPUT
file.
To fix your commands, I think the following should work (untested):
FIND_PACKAGE(BISON REQUIRED)
SET(BisonOutput ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp)
IF(BISON_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${BisonOutput}
COMMAND ${BISON_EXECUTABLE}
--defines=${CMAKE_SOURCE_DIR}/src/rcdgen/tokens.h
--output=${BisonOutput}
${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMENT "Generating parser.cpp"
)
ENDIF()
FIND_PACKAGE(FLEX REQUIRED)
SET(FlexOutput ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.cpp)
IF(FLEX_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${FlexOutput}
COMMAND ${FLEX_EXECUTABLE}
--outfile=${FlexOutput}
${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMENT "Generating scanner.cpp"
)
ENDIF()
ADD_LIBRARY(MyLib ${BisonOutput} ${FlexOutput})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With