I have a C++ project using VTK rendering which is build for Windows using MXE.
This project built just fine in the past. Now recently, the machine on which I build it was altered, mostly an additional hard drive added and a full update being done. Since then, my old build fails in the linking stage with the following errors:
[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
Which to me looks as if it is unable to locate the GLEW library files. (Note that all missing references have the prefix glew
.)
My first attempt to fix this was to add something like
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
link_libraries(${GLEW_LIBRARIES})
to my CMakeLists. (Note that I work seldomly with cmake and this and the following might be simply me not doing things properly.)
This results in
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)
Given that, I assumed that I need to set some variables here, since after all, I am supposed to use the GLEW libraries that come with MXE. Thus I prepended
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)
This resulted in the same error as before, despite GLEW_LIBRARIES
being set.
Another failed attempt, based on an answer in Linking GLEW with CMake, was to add
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)
At this point I have the feeling that my approach might be wrong and instead of adding to CMakeLists, I might have to do something else. Possibly configuring MXE? After all, it has worked before without additional lines.
Or if my approach is correct, maybe my arguments aren't? The paths are existing files.
Does anybody have an idea what else to try?
Edit: Note that even without me linking, it is rather strange that it does not find GLEW at all, given that this system has GLEW installed as regular package:
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.
Edit: After what Some Programmer Dude and Tsyvarev wrotein the comments, my current setup looks somewhat like this:
...
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)
(with several of the lines most likely not being necessary).
The linker seems to find the library files (no error about not finding something), but the references are still undefined.
My thought was whether the library files actually specify the required symbols, if it might be some version incompatibility, so I executed
nm libglew32
and searched for "glewGenVertexArrays" in the output, and yes, exists:
0000000000003a68 B __glewGenVertexArrays
In order to give more information, here is the content of my CMakeLists.txt, without the additional lines for GLEW as mentioned above, and with some parts like the project name being replaced by something like <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})
In this, core
is a library which contains most of the classes of the project, basically everything but the main
function.
Other than what was written before, I tried adding the library files explicitely in the last line above:
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)
doesn't work either.
Also, I noticed the following: during compilation, cmake
creates a file CMakeFiles/GLEW_LIBRARY.dir/link.txt
. This file contains
/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
which I find odd, given that there is no such file as libGLEW_LIBRARY.a.
Edit: I now also posted the question directly to the VTK forum, hoping that this might be a somewhat specific problem in regard to VTK: https://discourse.vtk.org/t/problems-with-linking-glew-in-mxe-build/7522