【问题标题】:"undefined reference to `FT_Load_Glyph'" and other SDL2_ttf functions using CMAKE“未定义对‘FT_Load_Glyph’的引用”和其他使用 CMAKE 的 SDL2_ttf 函数
【发布时间】:2015-12-11 15:20:15
【问题描述】:

在 Windows 10 上的 Clion 中使用此 CMAKE 文件(使用 MinGW 5.0):

cmake_minimum_required(VERSION 3.3)
project(ClionProjects)

# configure the SDL (cf. "SDL2-2.0.3\i686-w64-mingw32\lib\pkgconfig\sdl2.pc")
# C++ flags
set(SDL2_Flags "-mwindows -Wl,--no-undefined -static-libgcc")
# library paths
set(SDL2_ROOT     "C:/SDL2/i686-w64-mingw32")
set(SDL2_Includes "${SDL2_ROOT}/include")
set(SDL2_LibDir   "${SDL2_ROOT}/lib")
# imported targets for CMake (cf. https://cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets)
add_library(SDL2     STATIC IMPORTED)
add_library(SDL2main STATIC IMPORTED)
add_library(SDL2_image STATIC IMPORTED)
add_library(SDL2_ttf STATIC IMPORTED)
set_property(TARGET SDL2     PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2.a")
set_property(TARGET SDL2main PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2main.a")
set_property(TARGET SDL2_image PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2_image.a")
set_property(TARGET SDL2_ttf PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2_ttf.a")
# the libs to link against
# note: as always with gcc, the order is important...
set(SDL2_Libs mingw32 SDL2 SDL2main m SDL2_image SDL2_ttf dinput8 dxguid dxerr8 user32 gdi32 winmm imm32 ole32 oleaut32 shell32 version uuid)

# configure the project
# include the SDL flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${SDL2_Flags}")
# collect the sources
set(SOURCE_FILES
        Kod/Graphics/Graphics.cc
        Kod/Graphics/Graphics.h
        Kod/Game/Game.cc
        Kod/Game/Game.h
        Kod/Gameboard/Gameboard.cc
        Kod/Gameboard/Gameboard.h
        Kod/Meeple/Meeple.cc
        Kod/Meeple/Meeple.h
        Kod/Player/Player.cc
        Kod/Player/Player.h
        Kod/Resource/Resource.cc
        Kod/Resource/Resource.h
        Kod/Tile/Tile.cc
        Kod/Tile/Tile.h
        Kod/Carcassonne.cc)
# define the target
add_executable(ClionProjects ${SOURCE_FILES} Kod/Carcassonne.cc)
# include the SDL headers
target_include_directories(ClionProjects SYSTEM PRIVATE ${SDL2_Includes})
# link against the SDL (and its dependencies)
target_link_libraries(ClionProjects ${SDL2_Libs})


#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lSDL2 -lSDL2-image")


#add_executable(ClionProjects ${SOURCE_FILES} Kod/Carcassonne.cc)
#target_link_libraries(ClionProjects SDL2main SDL2 SDL2_image)

我收到此错误:

C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `Load_Glyph':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:609: undefined reference to `FT_Load_Glyph'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:671: undefined reference to `FT_Outline_Transform'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:677: undefined reference to `FT_Get_Glyph'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:678: undefined reference to `FT_Stroker_New'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:694: undefined reference to `FT_Render_Glyph'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:895: undefined reference to `FT_Done_Glyph'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:607: undefined reference to `FT_Get_Char_Index'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:682: undefined reference to `FT_Stroker_Set'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:683: undefined reference to `FT_Glyph_Stroke'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:684: undefined reference to `FT_Stroker_Done'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:686: undefined reference to `FT_Glyph_To_Bitmap'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:688: undefined reference to `FT_Done_Glyph'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_Init':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:340: undefined reference to `FT_Init_FreeType'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_CloseFont':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:927: undefined reference to `FT_Done_Face'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_OpenFontIndexRW':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:432: undefined reference to `FT_Open_Face'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:460: undefined reference to `FT_Set_Char_Size'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:454: undefined reference to `FT_Set_Charmap'
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:484: undefined reference to `FT_Set_Pixel_Sizes'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_SizeUTF8':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:1241: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_RenderUTF8_Solid':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:1429: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_RenderUTF8_Shaded':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:1610: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_RenderUTF8_Blended':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:1780: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_RenderUTF8_Blended_Wrapped':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:2048: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_Quit':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:2196: undefined reference to `FT_Done_FreeType'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_GetFontKerningSize':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:2209: undefined reference to `FT_Get_Kerning'
C:/SDL2/i686-w64-mingw32/lib/libSDL2_ttf.a(SDL_ttf.o): In function `TTF_GlyphIsProvided':
/Users/slouken/release/SDL_ttf/SDL2_ttf-2.0.12-source/foo-x86/../SDL_ttf.c:1138: undefined reference to `FT_Get_Char_Index'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\ClionProjects.dir\build.make:289: recipe for target 'ClionProjects.exe' failed
mingw32-make.exe[3]: *** [ClionProjects.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/ClionProjects.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/ClionProjects.dir/all' failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/ClionProjects.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/ClionProjects.dir/rule] Error 2
mingw32-make.exe: *** [ClionProjects] Error 2
makefile:117: recipe for target 'ClionProjects' failed

我已将 SDL2_ttf.dll 添加到 system32 和可执行文件所在的文件夹,将 SDL2_ttf.h 添加到 /include,其中 SDL2 的所有其他 .h 文件都在其中,还将 libSDL2_ttf.a 添加到 /lib。我不明白为什么会出现这些错误...我的标志顺序有问题吗?

【问题讨论】:

  • 谷歌搜索未定义符号的名称显示,它们是在TrueType 库中定义的。在您的链接列表中,我没有看到任何看起来像这个库的东西。顺便说一句,与SDL2 等3d 方库链接的常用方法是使用find_package(STDL2)。网上有很多关于在简单项目中使用这个命令的教程。
  • 我尝试让 find_package(SDL2) 工作,但无济于事。然后我在stackoverflow.com/questions/32857351/linking-sdl2-and-clion 中找到了标记为正确的答案,这本质上是一个复制粘贴。我的项目合作伙伴在 *nix 环境中编译它,并且只使用 -lsdl -lsdl_image -lsdl_ttf 标志,没有 TrueType 库 =S。
  • *nix 环境与 MinGW 不同。 (甚至不同 Linux 发行版上的环境也可能不同)。这就是硬编码库名称不适合可移植项目的原因。
  • 但是 SDL_tff 不是 TrueType 库吗? cmakefile 是我一个人的,所以没有什么是硬编码的。
  • 我现在已经下载并安装了 FreeType,但我不确定要包含什么库才能访问它。唯一的 .a 文件是 libfreetype.dll.a,是那个吗?

标签: c++ windows cmake mingw sdl-2


【解决方案1】:

以下是我如何使用 CLion 处理 SDL2、SDL2_ttf、SDL2_mixer 等。这与您迄今为止所做的完全不同,因此请记住这一点。我将在类似 POSIX 的环境中使用 MSYS2(而不是您正在使用的 MINGW/MSys)。

首先,我将从安装 MSYS2 开始。从http://msys2.github.io/ 获取它。然后,根据您安装的版本,您将在开始菜单中获得 2 或 3 个快捷方式。

从现在开始,我会坚持使用MINGW-W64-x86_64 版本的工具链。如果您使用的是i686,请将x86_64 替换为i686(并将mingw64 替换为mingw32)。

从开始菜单打开MinGW-w64 Win64 shell 快捷方式。欢迎您使用 bash shell。在这一点上,我首先要安装工具链。在提示符下,输入以下命令

pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-pkg-config mingw-w64-x86_64-make mingw-w64-x86_64-gdb

包管理器随后会为您安装 gcc、cmake、pkg-config、make 和 gdb。这包括这些工具的所有依赖项,因此需要相当多的时间。

然后通过在提示符处调用以下命令来安装库。:

pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-SDL2_image

pacman(包管理器)将下载并安装这 3 个库及其依赖项。

上面的步骤在我的头上。我还没有重新测试它(因为我已经有了工作环境)。如果您遇到问题,请告诉我。我以后可能会重新测试它。上述步骤也适用于 Arch Linux 用户,只需替换包名即可。

接下来,打开 CLion。转到文件->设置。在构建、执行和部署下选择工具链。然后将MinGW home改为你的MSYS2安装路径下的mingw64。

那么一切都应该准备好了。

我将使用FindPkgConfig 模块来获取链接器标志并包含我使用的每个库的标志。这个模块依赖于我们之前安装的 pkg-config 命令。在CMakeList.txt 中,添加以下行:

INCLUDE(FindPkgConfig)

pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(SDL2_IMG REQUIRED SDL2_image)
pkg_check_modules(SDL2_TTF REQUIRED SDL2_ttf)
pkg_check_modules(SDL2_MIX REQUIRED SDL2_mixer)

include_directories(${SDL2_INCLUDE_DIRS}
    ${SDL2_IMG_INCLUDE_DIRS}
    ${SDL2_TTF_INCLUDE_DIRS}
    ${SDL2_MIX_INCLUDE_DIRS})

link_directories (${SDL2_LIBRARY_DIRS}
    ${SDL2_IMG_LIBRARY_DIRS}
    ${SDL2_TTF_LIBRARY_DIRS}
    ${SDL2_MIX_LIBRARY_DIRS})

target_link_libraries (TestSDL2
    ${SDL2_LIBRARIES}
    ${SDL2_IMG_LIBRARIES}
    ${SDL2_TTF_LIBRARIES}
    ${SDL2_MIX_LIBRARIES})

将 TestSDL2 更改为您的可执行文件。您可能必须删除现有的 FindSDL 或任何查找 SDL 库的命令。

这种方法比自定义模块更简洁。缺点是它与系统的库文件非常相关(特别是如果您使用的是 Linux)。另外如果要打包exe文件的话,就得手动在MSYS2/mingw64/bin里面找dll文件了(顺便说一下也不是很难)。

另一种可能的方法是将 SDL 作为子项目包含在内。我以前没有这样做过,所以我无法解释。

我认为在您熟悉了它的工作原理之后,您也可以将相同的方法应用于其他库(例如 box2d)。你可以在https://github.com/Alexpux/MINGW-packages 看到可用包的列表,包名必须通过在库名之前插入arch 名称来稍微修改(例如mingw-w64-x86_64-box2d 用于mingw-w64-box2d 包)。

【讨论】:

  • 非常感谢您的教程!安装进行得非常顺利,但我现在收到“未定义对‘SDL_main’的引用”错误。我知道有很多问题要问,但是您认为您可以为 makefile 提供更多帮助吗?我需要的外部库是 SDL2、SDL2_image、SDL2_ttf 和 freetype。我尝试使用 pkg_check_modules(FREETYPE REQUIRED freetype2) 但进一步产生了奇怪的错误:“解析字符串时 C:/Users/~/ClionProjects/CMakeLists.txt:15 处的 cmake 代码语法错误 ${freetype”
  • “未定义对SDL_main的引用通常是由于缺少int main(char**, int)造成的。如果您使用main的不同签名,请尝试重新调整签名。
  • 如果你不直接使用FreeType,你就不用打电话给pkg_check_modules(FREETYPE REQUIRED freetype2)。我这样做是因为我不使用 SDL2_ttf(我自己进行文本渲染)。
  • 呃,我应该意识到这是错误的!它现在编译得很漂亮,但是当我尝试运行它(在 Linux 上完美运行)时,我得到了这个错误:进程完成,退出代码 -1073741515 (0xC0000135)" 没有程序甚至打开一个窗口。即使在第一行设置断点main(int argc, char* argv) 和调试它刚刚退出,有什么想法吗?谷歌搜索了一下,这似乎是一个“访问冲突”错误,但我什至不知道如何开始修复它。=(跨度>
  • 它在 Linux 上完美运行的原因是,在 Linux 中 main 是您程序的实际主要功能。控制台的主要功能可以是任何定义的AFAIK。另一方面,在 Windows 中,main 被重命名为 SDL_main 并将由 WinMain() 调用,因此如果签名不匹配,则编译将无法识别您的 main 函数。
猜你喜欢
  • 2012-10-07
  • 2012-10-14
  • 1970-01-01
  • 2013-05-04
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 2011-07-12
相关资源
最近更新 更多