【问题标题】:Dynamically Linking GLEW with CMake动态链接 GLEW 和 CMake
【发布时间】:2017-11-16 03:41:12
【问题描述】:

我查看了 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)

这是我的 main.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: %s\n", glewGetErrorString(err));
    }
    fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

    return 0;
}

现在,如果我在#include &lt;GL/glew.h&gt; 之前#define GLEW_STATIC,程序编译并输出预期的输出(没有 GLContext 的错误)。但是,据我所知,这是静态链接,我想动态链接 GLEW。这是我在没有#define GLEW_STATIC 的情况下编译时看到的:

"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" --build E:\CLion\GLEW-Test\cmake-build-debug --target GLEW_Test -- -j 2
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -HE:\CLion\GLEW-Test -BE:\CLion\GLEW-Test\cmake-build-debug --check-build-system CMakeFiles\Makefile.cmake 0
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\Makefile2 GLEW_Test
mingw32-make.exe[1]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -HE:\CLion\GLEW-Test -BE:\CLion\GLEW-Test\cmake-build-debug --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -E cmake_progress_start E:\CLion\GLEW-Test\cmake-build-debug\CMakeFiles 2
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\Makefile2 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 CMakeFiles\GLEW_Test.dir\build.make CMakeFiles/GLEW_Test.dir/depend
mingw32-make.exe[3]: Entering directory 'E:/CLion/GLEW-Test/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" E:\CLion\GLEW-Test E:\CLion\GLEW-Test E:\CLion\GLEW-Test\cmake-build-debug E:\CLion\GLEW-Test\cmake-build-debug E:\CLion\GLEW-Test\cmake-build-debug\CMakeFiles\GLEW_Test.dir\DependInfo.cmake --color=
mingw32-make.exe[3]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\GLEW_Test.dir\build.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 Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -E cmake_link_script CMakeFiles\GLEW_Test.dir\link.txt --verbose=1
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" -E remove -f CMakeFiles\GLEW_Test.dir/objects.a
C:\MinGW\bin\ar.exe cr CMakeFiles\GLEW_Test.dir/objects.a @CMakeFiles\GLEW_Test.dir\objects1.rsp
C:\MinGW\bin\g++.exe  -Wall -Wextra -g   -Wl,--whole-archive CMakeFiles\GLEW_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 @CMakeFiles\GLEW_Test.dir\linklibs.rsp
CMakeFiles\GLEW_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
CMakeFiles\GLEW_Test.dir\build.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
CMakeFiles\Makefile2:69: recipe for target 'CMakeFiles/GLEW_Test.dir/all' failed
mingw32-make.exe[2]: Leaving directory 'E:/CLion/GLEW-Test/cmake-build-debug'
CMakeFiles\Makefile2: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's sourceforge 的指南进行操作,并将 .dll 放在我的 System32 文件夹中。因为我使用 CMake 和 MinGW 构建,所以我有 .a 文件而不是 .lib 文件,并且我将它们保存在我的 MinGW/lib 目录中。 我唯一没有做的事情(因为我不确定),就是对我的 libglew32.dll.a 什么都不做 这是罪魁祸首吗?我不确定如何处理它,谷歌搜索有关 .dll.a 文件的信息一无所获。

【问题讨论】:

  • 通常,您会增加make 的详细程度以查看实际的编译器调用,然后手动运行它们以找到正确的选项。 make VERBOSE=1 用于此目的。您可以尝试对mingw32-make.exe 进行相同操作,可能是这样的:cmake.exe --build E:\CLion\GLEW-Test\cmake-build-debug --target GLEW_Test -- -j 2 VERBOSE=1,因为cmake.exe --build 基本上是make 调用。关于库:我认为任何配置都应该是target_link_libraries(GLEW_Test libglew32 libglu32 libopengl32)(静态或动态链接在其他地方决定)。
  • 我已经更新了详细输出。我看不出有什么不同。链接后似乎仍然无法解决某些 glew 功能。

标签: c++ windows opengl cmake clion


【解决方案1】:
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 链接器 searches the executable's directory first

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

【讨论】:

  • 这是有道理的。我对在它们上面加上“lib”前缀持谨慎态度。因此,我在构建目录中添加了以下内容:glew32.dlllibglu32.alibopengl32.a。但是,我仍然得到相同的总体错误:未定义的 glew 函数引用 (undefined reference to _imp__glewInit@0'`)。那么,无论出于何种原因,它都在正确查找和链接程序,但无法解析这些功能?
  • 在我的 glew 构建输出目录中有一个 libglew32.dll.a,知道它是干什么用的吗?我在 glew 网站上没有看到任何记录
  • 您是否尝试更改链接库的顺序?特别是对于静态库,我认为顺序很重要。
  • 我没做过,我回家试试看。
【解决方案2】:

好的,所以在谷歌搜索了一下并试图了解 .dll.a 文件是什么之后,我已经弄清楚了!

这是我使用 CMake 动态链接 glew 所做的:

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

仅此而已!我的 CMakeLists.txt 还是一样的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    相关资源
    最近更新 更多