SDL3 入门(1):Hello, SDL3!
在本系列中我们使用 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!的更多相关文章
- C语言的本质(15)——C语言的函数接口入门
C语言的本质(15)--C语言的函数接口 函数的调用者和其实现者之间存在一个协议,在调用函数之前,调用者要为实现者提供某些条件,在函数返回时,实现者完成调用者需要的功能. 函数接口通过函数名,参数和返 ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- Oracle分析函数入门
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
随机推荐
- MySQL 深潜 - MDL 锁的实现与获取机制
简介:本文将介绍在 MDL 系统中常用的数据结构及含义,然后从实现角度讨论 MDL 的获取机制与死锁检测,最后分享在实践中如何监控 MDL 状态. 作者 | 泊歌 来源 | 阿里技术公众号 一 背 ...
- WPF 已知问题 资源字典树引用与资源寻找的坑
大家都知道,在 WPF 里面,可以让资源字典合并其他资源字典,从而定义出资源字典引用树.然而在资源字典引用树里面,如果没有理清关系,将可以作出一个超级复杂的引用关系网.如果在性能优化中,将网断开部分, ...
- 使用sqlcmd命令行执行.sql文件
用微软自带的sqlcmd命令行工具,可以执行导入.以SQL Server 2016版本为例: 第一步:Win+R 键入:cmd 命令,开启命令行工具: 第二步:键入:sqlcmd -S . -U sa ...
- 3.Exporter概述
一.Exporter概述 所有可以向Prometheus提供监控样本数据的程序都可以被称为一个Exporter.而Exporter的一个实例称为target,如下所示,Prometheus通过轮询的方 ...
- 使用Binlog日志恢复误删的MySQL数据实战
前言 "删库跑路"是程序员经常谈起的话题,今天,我就要教大家如何删!库!跑!路! 开个玩笑,今天文章的主题是如何使用Mysql内置的Binlog日志对误删的数据进行恢复,读完本文, ...
- 二:大数据架构回顾-Kappa架构
Kappa 架构是由 LinkedIn 的前首席工程师杰伊·克雷普斯(Jay Kreps)提出的一种架构思想.克雷普斯是几个著名开源项目(包括 Apache Kafka 和 Apache Samza ...
- kali 设置 Java 版本,并更换为 1.8 版本
kali 设置 Java 版本,并更换为 1.8 版本 1.安装 JDK 1.下载java 1.8 :https://repo.huaweicloud.com/java/jdk/8u202-b08/j ...
- su与sudo用法详解
su与sudo用法详解 目录 su与sudo用法详解 1. su和sudo详解:切换用户身份 1.1 shell登录类型和环境配置文件 1.2 su进行身份切换 1.3 sudo命令详解 1.3.1 ...
- Js中valueOf和toString区别和使用
对于number.string.Boolean.object.symbol数据类型调用valueOf方法,得到的都是数据本身(null.undefined两种类型上的原型链上没有valueOf方法) ...
- js原生小知识
new Array(3).fill(0) 就会生成3个元素为0的数组