簡體   English   中英

CMake FindFLEX 在 windows 上產生 NOTFOUND

[英]CMake FindFLEX produces NOTFOUND on windows

我用巧克力安裝了 flex 和 bison

choco install winflexbison3

並創建了這個 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})

我寫了一個虛擬解析器(從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.

由於某種原因 CMake 找不到庫並包含目錄。 我應該怎么辦? FLEX 期望這些庫在哪里?

這是我到目前為止所做的:

我看到 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

我看到 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})

我找到了 find_path http://devdoc.net/linux/cmake-3.9.6/command/find_path.html的文檔,並且有一個搜索路徑列表。 我問他們

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

並得到

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

所以看起來find_path完全沒有做任何事情。 我應該自己指定路徑嗎? 但是這種情況下 CMake 甚至是為了什么?

令人震驚的是,一個微不足道的庫文件導致了多少惱人的問題,這些庫文件可能無論如何都不應該存在,而且幾乎不需要。

有問題的庫最初稱為libll用於 lex),Posix 要求當您鏈接包含 lex 生成的掃描程序的可執行文件時,您將-ll添加到 linker 調用中。 從所有意圖和目的來看,Flex 都是 Lex 工具的當前繼任者,它決定將庫的名稱更改為libfl ,這通常是您在 Flex 安裝中會找到的內容。 因此,這些天(即過去幾十年)您會發現的通常說明說您應該使用命令行選項-lfl

通常,但並非總是如此,發行版會為libl添加符號鏈接(或等效鏈接),以便 Posix 指定的-ll仍然有效。 有時,Flex 發行版會被修改,以便將庫稱為libl ,在這種情況下-lfl將不起作用。 有時,該庫根本不是發行版的一部分,需要從不同的 package 獲取。

Posix 想要迎合 Lex 實現,它將一些函數放入庫中,而不是每次都生成相同的代碼。 但是很少(如果有的話) lex 實現利用了該條款。 特別是,Flex 生成的掃描器對於任何內部 function 都不依賴libfl 該庫中只定義了兩個函數:

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

int yywrap(void) { return 1; }

第一個是main的默認實現,它只調用yylex直到它返回 0(表示 EOF)。 這對於快速而骯臟的掃描器規則測試可能很方便,但是任何真正的項目肯定會有一個main()定義。

第二個提供默認的yywrap實現。 但是,Flex 提供了一種更簡單的方式來指示不需要yywrap功能:

%option noyywrap

如果您不需要yywrap ,您只需將以上內容添加到您的.l文件中(在序言中)。 如果您確實需要yywrap ,那么您需要定義它。 無論哪種情況,您都不需要該庫。

所以我的建議是,與其浪費你的時間試圖找出你正在使用的 flex 打包的缺陷,只需將上面的%option添加到你的 Flex 輸入文件中,並從你的構建規則中刪除庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM