将 GLEW 与 cmake 链接的问题
Posted
技术标签:
【中文标题】将 GLEW 与 cmake 链接的问题【英文标题】:Problems linking GLEW with cmake 【发布时间】:2021-12-08 13:18:08 【问题描述】:我有一个使用 VTK 渲染的 C++ 项目,该项目是使用 MXE 为 Windows 构建的。 这个项目在过去建造得很好。最近,我构建它的机器发生了变化,主要是添加了一个额外的硬盘驱动器并完成了完整的更新。从那时起,我的旧版本在链接阶段失败并出现以下错误:
[8%] Linking CXX executable <name>.exe
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):
vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4299):
undefined reference to `__imp___glewGenVertexArrays'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x42ae):
undefined reference to `__imp___glewGenBuffers'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4300):
undefined reference to `__imp___glewDeleteVertexArrays'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4323):
undefined reference to `__imp___glewBindBuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4331):
undefined reference to `__imp___glewDeleteBuffers'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4353):
undefined reference to `__imp___glewBindBuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x4361):
undefined reference to `__imp___glewDeleteBuffers'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x12cc3):
undefined reference to `__imp___glewBindVertexArray'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x12cd0):
undefined reference to `__imp___glewBindBuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x12f0d):
undefined reference to `__imp___glewBindVertexArray'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x12f1a):
undefined reference to `__imp___glewBindBuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x12f2b):
undefined reference to `__imp___glewBufferData'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text+0x1300d):
undefined reference to `__imp___glewBufferData'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text$_ZN18vtkVolumeStateRAIID1Ev[_ZN18vtkVolumeStateRAIID1Ev]+0x9):
undefined reference to `__imp___glewBindVertexArray'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLGPUVolumeRayCastMapper.cxx.obj):vtkOpenGLGPUVolumeRayCastMapper.cxx:(.text$_ZN18vtkVolumeStateRAIID1Ev[_ZN18vtkVolumeStateRAIID1Ev]+0x17):
undefined reference to `__imp___glewBindBuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLProjectedTetrahedraMapper.cxx.obj):vtkOpenGLProjectedTetrahedraMapper.cxx:(.text+0x43ea):
undefined reference to `__imp___glewDrawRangeElements'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLProjectedTetrahedraMapper.cxx.obj):vtkOpenGLProjectedTetrahedraMapper.cxx:(.text+0x4494):
undefined reference to `__imp___glewBlitFramebuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkOpenGLProjectedTetrahedraMapper.cxx.obj):vtkOpenGLProjectedTetrahedraMapper.cxx:(.text+0x48f7):
undefined reference to `__imp___glewBlitFramebuffer'
/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libvtkRenderingVolumeOpenGL2-8.2.a(vtkVolumeTexture.cxx.obj):vtkVolumeTexture.cxx:(.text+0x3349):
undefined reference to `__imp___glewTexSubImage3D'
collect2: error: ld returned 1 exit status
在我看来,它似乎无法找到 GLEW 库文件。 (请注意,所有缺失的引用都有前缀glew
。)
我第一次尝试解决这个问题是添加类似的东西
find_package(GLEW REQUIRED)
include_directories($GLEW_INCLUDE_DIRS)
link_libraries($GLEW_LIBRARIES)
到我的 CMakeLists。 (请注意,我很少使用 cmake 工作,而这和以下可能只是我做事不正确。) 这导致
CMake Error at /opt/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
Could NOT find GLEW (missing: GLEW_LIBRARIES) (found version "2.1.0")
Call Stack (most recent call first):
/opt/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:445 (_FPHSA_FAILURE_MESSAGE)
/opt/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.17/Modules/FindGLEW.cmake:207 (find_package_handle_standard_args)
CMakeLists.txt:41 (find_package)
鉴于此,我假设我需要在这里设置一些变量,因为毕竟我应该使用 MXE 附带的 GLEW 库。所以我在前面加了
set(GLEW_INCLUDE_DIR "/opt/mxe/usr/x86_64-w64-mingw32.static/include/GL/")
set(GLEW_SHARED_LIBRARIES "/opt/mxe/usr/x86_64-w64-mingw32.static/lib/glew32.lib")
set(GLEW_STATIC_LIBRARIES "/opt/mxe/usr/x86_64-w64-mingw32.static/lib/glew32s.lib")
set(GLEW_LIBRARIES "optimized;/opt/mxe/usr/x86_64-w64-mingw32.static/lib/glew32s.lib;debug;optimized;/opt/mxe/usr/x86_64-w64-mingw32.static/lib/glew32s.lib")
# just to see if there is more information gained by this:
set(GLEW_VERBOSE)
尽管设置了GLEW_LIBRARIES
,但仍会导致与以前相同的错误。
根据Linking GLEW with CMake 中的回答,另一个失败的尝试是添加
set(GLEW_LIBRARY "/opt/mxe/usr/x86_64-w64-mingw32.static/lib/")
find_path(GLEW_INCLUDE_DIR glew.h)
find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64)
在这一点上,我感觉我的方法可能是错误的,而不是添加到 CMakeLists,我可能不得不做 一些事情 其他。可能配置 MXE?毕竟,它以前没有额外的行就可以工作。 或者如果我的方法是正确的,也许我的论点不是?路径是现有文件。 有人知道还有什么可以尝试的吗?
编辑:请注意,即使没有我的链接,它根本找不到 GLEW 也很奇怪,因为该系统已将 GLEW 作为常规包安装:
sudo apt-get install -y libglew-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
libglew-dev is already the newest version (2.1.0-4).
0 upgraded, 0 newly installed, 0 to remove and 12 not upgraded.
编辑:根据 Some Programmer Dude 和 Tsyvarev 在 cmets 中所写的内容,我当前的设置看起来有点像这样:
...
find_package(VTK REQUIRED)
include($VTK_USE_FILE)
set(GLEW_INCLUDE_DIR "/opt/mxe/usr/x86_64-w64-mingw32.static/include/")
set(GLEW_LIBRARY "/opt/mxe/usr/x86_64-w64-mingw32.static/lib/")
find_path(GLEW_INCLUDE_DIR GL/glew.h)
add_library(GLEW_LIBRARY glew32 glew glew32s)
include_directories("/opt/mxe/usr/x86_64-w64-mingw32.static/include/GL/" $GLEW_LIBRARY)
link_directories($GLEW_LIBRARY)
...
target_link_libraries(<MyExecutable> <other libraries> -lglew32s -lglew32 -lGLEW)
(有几行很可能不需要)。
链接器似乎找到了库文件(没有找到任何东西的错误),但引用仍然未定义。
我的想法是库文件是否真的指定了所需的符号,如果可能是某些版本不兼容,所以我执行了
nm libglew32
并在输出中搜索“glewGenVertexArrays”,是的,存在:
0000000000003a68 B __glewGenVertexArrays
为了提供更多信息,这里是我的 CMakeLists.txt 的内容,没有上面提到的 GLEW 的附加行,并且项目名称等某些部分被替换为 <placeholder>
之类的东西:
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
cmake_minimum_required(VERSION 3.1.0)
PROJECT(<name>)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 REQUIRED Core Gui Svg Widgets Xml)
find_package(Qt5 COMPONENTS Network REQUIRED)
find_package(BZip2 REQUIRED)
find_package(VTK REQUIRED)
include($VTK_USE_FILE)
qt5_add_resources(<name> resources.qrc)
include_directories (<some subdirectories>)
LINK_DIRECTORIES ( release /var/opt/mxe/usr/x86_64-w64-mingw32.static/qt5/lib /var/opt/mxe/usr/x86_64-w64-mingw32.static/lib/)
qt5_wrap_ui(UISrcs $UI_FILES )
set(APP_ICON_RESOURCE_WINDOWS <icon file>)
add_executable(<name> WIN32 main/main.cpp $APP_ICON_RESOURCE_WINDOWS)
qt5_use_modules(<name> Core Gui Svg Widgets Xml Network)
target_link_libraries(<name> core Qt5::Core Qt5::QWindowsIntegrationPlugin Qt5::QSvgPlugin $QT5ALL_LDFLAGS Qt5::Widgets Qt5::Xml Qt5::Svg Qt5::Gui Qt5::Network $QT5SVG_LIBRARIES -lQt5EventDispatcherSupport -lQt5AccessibilitySupport -lQt5FontDatabaseSupport -lQt5ThemeSupport -lQt5WindowsUIAutomationSupport $VTK_LIBRARIES -lfreetype -lharfbuzz_too -lfreetype_too $BZIP2_LIBRARIES)
在此,core
是一个包含项目大部分类的库,基本上除了 main
函数之外的所有类。
除了之前写的,我尝试在上面的最后一行显式添加库文件:
target_link_libraries(<name> <other libraries> /var/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libGLEW.a /var/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libglew32.a /var/opt/mxe/usr/x86_64-w64-mingw32.static/lib/libglew32s.a)
也不行。
另外,我注意到以下几点:在编译期间,cmake
创建了一个文件CMakeFiles/GLEW_LIBRARY.dir/link.txt
。该文件包含
/var/opt/mxe/usr/bin/x86_64-w64-mingw32.static-ar qc libGLEW_LIBRARY.a CMakeFiles/GLEW_LIBRARY.dir/GLEW_LIBRARY_autogen/mocs_compilation.cpp.obj
/var/opt/mxe/usr/bin/x86_64-w64-mingw32.static-ranlib libGLEW_LIBRARY.a
我觉得很奇怪,因为没有像 libGLEW_LIBRARY.a 这样的文件。
编辑:我现在也将问题直接发布到 VTK 论坛,希望这可能是关于 VTK 的一些具体问题:https://discourse.vtk.org/t/problems-with-linking-glew-in-mxe-build/7522
【问题讨论】:
CMakefind_package
函数不会查看自定义位置。您需要添加 PATHS
选项来指定在哪里可以找到库。
@Someprogrammerdude 将其重写为find_package(GLEW REQUIRED PATHS "/opt/mxe/usr/x86_64-w64-mingw32.static/lib/")
,然后得到消息,它既找不到GLEWConfig.cmake
也找不到glew-config.cmake
。 (文件夹结构中不存在。)我假设我必须触发一些安装?我找到了一个带有 cmake_install.cmake
文件的 glew 目录,但我不愿调用它,特别是因为它位于错误架构的文件夹中(x86 linux 而不是 x86 windows)。
您需要可移植的项目(和CMakeLists.txt
文件)吗?如果没有,那么您可以对目录路径和库进行硬编码。否则,您可以使用find_package(GLEW REQUIRED)
,如果找不到,您可以自己将变量设置为硬编码位置,也可以检查文件和目录以确保。
@Someprogrammerdude 只需要为该特定目标工作。但是,第二种方式对我来说听起来更好。您是否碰巧知道 GLEW 特有的必要硬编码路径?在我的问题中使用find_library
命令,缺少的引用没有得到解决。
我知道 your 项目的硬编码的具体路径,因为你已经提到了它们 (/opt/mxe/usr/x86_64-w64-mingw32.static/...
) :) 你设置 @987654353 的 sn-p @ 变量,使用它,然后在 target_include_directories
和 target_link_libraries
中使用这些变量。
【参考方案1】:
经过一段时间后,我终于修复了它,虽然我不确定为什么修复了它。 在我的代码中,我有初始化命令
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
我认为这是必需的。 删除此行解决了问题。
我不知道为什么会这样,因为这应该是一个有效的命令,所以如果有人对 VTK 有更深入的了解并知道答案,那将不胜感激。 我的猜测是,VTK 的 MXE 版本不适用于体绘制。 我也不知道为什么这个问题是在电脑更新之后才出现的。
【讨论】:
以上是关于将 GLEW 与 cmake 链接的问题的主要内容,如果未能解决你的问题,请参考以下文章
GLEW + cmake 链接失败“未定义对符号 glDrawElements 的引用”+“命令行中缺少 DSO”