简体   繁体   English

CMake FindFLEX 在 windows 上产生 NOTFOUND

[英]CMake FindFLEX produces NOTFOUND on windows

I installed flex and bison with chocolatey我用巧克力安装了 flex 和 bison

choco install winflexbison3

and created this CMakeLists.txt并创建了这个 CMakeLists.txt

find_package(BISON)
find_package(FLEX)
message("FLEX_FOUND: ${FLEX_FOUND}")
message("FLEX_EXECUTABLE: ${FLEX_EXECUTABLE}")
message("FLEX_INCLUDE_DIRS: ${FLEX_INCLUDE_DIRS}")
message("FLEX_LIBRARIES: ${FLEX_LIBRARIES}")

BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
FLEX_TARGET(MyScanner lexer.l  ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
 add_executable(Foo
    ${BISON_MyParser_OUTPUTS}
    ${FLEX_MyScanner_OUTPUTS}
 )
 target_link_libraries(Foo ${FLEX_LIBRARIES})

I wrote a dummy parser (copied from https://aquamentus.com/flex_bison.html ) and tried to build the project我写了一个虚拟解析器(从https://aquamentus.com/flex_bison.html复制)并尝试构建项目

-- Found BISON: C:/ProgramData/chocolatey/bin/win_bison.exe (found version "3.7.4")
-- Found FLEX: C:/ProgramData/chocolatey/bin/win_flex.exe (found version "2.6.4")
FLEX_FOUND: TRUE
FLEX_EXECUTABLE: C:/ProgramData/chocolatey/bin/win_flex.exe
FLEX_INCLUDE_DIRS: FLEX_INCLUDE_DIR-NOTFOUND
FLEX_LIBRARIES: FL_LIBRARY-NOTFOUND
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.23)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
FL_LIBRARY (ADVANCED)
    linked by target "Foo" in directory C:/Users/Aleksander/source/repos/C/insilico/blender/test

-- Generating done
CMake Generate step failed.  Build files cannot be regenerated correctly.

For some reason CMake can't find the library and include dir.由于某种原因 CMake 找不到库并包含目录。 What should I do?我应该怎么办? Where does FLEX expect the libraries to be? FLEX 期望这些库在哪里?

This is what I did so far:这是我到目前为止所做的:

I see FlexLexer.h to be right there我看到 FlexLexer.h 就在那里

C:\ProgramData\chocolatey\lib\winflexbison3\tools> ls
FlexLexer.h          changelog.md           custom_build_rules  win_bison.exe
UNISTD_ERROR.readme  chocolateyInstall.ps1  data                win_flex.exe

I see that FindFLEX uses this source code to look for this file but somehow fails https://github.com/Kitware/CMake/blob/241fc839d56ccd666fe41269e291b8d8190cf97b/Modules/FindFLEX.cmake#L117我看到 FindFLEX 使用这个源代码来查找这个文件,但不知何故失败了 https://github.com/Kitware/CMake/blob/241fc839d56ccd666fe41269e291b8d8190cf97b/Modules/FindFLEX.cmake#L117


find_library(FL_LIBRARY NAMES fl
  DOC "Path to the fl library")

find_path(FLEX_INCLUDE_DIR FlexLexer.h
  DOC "Path to the flex headers")

mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR)

set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
set(FLEX_LIBRARIES ${FL_LIBRARY})

I found this documentation for find_path http://devdoc.net/linux/cmake-3.9.6/command/find_path.html and there is a list of paths that are searched.我找到了 find_path http://devdoc.net/linux/cmake-3.9.6/command/find_path.html的文档,并且有一个搜索路径列表。 I queried them with我问他们

message("CMAKE_INCLUDE_PATH: ${CMAKE_INCLUDE_PATH}")
message("CMAKE_FRAMEWORK_PATH: ${CMAKE_FRAMEWORK_PATH}")
message("CMAKE_SYSTEM_INCLUDE_PATH: ${CMAKE_SYSTEM_INCLUDE_PATH}")
message("CMAKE_SYSTEM_FRAMEWORK_PATH: ${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message("CMAKE_LIBRARY_ARCHITECTURE: ${CMAKE_LIBRARY_ARCHITECTURE}")
message("CMAKE_FIND_ROOT_PATH: ${CMAKE_FIND_ROOT_PATH}")
message("CMAKE_SYSROOT: ${CMAKE_SYSROOT}")

and got并得到

CMAKE_INCLUDE_PATH:
CMAKE_FRAMEWORK_PATH:
CMAKE_SYSTEM_INCLUDE_PATH:
CMAKE_SYSTEM_FRAMEWORK_PATH:
CMAKE_LIBRARY_ARCHITECTURE:
CMAKE_FIND_ROOT_PATH:
CMAKE_SYSROOT:

So it seems that find_path does absolutely nothing.所以看起来find_path完全没有做任何事情。 Should I specify the paths myself?我应该自己指定路径吗? But is such case what is CMake even for?但是这种情况下 CMake 甚至是为了什么?

It's astounding how many irritating problems are caused by a trivial library file which probably shouldn't exist anyway, and which is hardly ever needed.令人震惊的是,一个微不足道的库文件导致了多少恼人的问题,这些库文件可能无论如何都不应该存在,而且几乎不需要。

The library in question was originally called libl ( l for lex), and Posix requires that when you link executables which include a lex-generated scanner, you add -ll to the linker invocation.有问题的库最初称为libll用于 lex),Posix 要求当您链接包含 lex 生成的扫描程序的可执行文件时,您将-ll添加到 linker 调用中。 Flex, which to all intents and purposes is the current successor to the Lex tool, decided to change the name of the library to libfl , and that's generally what you'll find in a Flex installation.从所有意图和目的来看,Flex 都是 Lex 工具的当前继任者,它决定将库的名称更改为libfl ,这通常是您在 Flex 安装中会找到的内容。 So the usual instructions you'll find these days (ie, for the last several decades) say that you should use the command-line option -lfl .因此,这些天(即过去几十年)您会发现的通常说明说您应该使用命令行选项-lfl

Often, but not always, distributions add a symbolic link (or equivalent) for libl so that the Posix-specified -ll still works.通常,但并非总是如此,发行版会为libl添加符号链接(或等效链接),以便 Posix 指定的-ll仍然有效。 Occasionally, the Flex distribution is modified so that the library is called libl , in which case -lfl won't work.有时,Flex 发行版会被修改,以便将库称为libl ,在这种情况下-lfl将不起作用。 And sometimes, the library isn't part of the distribution at all and needs to be acquired from a different package.有时,该库根本不是发行版的一部分,需要从不同的 package 获取。

Posix wanted to cater for a Lex implementation which puts some functions into a library instead of generating the same code each time. Posix 想要迎合 Lex 实现,它将一些函数放入库中,而不是每次都生成相同的代码。 But few (if any) lex implementations ever took advantage of that provision;但是很少(如果有的话) lex 实现利用了该条款。 in particular, Flex-generated scanners have no reliance on libfl for any internal function.特别是,Flex 生成的扫描器对于任何内部 function 都不依赖libfl There are only two functions defined in that library:该库中只定义了两个函数:

int main(void) { while (yylex()) {} }

int yywrap(void) { return 1; }

The first one is a default implementation of main which just calls yylex until it returns 0 (indicating EOF).第一个是main的默认实现,它只调用yylex直到它返回 0(表示 EOF)。 That can be handy for quick-and-dirty scanner rule tests, but any real project will certainly have a main() definition.这对于快速而肮脏的扫描器规则测试可能很方便,但是任何真正的项目肯定会有一个main()定义。

The second provides a default yywrap implementation.第二个提供默认的yywrap实现。 However, Flex provides an even simpler way of indicating that the yywrap functionality isn't required:但是,Flex 提供了一种更简单的方式来指示不需要yywrap功能:

%option noyywrap

If you don't require yywrap , you should just add the above to your .l file (in the prologue).如果您不需要yywrap ,您只需将以上内容添加到您的.l文件中(在序言中)。 If you do require yywrap , then you need to define it.如果您确实需要yywrap ,那么您需要定义它。 In either case, you don't need the library.无论哪种情况,您都不需要该库。

So my recommendation is that rather wasting your time trying to figure out the deficiencies of the flex packaging you're using, just add the above %option to your Flex input file and eliminate the library from your build rules.所以我的建议是,与其浪费你的时间试图找出你正在使用的 flex 打包的缺陷,只需将上面的%option添加到你的 Flex 输入文件中,并从你的构建规则中删除库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM