How to write a working cmake file for flex & bison?

ⅰ亾dé卋堺 提交于 2019-12-24 07:27:44

问题


I am writing a small parser, but have problems of using cmake.

My purpose is: flex F.l => F.cc, bison B.y => B.cc, my_program.cc + F.cc + B.cc => library

My first attempt:

FIND_PACKAGE(FLEX REQUIRED)
if (FLEX_FOUND)
    ADD_CUSTOM_TARGET(
        flex_target
        COMMAND ${FLEX_EXECUTABLE} 
            --header-file=${CMAKE_CURRENT_SOURCE_DIR}/F.h
            --outfile=${CMAKE_CURRENT_SOURCE_DIR}/F.cc
            ${CMAKE_CURRENT_SOURCE_DIR}/F.l
        COMMENT "Generating F.cc"
    )
endif(FLEX_FOUND)
FIND_PACKAGE(BISON REQUIRED)
if (BISON_FOUND)
    ADD_CUSTOM_TARGET(
        bison_target
        COMMAND ${BISON_EXECUTABLE} 
            --defines=${CMAKE_CURRENT_SOURCE_DIR}/B.h
            --output=${CMAKE_CURRENT_SOURCE_DIR}/B.cc
            ${CMAKE_CURRENT_SOURCE_DIR}/B.y
        COMMENT "Generating B.cc"
    )
endif(BISON_FOUND)

add_library(my_library my_program.cc F.cc B.cc)
add_dependencies(my_library bison_target)
add_dependencies(my_library flex_target)

Everything is OK except that flex & bison commands are called every time when I run make, even F.l and B.y files are NOT changed.

Then I try to switch to use ADD_CUSTOM_COMMAND instead of ADD_CUSTOM_TARGET.

FIND_PACKAGE(FLEX REQUIRED)
if (FLEX_FOUND)
    ADD_CUSTOM_COMMAND(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/F.cc
        SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/F.l
        COMMAND ${FLEX_EXECUTABLE} 
            --header-file=${CMAKE_CURRENT_SOURCE_DIR}/F.h
            --outfile=${CMAKE_CURRENT_SOURCE_DIR}/F.cc
            ${CMAKE_CURRENT_SOURCE_DIR}/F.l
        COMMENT "Generating F.cc"
    )
endif(FLEX_FOUND)
FIND_PACKAGE(BISON REQUIRED)
if (BISON_FOUND)
    ADD_CUSTOM_COMMAND(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/B.cc
        SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/B.y
        COMMAND ${BISON_EXECUTABLE} 
            --defines=${CMAKE_CURRENT_SOURCE_DIR}/B.h
            --output=${CMAKE_CURRENT_SOURCE_DIR}/B.cc
            ${CMAKE_CURRENT_SOURCE_DIR}/B.y
        COMMENT "Generating B.cc"
    )
endif(BISON_FOUND)

add_library(my_library my_program.cc F.cc B.cc)

Note that it seems that I can't add dependencies for ADD_CUSTOM_COMMAND.

Then when I run make it seems that flex & bison will only run ONCE. It won't run second time even .l and .y files are changed.

Is there a way to achieve my goal?

Thanks.


回答1:


CMake has module for both Flex and Bison, so you could do this:

find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)

flex_target(lexer F.l "${CMAKE_CURRENT_BINARY_DIR}/F.cc")

bison_target(parser B.y "${CMAKE_CURRENT_BINARY_DIR}/B.cc")

add_library(my_library STATIC
    ${sources}
    "${CMAKE_CURRENT_BINARY_DIR}/F.cc"
    "${CMAKE_CURRENT_BINARY_DIR}/B.cc"
)

Note that both flex_target and bison_target use add_custom_command internally.

Edit: For completeness, as @vre points out in comments, there's FindFLEX provides add_flex_bison_dependency command:

add_flex_bison_dependency(lexer parser)

Which makes lexer depend on parser, in order to allow former use tokens from later.




回答2:


  1. Yes, you need to use add_custom_command.
  2. Do not output into source dir, use inary dir for that.
  3. List input file in the DEPENDS section to make CMake track changes and re-run the command whenever it changes.

See the add_custom_command documentation for more info.



来源:https://stackoverflow.com/questions/50827935/how-to-write-a-working-cmake-file-for-flex-bison

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!