在本系列中我们使用 Windows Terminal + Powershell 组合作为我们在 Windows 系统下的终端工具,Windows 11 自带该环境。你也可以使用任意自己喜欢的终端环境代替,或使用鼠标执行等价的操作。

源码准备

我们使用 git 管理我们的项目,所以首先我们创建一个名为 "hello_sdl3" 的目录并且使用 git 进行初始化,这组命令实际上是各平台通用的:

mkdir hello_sdl3
cd ./hello_sdl3
git init

使用 git submodule 机制引入 SDL3 的源代码,源码地址: https://github.com/libsdl-org/SDL.git

git submodule add https://github.com/libsdl-org/SDL.git ./third_party/SDL3

如果不使用 git 可以手工下载源码到对应的目录,不影响后续使用。

接下来在项目文件夹根目录下创建源码文件和 CMakeLists.txt 文件:

hello_window.cpp

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h> int main(int argc, char* argv[])
{
SDL_Log("Hello, SDL3!");
return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(hello_sdl3)
set(CMAKE_CXX_STANDARD 20) add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/third_party/SDL3" EXCLUDE_FROM_ALL)
link_libraries(SDL3::SDL3) add_executable(hello_window hello_window.cpp)

编译运行

创建并切换当前目录到 build 文件夹

mkdir build
cd ./build

执行 cmake 命令初始化项目配置,cmake 会自动扫描系统安装的开发环境,在 Windows 系统下一般是 VisualStudio(简称 VS)开发环境:

cmake ..

一切顺利的话已经可以看到 build 文件夹下生成的 VisualStudio 工程文件,接下来可以使用 VS 打开 sln 文件执行编译调试等工作,也可以继续使用 cmake 命令编译。

cmake 命令编译项目:

cmake --build .

如果编译成功可以在 build/Debug 文件夹下看到 hello_window.exe 可执行文件,如果使用 clang 编译则直接在 build 文件夹下。命令行执行:

呃,没输出任何字符,有点不合预期

这里是因为我们以动态链接库(DLL)的方式使用 SDL3,而 SDL3.dll 并没有生成到 build/Debug 文件夹下,hello_window.exe 可执行程序找不到需要的 DLL 所以无法启动。

解决方法是使用 CMake 的 add_custom_command 方法自定义文件拷贝指令,在 CMakeLists.txt 中增加如下内容:

add_custom_command(TARGET hello_window POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:SDL3::SDL3>
$<TARGET_FILE_DIR:hello_window>
)

重新编译执行,输出如下:

搞定!

至此,说明我们已经解决基本的工程设置、动态库依赖等一系列问题,接下来可以继续编写更复杂的程序了。

注意事项

注意观察 hello_window.cpp 文件的源码,如果 IDE 比较智能的话可以看到 "main" 这个单词不是正常的表示函数名的颜色,比如在我这里它显示的是蓝色,这表示 "main" 是一个宏。

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h> int main(int argc, char* argv[])
...

玄机在 SDL_main.h 中:

#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) || defined(SDL_MAIN_USE_CALLBACKS)
#define main SDL_main
#endif

"main" 被宏定义修改成了 "SDL_main",因此 main 函数的声明必须写成带参数的完整形式,不能使用如下的无参写法:

int main()
{
...
}

否则会在链接时报 "无法解析的外部符号" 错误,因为无法解析的符号是 "SDL_main" 所以如果不熟悉 SDL 的话即使是有经验的 C++ 程序员(比如我)也颇为挠头(万恶的宏)。去掉 #include <SDL3/SDL_main.h> 这一行或者使用完整的 main 函数声明都可以解决问题。

不过 SDL_main.h 头文件还有其他用处,在 Windows 下如果希望将程序编译成窗口程序(启动后不带控制台)则必须包含这个头文件,同时在 CMakeLists.txt 中增加如下内容:

set_property(TARGET hello_window PROPERTY WIN32_EXECUTABLE TRUE)

不过这样在调试过程就看不到日志了,需要做一些额外的处理接管日志输出,所以在调试阶段建议继续使用控制台类型编译可执行程序。

SDL3 入门(1):Hello, SDL3!的更多相关文章

  1. C语言的本质(15)——C语言的函数接口入门

    C语言的本质(15)--C语言的函数接口 函数的调用者和其实现者之间存在一个协议,在调用函数之前,调用者要为实现者提供某些条件,在函数返回时,实现者完成调用者需要的功能. 函数接口通过函数名,参数和返 ...

  2. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  3. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  4. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  5. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  6. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  7. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  8. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  9. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  10. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

随机推荐

  1. 作业帮在线业务 Kubernetes Serverless 虚拟节点大规模应用实践

    ​简介:目前方案已经成熟,高峰期已有近万核规模的核心链路在线业务运行在基于阿里云 ACK+ECI 的 Kubernetes Serverless 虚拟节点.随着业务的放量,未来运行在 Serverle ...

  2. Arthas 初探--安装初步适用

    简介: 由于在项目中遇到一种情况,某段代码在进行单元测试和在 tomcat 容器中运行的性能相差数百倍,因此需要分析在不同环境下某个方法执行的具体时间,从而确定问题.Arthas 可以做到无侵入的监控 ...

  3. 基于 Mesh 的统一路由在海外业务的实践

    ​简介:本文主要介绍我们最近在利用 Service Mesh 架构解决海外业务问题中一些实践和价值探索.我们在海外业务引入 Mesh 架构过程中,充分利用 Istio 的基于 yaml 来描述和定义路 ...

  4. Fluid 0.5 版本发布:开启数据集缓存在线弹性扩缩容之路

    简介: 为了解决大数据.AI 等数据密集型应用在云原生场景下,面临的异构数据源访问复杂.存算分离 I/O 速度慢.场景感知弱调度低效等痛点问题,南京大学PASALab.阿里巴巴.Alluxio 在 2 ...

  5. 为什么Spring仍然会是云原生时代最佳平台之一?

    简介: 基于Java语言的Spring生态,还能否适应新的开发方式,比如Cloud Native.Serverless.Faas等,它还会是云原生时代的最佳平台的选择吗?本文将从5个角度来为你分析一下 ...

  6. WPF 使用 Skia 解析绘制 SVG 图片

    本文告诉大家如何在 WPF 里面,使用 Skia 解析绘制 SVG 图片.本文也适合控制台使用 SkiaSharp 解析绘制 SVG 图片,本文的 WPF 部分只是在 Skia 绘制完成之后,将 Sk ...

  7. K8s集群中部署SpringCloud在线购物平台(三)

    五.SpringCloud概述 springcloud架构图 5.1 SpringCloud是什么? 官网: https://spring.io/projects/spring-cloud Sprin ...

  8. Ubuntu开启root账户登陆

    Ubuntu开启root账户登陆 设置 root 密码:sudo passwd root sudo chmod 777 /usr/share/lightdm/lightdm.conf.d/50-xx ...

  9. ubuntu系统下安装php7.4

    目录 一.下载/更新php源 二.安装php7.4 三.修改配置 3.1 修改www.conf 文件 四.配置域名 五.nginx的配置文件 5.1 sock方式和nginx配合工作 5.2监听900 ...

  10. cuBlas API Launch Latency 耗时异常分析记录

    一.背景 最近在做 AI 编译器生成 Kernel 支持 Bert 模型训练调优工作,在分析 bert 的timeline中发现,在每个 step 的前两个 cinn_instruction_run ...