天天看点

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

参考文章: https://my.oschina.net/u/5732601/blog/5516455
大体上参考了此文章, 但其原文的中有几处bug或说明不到的地方, 我在后文中会指出。

0. 序言

为何会有此文?

最近一段在开发一个基于LVGL GUI的小设备, 开发过程中就觉得, 每次图形界面有些稍稍的改动, 都必须把程序烧到设备中才能看到效果, 实在是麻烦. 就想着还是必要在PC上搭建一个LVGL的模拟器.

LVGL的官网里列出了以下几种搭建模拟器的方案:

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

CodeBlocks没用过不想再去安装个新软件, VisualStudio也是要新装而且太笨重, FastModel不知道是什么?

VSCode已经是我目前的主力编辑器, 所以就选了VSCode with SDL driver的方案, 虽然官网推荐其用在Linux or Mac环境下,

但我已搜索就找到参考文章, 觉得应该也能在Win下搞定.

这个本质上的工作就是在Win下的VSCode里搭建SDL的开发环境, 好的接下来开始.

1. 安装MSYS2

先下载MSYS2, 到其官网下载即可, 不过它的下载链接是github的, 众所周知的原因, 下载会比较慢, 最新的安装程序83.5MB, 直接下载基本不可行. 我是到清华大学的镜像站下载的, 下载链接: https://mirrors.tuna.tsinghua.edu.cn/msys2/distrib/x86_64/msys2-x86_64-20230318.exe

安装MSYS2还是比较简单, 根据其官网的说明, 一步步默认安装即可.

关于其安装目录, 官网有如下提醒:

short ASCII-only path on a NTFS volume, no accents, no spaces, no symlinks, no subst or network drives, no FAT           

所以就不要使用中文路径了.

而且最好把安装路径改到非系统盘比如D盘, 因为随着在MSYS2内不断安装各种软件, 其占用空间会越来越大.

2. 在MSYS2中安装GCC和CMake

2.1 修改镜像源

pacman是MSYS2的软件包管理工具, 还是因为众所周知的原因, 直接使用官方默认的软件包安装源的话, 安装速度会让你感动. 所以我们需要 和在Linux发行版中所作的一样, 装软件之前先改成国内的镜像源.

不过这个修改安装源要稍稍方便一点, 因为MSYS2的默认安装里的 源配置文件 中已经列出来了 国内 清华tsinghua 和 中科大ustc 的镜像源地址, 我们所做的不过是把这2个源给剪切到最前面 即可.

共有7个源配置文件, 位于类似D:\msys64\etc\pacman.d\目录下, 视你的MSYS2安装目录而定.

如果你只用mingw64工具链, 可以只修改mirrorlist.mingw64这一个配置文件; 也可以7个全修改.

我修改了 mirrorlist.mingw32, mirrorlist.mingw64, mirrorlist.msys, mirrorlist.ucrt64 这4个配置文件.

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境
基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境
BTW: 在参考文章并没有提到 这一步, 这算是它的一个小坑吧或者不完善之处.

2.2 更新panman基本软件仓库

还是和通常Linux发行版下所做的一样, 修改完镜像源, 应更新一下软件仓库, 使用如下命令:

pacman -Syu           

检查更新过程中,MSYS2可能会因为安装更新而自动关闭,可再次在开始菜单中打开MSYS2,然后再次执行pacman -Syu命令即可.

确定更新完毕, 还可用pacman -Su命令确认一下, 如下图:

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

2.3 安装GCC和CMake

因为我们要用MINGW64工具链, 所以从开始菜单打开MSYS2 MINGW64命令行, 输入下面命令:

pacman -S --needed base-devel mingw-w64-x86_64-toolchain           

安装C/C++编译工具链.

安装过程中, 可如下图选择:

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

安装完后, 可用gcc --version命令试一下.

GCC好了后, 再来安装CMake, 命令如下:

pacman -S --needed base-devel mingw-w64-x86_64-cmake           

都安装好后, 将类似D:\msys64\mingw64\bin路径(视MSYS2安装目录而定), 添加到系统环境变量PATH里.

BTW: 参考文章中只安装了cmake, 没有安装gcc. 相当于只安装了make, 但程序没法编译链接, 有点坑.

3. VSCode配置

在作VSCode配置的配置工作之前, 有2个前提条件.

第1个前提, 需要VSCode已安装下面4个插件:

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

第2个前提, 需用VSCode随便打开一个目录.

下面的配置操作,都是以VSCode已打开一个目录为前提, 不然很多配置选项出不来.

(当然这2点前提参考文章也未提及).

3.1 配置C/C++工具链

VSCode配置C/C++工具链, Shift+Ctl+P调出搜索框,输入 C/C++ 后从下拉框中选择C/C++: Edit Configurations (UI)

在编译器路径中输入:D:/msys64/mingw64/bin/gcc.exe (同样取决于你的MSYS2安装目录而定)

3.2 配置CMake tools

VSCode配置CMake tools, Shift+Ctl+P调出配置搜索框,输入 cmake:scan 会自动显示出CMake:Scan for kits,点击它,

VSCode会自动扫描机子上的已安装的工具链,并在C:\Users\admin\AppData\Local\CMakeTools\目录下生产文件cmake-tools-kits.json, 并填充内容如下:

[
  {
    "name": "GCC 12.2.0 x86_64-w64-mingw32",
    "compilers": {
      "C": "D:\\msys64\\mingw64\\bin\\gcc.exe",
      "CXX": "D:\\msys64\\mingw64\\bin\\g++.exe"
    }
  }
]           

OK, CMake tools配置完毕!

这里和 参考文章 中差别还是蛮大, 参考文章中的cmake-tools-kits.json文件内容如下:
[ { "name": "GCC 11.2.0 x86_64-w64-mingw32", "compilers": { "C": "D:\\msys64\\mingw64\\bin\\gcc.exe", "CXX": "D:\\msys64\\mingw64\\bin\\g++.exe" }, "preferredGenerator": { "name": "MinGW Makefiles", "plateform": "x64" }, "environmentVariables": { "CMT_MINGW_PATH": "D:\\msys64\\mingw64\\bin\\" } } ]
后面多了一大坨东东.
而且它还有这样的描述:
其中 “CMT_MINGW_PATH” 是我手动改的,自动生成的是 “PATH”,我从网上看到需要这么改,具体原理未知。
这说明它还手动修改了一些内容.
而我直接用VSCode自动生成的, 未作任何修改, 就完全OK了! 后续的操作也没收影响!

4. 下载安装SDL

SDL的官网可找到SDL Release下载链接, 其下载页面也是在github, 选择SDL2-devel-2.26.4-mingw.zip下载, 文件不算大, 15MB, 我直接用github的链接也成功下下来了.

下载后, 解压, 进入 SDL2-2.26.4\x86_64-w64-mingw32 目录, 里面有4个目录:

  • bin
  • include
  • lib
  • share

将这4个目录下的内容, 分别依次复制到 MINGW64工具链目录 下的 对应同名目录 下. (我的工具链目录是D:\msys64\mingw64)

到此, VSCode里的SDL2的开发环境 都已经准备好!

5. 测试程序

接下来, 整个测试程序来试验一下吧.

先新建一个工程目录, 用VSCode打开此目录, shift+ctrl+p 打开搜索框, 输入CMake:Quick Start, 会自动创建一个工程,并生成CMakeLists.txt.

我对CMake没有去学过, 并不太了解, 我的理解 CMakeLists.txt 文件之于 CMake, 就像 Makefile 文件之于 Make.

还需要对这个自动生成的 CMakeLists.txt 文件, 做些修改, 在 add_executable(….) 行的后面加入如下3个库链接:

target_link_libraries(xxx mingw32)
target_link_libraries(xxx SDL2main)
target_link_libraries(xxx SDL2)           

其中 xxx 应改为 编译生成的目标可执行文件名.

参考文章中声称: "这3个库链接一定要按照以上顺序添加, 否则会报 WinMain 无法找到的错误".

我也懒得, 故意打乱顺序测试一下 它这说法 是否真切?

我的最终修改后的CMakeLists.txt 文件全文如下:

cmake_minimum_required(VERSION 3.0.0)
project(aaa VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(aaa main.cpp)

target_link_libraries(aaa mingw32)
target_link_libraries(aaa SDL2main)
target_link_libraries(aaa SDL2)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)           

其中main.cpp是程序源文件, aaa是最终编译生成的 可执行文件名.

源文件的代码 如下:

//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main( int argc, char* args[] )
{
    //The window we'll be rendering to
    SDL_Window* window = NULL;

    //The surface contained by the window
    SDL_Surface* screenSurface = NULL;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    }
    else
    {
        //Create window
        window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( window == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
        }
        else
        {
            //Get window surface
            screenSurface = SDL_GetWindowSurface( window );

            //Fill the surface white
            SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) );

            //Update the surface
            SDL_UpdateWindowSurface( window );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Destroy window
    SDL_DestroyWindow( window );

    //Quit SDL subsystems
    SDL_Quit();

    return 0;
}           

这个源文件copy自参考文章 (BTW:不过它把其中一个else写成了elsea, 又被它小小的坑了一下).

按F7VSCode会自动编译, 编译成功之后, 在工程目录的build目录下生成aaa.exe可执行文件.

可直接双击运行, 运行的效果是 "出现一个如下图的空白窗口, 2秒钟后自动关闭".

基于MSYS2的MINGW64 GCC和CMake在Win下VSCode里搭建SDL2开发环境

OK, SDL2开发环境顺利验证完成!

继续阅读