18

我正在将我的构建系统从配置/制作转换为 cmake 系统

系统有一些自动生成的文件,来自 bison/flex。原始的 makefile 命令是:

bison --defines=tokens.h --output=parser.cpp parser.y
flex --outfile=scanner.cpp scanner.l

我遇到了这个古老的链接,它似乎解释了如何做到这一点,但是当我使用以下自定义命令运行 cmake 时,似乎什么也没发生(没有错误消息,没有文件生成)

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)

我是cmake的新手,所以对我来说有点困惑。有谁知道一个有效的 custom_command 是什么?

4

2 回答 2

31

野牛使用的新热点实际上记录在cmake.org所以对于一个简单的解析器项目:

bison_target(parser fl.ypp fl.tab.cpp)
add_executable(fl ${BISON_parser_OUTPUTS})

就是你要做的。对于 Flex 也是如此。

于 2014-07-03T18:59:51.740 回答
13

您的 s 的格式add_custom_command不太正确,但它们似乎几乎是正确的。有两个版本add_custom_command,您想要的一个是生成输出文件的版本(方括号内的部分是可选的):

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

OUTPUT这个想法是,只有当指定为此命令的文件被用作同一 CMakeLists.txt 中其他地方的输入时(例如,在add_libraryadd_executable调用中),自定义命令才会执行。

因此,自定义命令只会在构建时(即运行时make)运行,而不是在配置时(运行 CMake 时)运行,并且仅在您构建直接或间接需要该OUTPUT文件的目标时运行。

要修复您的命令,我认为以下内容应该有效(未经测试):

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})
于 2013-10-16T08:35:13.027 回答