将GLEW与CMake动态链接

Dynamically Linking GLEW with CMake

本文关键字:动态 链接 CMake GLEW      更新时间:2023-10-16

我已经查看了Stack Overflow和Google,试图弄清楚这一点,但我所看到的关于动态链接的一切要么不起作用,要么最终都是静态链接。

E:/CLion/GLEW-Test/main.cpp:8: undefined reference to `_imp__glewInit@0'
E:/CLion/GLEW-Test/main.cpp:12: undefined reference to `_imp__glewGetErrorString@4'
E:/CLion/GLEW-Test/main.cpp:14: undefined reference to `_imp__glewGetString@4'

我正在尝试使用CLion动态链接GLEW。问题是,我是在Visual Studio的陪伴下长大的,所以我从来没有想过太多。我正在努力自学CMake和OpenGL,所以这将是一个完美的练习。

我下载了GLEW的源代码,并用CMake和MinGW构建了它。我将得到的glew32.dll放入C:/Windows/System32/,将libglew32.a放入C:/MinGW/lib,并将glew.hglxew.hwglew.h放入C:/MinGW/include/GL

目前,我的构建目录中还有库glew32.dlllibglu32.alibopengl32.a

这是我的CMakeLists.txt:

cmake_minimum_required(VERSION 3.8)
project(GLEW_Test)
set(CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
set( CMAKE_VERBOSE_MAKEFILE on )
set(SOURCE_FILES main.cpp)
add_executable(GLEW_Test ${SOURCE_FILES})
target_link_libraries(GLEW_Test glew32 glu32 opengl32)

这是我的主.cpp:

#include <iostream>
#include <GL/glew.h>
int main()
{
std::cout << "Hello, World!" << std::endl;
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %sn", glewGetErrorString(err));
}
fprintf(stdout, "Status: Using GLEW %sn", glewGetString(GLEW_VERSION));
return 0;
}

现在,如果I#define GLEW_STATIC先于I#include <GL/glew.h>,则程序编译并输出预期输出(没有GLContext的错误)。然而,据我所知,这是静态链接,我想动态链接GLEW。这是我在没有#define GLEW_STATIC:的情况下编译时看到的情况

"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" --build E:CLionGLEW-Testcmake-build-debug --target GLEW_Test -- -j 2
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -HE:CLionGLEW-Test -BE:CLionGLEW-Testcmake-build-debug --check-build-system CMakeFilesMakefile.cmake 0
C:/MinGW/bin/mingw32-make.exe -f CMakeFilesMakefile2 GLEW_Test
mingw32-make.exe[1]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -HE:CLionGLEW-Test -BE:CLionGLEW-Testcmake-build-debug --check-build-system CMakeFilesMakefile.cmake 0
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -E cmake_progress_start E:CLionGLEW-Testcmake-build-debugCMakeFiles 2
C:/MinGW/bin/mingw32-make.exe -f CMakeFilesMakefile2 CMakeFiles/GLEW_Test.dir/all
mingw32-make.exe[2]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
C:/MinGW/bin/mingw32-make.exe -f CMakeFilesGLEW_Test.dirbuild.make CMakeFiles/GLEW_Test.dir/depend
mingw32-make.exe[3]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -E cmake_depends "MinGW Makefiles" E:CLionGLEW-Test E:CLionGLEW-Test E:CLionGLEW-Testcmake-build-debug E:CLionGLEW-Testcmake-build-debug E:CLionGLEW-Testcmake-build-debugCMakeFilesGLEW_Test.dirDependInfo.cmake --color=
mingw32-make.exe[3]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
C:/MinGW/bin/mingw32-make.exe -f CMakeFilesGLEW_Test.dirbuild.make CMakeFiles/GLEW_Test.dir/build
mingw32-make.exe[3]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
[ 50%] Linking CXX executable GLEW_Test.exe
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -E cmake_link_script CMakeFilesGLEW_Test.dirlink.txt --verbose=1
"C:Program FilesJetBrainsCLion 2017.2.2bincmakebincmake.exe" -E remove -f CMakeFilesGLEW_Test.dir/objects.a
C:MinGWbinar.exe cr CMakeFilesGLEW_Test.dir/objects.a @CMakeFilesGLEW_Test.dirobjects1.rsp
C:MinGWbing++.exe  -Wall -Wextra -g   -Wl,--whole-archive CMakeFilesGLEW_Test.dir/objects.a -Wl,--no-whole-archive  -o GLEW_Test.exe -Wl,--out-implib,libGLEW_Test.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFilesGLEW_Test.dirlinklibs.rsp
CMakeFilesGLEW_Test.dir/objects.a(main.cpp.obj): In function `main':
E:/CLion/GLEW-Test/main.cpp:8: undefined reference to `_imp__glewInit@0'
E:/CLion/GLEW-Test/main.cpp:12: undefined reference to `_imp__glewGetErrorString@4'
E:/CLion/GLEW-Test/main.cpp:14: undefined reference to `_imp__glewGetString@4'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [GLEW_Test.exe] Error 1
CMakeFilesGLEW_Test.dirbuild.make:98: recipe for target 'GLEW_Test.exe' failed
mingw32-make.exe[2]: *** [CMakeFiles/GLEW_Test.dir/all] Error 2
mingw32-make.exe[3]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
mingw32-make.exe[1]: *** [CMakeFiles/GLEW_Test.dir/rule] Error 2
CMakeFilesMakefile2:69: recipe for target 'CMakeFiles/GLEW_Test.dir/all' failed
mingw32-make.exe[2]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
CMakeFilesMakefile2:81: recipe for target 'CMakeFiles/GLEW_Test.dir/rule' failed
mingw32-make.exe[1]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
Makefile:120: recipe for target 'GLEW_Test' failed
mingw32-make.exe: *** [GLEW_Test] Error 2

我做错了什么?我在glew的sourceforge上遵循了指南,并将.dll放在了我的System32文件夹中。由于我使用CMake和MinGW构建,所以我有.a文件而不是.lib文件,并且我将这些文件保存在我的MinGW/lib目录中。我唯一没有做的事(因为我不确定)就是对我的libglew32.dll.a这是罪魁祸首吗?我不知道该怎么办,在谷歌上搜索.dll文件的信息却一无所获。

target_link_libraries(GLEW_Test libglew32.a libglu32.a libopengl32.a)

永远不要在target_link_libraries中包含库的"lib"前缀和文件扩展名。相反,你应该像这样做

target_link_libraries(GLEW_Test glew32 glu32 opengl32)

由于cmake已经在搜索例如glew32.dll,那么libglew32.a本身。这样,您还可以保持平台/编译器的独立性。

出于测试/错误查找的目的,我建议您首先将所需的库放在可执行文件的目录中,并检查错误是否仍然发生,因为windows链接器首先在可执行程序的目录中搜索库。

如果它不再发生,但当库位于其他位置时发生,请确保这些位置是PATH环境变量的一部分。

好吧,在谷歌上搜索了一下并试图了解什么是.dll.a文件之后,我已经弄明白了!

这就是我使用CMake:动态链接glew的方法

  1. 我从C:MinGWlib目录中删除了glew32.a,并将其替换为glew32.dll.a
  2. 我将glew32.dll放入构建文件夹中。但是,您也可以将它放在SysWOW64文件夹中,它应该可以工作

仅此而已!我的CMakeLists.txt仍然是原来的。