【问题标题】:CMake and Flex/BisonCMake 和 Flex/Bison
【发布时间】:2013-10-24 06:06:24
【问题描述】:

我正在将我的构建系统从 configure/make 转换为 cmake 系统

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

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

我遇到了this ancient link,它似乎解释了如何做到这一点,但是当我使用以下自定义命令运行 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 是什么?

【问题讨论】:

  • 你能把使用生成文件的部分 CMakeList 贴出来吗?
  • 请注意标签。 Flex-lexer 用于词法分析器; flex 标签用于 Adob​​e/Apache UI 框架。
  • 抱歉,'flex' 是自动向我建议的,我没想到要检查描述

标签: c++ makefile cmake bison flex-lexer


【解决方案1】:

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

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

是你会做的。 Flex 也是如此。

【讨论】:

  • 不适用于旧版本 Flex 版本应该是 2.5.5 或更高版本。原因是这些函数传递的参数。
  • 使用该命令时,Bison生成的header如何在代码中使用? #include "parser.hpp#include "parser.tab.hpp" 都不适合我...
  • @AleksandarStefanović 根据 Cmake 文档,将生成一个标头,其文件名将由某个宏定义。我不知道为什么会这样:显然你想在你的代码中有这个名字。
【解决方案2】:

add_custom_commands 的格式不太正确,但它们似乎几乎是正确的。 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 时),并且仅当您正在构建直接或间接需要 @ 的目标时987654330@文件。

要修复您的命令,我认为以下应该可以工作(未经测试):

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

【讨论】:

  • 这看起来不错,虽然我不确定 add_library 的用途,您能详细说明一下吗?
  • @LordAro - 抱歉,我本可以更清楚一点。我只是想给出一个实际使用输出文件作为另一个命令输入的例子。我不希望您实际上有一个名为“MyLib”的库,或者任何目标都只使用这两个文件。我想这些文件将是许多文件中的 2 个,它们在您的 CMakeLists.txt 中包含一个 lib/exe。
  • 好的,这就是我的怀疑,而且,它似乎工作 :) 非常感谢
  • 野牛使用的新热点实际上记录在cmake.org 所以bison_target(parser fl.ypp fl.tab.cpp) add_executable(fl ${BISON_parser_OUTPUTS}) 是你要做的。 Flex 也是如此。
  • scanner.l parser.hparser.tab.h 应在自定义命令中添加为 DEPENDS,以便在修改 .l.y 文件时重新生成解析器/词法分析器。解析器仅依赖于parser.y,但词法分析器同时依赖于scanner.l 和野牛生成的任何标头,通常是parser.tab.h
猜你喜欢
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多