如何为flex&bison编写一个有效的cmake文件?

如何为flex&bison编写一个有效的cmake文件?,cmake,bison,flex-lexer,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时遇到问题

我的目标是: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)
除了每次运行make时都会调用flex和bison命令外,一切都正常,即使F.l和B.y文件也不会更改

然后我尝试切换到使用ADD_CUSTOM_命令,而不是ADD_CUSTOM_目标

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_命令添加依赖项

然后当我跑步时,让flex&bison看起来只会跑一次。即使.l和.y文件已更改,它也不会再次运行

有没有办法实现我的目标

谢谢

是的,您需要使用add_custom_命令。 不要输出到源目录,使用inary dir。 在Dependes部分列出输入文件,以进行CMake跟踪更改,并在命令更改时重新运行该命令。 有关更多信息,请参阅

是的,您需要使用add_custom_命令。 不要输出到源目录,使用inary dir。 在Dependes部分列出输入文件,以进行CMake跟踪更改,并在命令更改时重新运行该命令。 有关更多信息,请参阅。

CMake具有和模块,因此您可以执行以下操作:

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_目标和bison_目标都在内部使用add_custom_命令

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

这使得lexer依赖于解析器,以允许前者使用来自后者的令牌。

CMake具有用于和的模块,因此您可以执行以下操作:

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_目标和bison_目标都在内部使用add_custom_命令

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


这使得lexer依赖于解析器,以便允许前者从后面使用令牌。

这是一个次要问题,但您确实不应该使用-y bison选项,如果您指定-define,-d是多余的。@rici谢谢,它在问题中被删除。这是一个次要问题,但您确实不应该使用-y bison选项,如果您指定-defines,-d是多余的。@rici谢谢,它在问题中被删除了。+1,但我更愿意使用FindFLEX.cmake示例${BISON_parser_OUTPUTS}${FLEX_lexer_OUTPUTS}中的建议名称,而不是重复输出名称并提及在某些情况下添加add_FLEX_BISON_dependency parser lexer的必要性。谢谢,更新我的答案查看文档,正确的顺序是lexer,然后是parser。啊,抱歉我弄错了。+1,但我更愿意使用FindFLEX.cmake示例${BISON_parser_OUTPUTS}${FLEX_lexer_OUTPUTS}中建议的名称而不是重复输出名称并提到在某些情况下添加add_flex_bison_dependencParser lexer的必要性。谢谢,更新了我在文档中的答案,正确的顺序是lexer,然后是parser。啊,抱歉我弄错了。