Windows系统下使用cmake/gcc配置Qt SDL2 FFmpeg的一些坑
1. 了解不同版本的gcc的含义
window
下常见的gcc编译器可以分为下面三种mingw32-gcc
:32位操作系统下编译32位应用程序.i686-w64-mingw32-gcc
:64位操作系统下编译32位应用程序.x86_64-w64-mingw32
:64位操作系统下编译64位应用程序
2. Qt支持的gcc编译器
- 拿较早版本的
Qt5.11
为例,可以在安装目录下的Tools文件下查看它支持哪些gcc
编译器,如果没记错的话,Qt5.11
支持mingw32-gcc
以及i686-w64-mingw32-gcc
两种编译模式,不支持x86_64-w64-mingw32
,这也意味着Qt5.11
会为其准备两套不同的库,可以在安装目录的5.11.x文件下下看到两套不同的库,分别是为mingw32-gcc
以及i686-w64-mingw32-gcc
准备的,因此你可以使用其中一者对你的Qt程序进行编译,生成的应用程序都是32位的
3. SDL2支持的gcc编译器
- 同上,我们可以进入
SDL2
的安装目录查看其支持的gcc编译器如下图:
- 可以发现
SDL2-2.24
分别支持i686-w64-mingw32-gcc
以及x86_64-w64-mingw32
,不支持mingw32-gcc
- 这意味着如果你要同时使用
Qt5.11
以及SDL2-2.24
时,你的gcc编译器只能是i686-w64-mingw32-gcc
,否则肯定会出现gcc无法链接到某个库cannot find -l
的报错
4. FFmpeg支持的gcc编译器
- 以我下载的
FFmpeg4.3
为例,安装目录下并没有指明支持的gcc编译器,测试发现其只支持x86_64-w64-mingw32
gcc编译器,尝试使用其它编译器编译都会出现cannot find -l avcodec ...
的报错 - 那这不是完犊子了,没有一个gcc编译器可以同时支持
Qt5.11
,SDL2-2.24
,FFmpeg4.3
5.解决办法
- 安装高版本支持
x86_64-w64-mingw32
gcc编译器的Qt如Qt5.15
(同时支持i686-w64-mingw32-gcc
,x86_64-w64-mingw32
) - 这样就可以在编译时指定gcc编译器为
x86_64-w64-mingw32
类型同时对三个库进行编译
6.最后的建议
- 在安装
Qt5.15
时可以指定是否需要安装Tools(i686-w64-mingw32-gcc, x86_64-w64-mingw32)
建议勾选安装(哪怕你电脑本身自带了x86_64-w64-mingw32
类型的编译器) - 如果你电脑本身就有gcc
x86_64-w64-mingw32
环境你可以选择不安装,但是应该使用与Qt5.15
版本匹配的gcc编译器(Qt5.15
使用gcc8.1.0
),同时应该在环境变量中将x:\x\5.15.2\mingw81_64\bin
添加入环境变量中,只有两者有其中一者不符合要求在编译时就会出现__imp__ZN12QApplicationC1ERiPPci
等可怕的错误
cmake测试案例
- 环境
gcc8.1.0(x86_64-w64-mingw32)
,Qt5.15.2
,sdl2-2.24
,FFmpeg4.3
IDE:VSCODE
- 目录
CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(sdl_qt) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/workspace) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) # ffmpeg set(FFMPEG_DIR "D:/Embedded_Software/ffmpeg") include_directories(${FFMPEG_DIR}/include) link_directories(${FFMPEG_DIR}/lib) link_libraries(avcodec avformat avfilter avdevice swresample swscale avutil) # QT set(CMAKE_AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) link_libraries(Qt5::Core Qt5::Gui Qt5::Widgets) # SDL2 set(SDL2_DIR "D:/Embedded_Software/SDL2-2.24.0") find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2) find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2main) include_directories(${SDL2_INCLUDE_DIRS}) link_libraries(SDL2::SDL2) message(STATUS "${SDL2_INCLUDE_DIRS}") # if (TARGET SDL2::SDL2::main) # target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2::main) # endif() include_directories(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_autogen/include ${CMAKE_SOURCE_DIR}/src) file(GLOB_RECURSE cpp_srcs ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp *.hpp) add_executable(${PROJECT_NAME} main.cpp ${cpp_srcs})