如何为flex& amp写一个工作的cmake文件野牛?

时间:2018-06-13 01:27:28

标签: cmake bison flex-lexer

我正在编写一个小解析器,但是在使用cmake方面存在问题。

我的目的是:flex F.l => F.cc,bison B.y => B.cc, my_program.cc + F.cc + B.cc =>文库

我的第一次尝试:

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)

一切都很好,除了flex&每次运行make时都会调用bison命令,甚至不会更改F.l和B.y文件。

然后我尝试切换到使用ADD_CUSTOM_COMMAND而不是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)

请注意,我似乎无法为ADD_CUSTOM_COMMAND添加依赖项。

然后,当我跑步时,似乎flex&野牛只会运行一次。它甚至不会第二次运行.l和.y文件都会被更改。

有没有办法实现我的目标?

感谢。

2 个答案:

答案 0 :(得分:4)

CMake有FlexBison模块,所以你可以这样做:

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"
)

请注意,flex_targetbison_target都在内部使用add_custom_command

修改:为了完整性,正如@vre在评论中指出的那样,FindFLEX提供了add_flex_bison_dependency命令:

add_flex_bison_dependency(lexer parser)

使lexer取决于parser,以便以后允许以前使用令牌。

答案 1 :(得分:1)

  1. 是的,您需要使用add_custom_command
  2. 不要输入源目录,请使用inary目录。
  3. 列出DEPENDS部分中的输入文件以进行CMake跟踪更改,并在命令发生变化时重新运行该命令。
  4. 有关详细信息,请参阅add_custom_command documentation