SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用 C语言 写成。本文主要介绍 SDL 库的静态编译方法。SDL 当前是第二版,开源协议改为 Zlib 授权模式,官方文档上描述虽然 SDL 可以编译为静态库,但不会主动介绍静态库的编译方法,也不推荐将 SDL 编译为静态库使用,不过在很多场合下,静态编译去除依赖可以让程序看起来更便捷,所以这里简单的记录一下在 Windows 平台上静态编译的简易流程。

1. 下载源码

首先去 SDL 官网下载编译所需的源代码,当前最新的版本是 SDL2-2.0.10 。

SDL 官网

如果你不需要静态编译,推荐直接使用官方已经编译好的开发库,基本上解压即用。

2. 配置 CMake

这里编译 SDL 使用 CMake 的方式,所以在编译之前需要确保你的电脑已经安装最新版本的 CMake 和 Visual Studio,如果你不知道怎样安装,可以查看 CMake 安装教程Visual Studio 安装教程。 安装好 CMake 和 Visual Studio 之后,解压 SDL 压缩包,并确保找到压缩包里面的 CMakeLists.txt 文件,这个文件是 CMake 的配置文件,一会生成工程需要使用这个文件。

CMakeLists.txt 文件

打开 CMake 的使用界面:

cmake_gui

将前面提到的 CMakeLists.txt 拖到界面上,并在 Where to build the binaries 目录后面增加 _build 目录。这样可以确保生成的文件在 _build 目录中,而不会污染原有的 SDL 目录。

_build 目录

点击左下角的 Configure 按钮:

点击 configure 按钮

中间可能弹出是否确认创建 _build 目录的提示,这里直接点击确认即可。接着会弹出配置生成工程的相关属性,因为我机器上安装了 vs2019,并且电脑是 64 位系统,所以选择如下图所示,你可以根据自身系统的情况自行选择:

选择编译器

选择完毕后,点击 Finish,CMake 会自动生成相应的工程配置信息,下面是我电脑的生成配置日志:

Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.18363.
The C compiler identification is MSVC 19.24.28314.0
The CXX compiler identification is MSVC 19.24.28314.0
Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
Detecting C compiler ABI info
Detecting C compiler ABI info - done
Detecting C compile features
Detecting C compile features - done
Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
Detecting CXX compiler ABI info
Detecting CXX compiler ABI info - done
Detecting CXX compile features
Detecting CXX compile features - done
Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) 
Performing Test HAVE_WIN32_CC
Performing Test HAVE_WIN32_CC - Success
Performing Test HAVE_XINPUT_H
Performing Test HAVE_XINPUT_H - Success
Performing Test HAVE_XINPUT_GAMEPAD_EX
Performing Test HAVE_XINPUT_GAMEPAD_EX - Failed
Performing Test HAVE_XINPUT_STATE_EX
Performing Test HAVE_XINPUT_STATE_EX - Failed
Looking for d3d9.h
Looking for d3d9.h - found
Looking for d3d11_1.h
Looking for d3d11_1.h - found
Looking for ddraw.h
Looking for ddraw.h - found
Looking for dsound.h
Looking for dsound.h - found
Looking for dinput.h
Looking for dinput.h - found
Looking for dxgi.h
Looking for dxgi.h - found
Looking for mmdeviceapi.h
Looking for mmdeviceapi.h - found
Looking for audioclient.h
Looking for audioclient.h - found
Looking for endpointvolume.h
Looking for endpointvolume.h - found

SDL2 was configured with the following options:

Platform: Windows-10.0.18363
64-bit:   TRUE
Compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe

Subsystems:
  Atomic:	ON
  Audio:	ON
  Video:	ON
  Render:	ON
  Events:	ON
  Joystick:	ON
  Haptic:	ON
  Power:	ON
  Threads:	ON
  Timers:	ON
  File:	ON
  Loadso:	ON
  CPUinfo:	ON
  Filesystem:	ON
  Dlopen:	ON
  Sensor:	ON

Options:
  3DNOW                  (Wanted: ON): OFF
  ALSA                   (Wanted: OFF): OFF
  ALSA_SHARED            (Wanted: OFF): OFF
  ALTIVEC                (Wanted: ON): OFF
  ARTS                   (Wanted: OFF): OFF
  ARTS_SHARED            (Wanted: OFF): OFF
  ASSEMBLY               (Wanted: ON): OFF
  ASSERTIONS             (Wanted: auto): auto
  BACKGROUNDING_SIGNAL   (Wanted: OFF): OFF
  CLOCK_GETTIME          (Wanted: OFF): OFF
  DIRECTFB_SHARED        (Wanted: OFF): OFF
  DIRECTX                (Wanted: ON): ON
  DISKAUDIO              (Wanted: ON): ON
  DUMMYAUDIO             (Wanted: ON): ON
  ESD                    (Wanted: OFF): OFF
  ESD_SHARED             (Wanted: OFF): OFF
  FOREGROUNDING_SIGNAL   (Wanted: OFF): OFF
  FUSIONSOUND            (Wanted: OFF): OFF
  FUSIONSOUND_SHARED     (Wanted: OFF): OFF
  GCC_ATOMICS            (Wanted: OFF): OFF
  HIDAPI                 (Wanted: ON): ON
  INPUT_TSLIB            (Wanted: OFF): OFF
  JACK                   (Wanted: OFF): OFF
  JACK_SHARED            (Wanted: OFF): OFF
  KMSDRM_SHARED          (Wanted: OFF): OFF
  LIBC                   (Wanted: OFF): OFF
  LIBSAMPLERATE          (Wanted: OFF): OFF
  LIBSAMPLERATE_SHARED   (Wanted: OFF): OFF
  MMX                    (Wanted: ON): OFF
  NAS                    (Wanted: OFF): OFF
  NAS_SHARED             (Wanted: OFF): OFF
  OSS                    (Wanted: OFF): OFF
  PTHREADS               (Wanted: OFF): OFF
  PTHREADS_SEM           (Wanted: OFF): OFF
  PULSEAUDIO             (Wanted: OFF): OFF
  PULSEAUDIO_SHARED      (Wanted: OFF): OFF
  RENDER_D3D             (Wanted: ON): ON
  RPATH                  (Wanted: OFF): OFF
  SDL_DLOPEN             (Wanted: ON): OFF
  SDL_STATIC_PIC         (Wanted: OFF): OFF
  SDL_TEST               (Wanted: OFF): OFF
  SNDIO                  (Wanted: OFF): OFF
  SSE                    (Wanted: ON): ON
  SSE2                   (Wanted: ON): ON
  SSE3                   (Wanted: ON): ON
  SSEMATH                (Wanted: ON): OFF
  VIDEO_COCOA            (Wanted: OFF): OFF
  VIDEO_DIRECTFB         (Wanted: OFF): OFF
  VIDEO_DUMMY            (Wanted: ON): ON
  VIDEO_KMSDRM           (Wanted: OFF): OFF
  VIDEO_OPENGL           (Wanted: ON): ON
  VIDEO_OPENGLES         (Wanted: ON): ON
  VIDEO_RPI              (Wanted: OFF): OFF
  VIDEO_VIVANTE          (Wanted: OFF): OFF
  VIDEO_VULKAN           (Wanted: ON): ON
  VIDEO_WAYLAND          (Wanted: OFF): OFF
  VIDEO_WAYLAND_QT_TOUCH (Wanted: OFF): OFF
  VIDEO_X11              (Wanted: OFF): OFF
  VIDEO_X11_XCURSOR      (Wanted: OFF): OFF
  VIDEO_X11_XINERAMA     (Wanted: OFF): OFF
  VIDEO_X11_XINPUT       (Wanted: OFF): OFF
  VIDEO_X11_XRANDR       (Wanted: OFF): OFF
  VIDEO_X11_XSCRNSAVER   (Wanted: OFF): OFF
  VIDEO_X11_XSHAPE       (Wanted: OFF): OFF
  VIDEO_X11_XVM          (Wanted: OFF): OFF
  WASAPI                 (Wanted: ON): OFF
  WAYLAND_SHARED         (Wanted: OFF): OFF
  X11_SHARED             (Wanted: OFF): OFF

 CFLAGS:        /DWIN32 /D_WINDOWS /W3  -IC:/projects/SDL2-2.0.10/SDL2-2.0.10/src/hidapi/hidapi
 EXTRA_CFLAGS:  
 EXTRA_LDFLAGS: 
 EXTRA_LIBS:    user32;gdi32;winmm;imm32;ole32;oleaut32;version;uuid;advapi32;setupapi;shell32;dinput8

 Build Shared Library: ON
 Build Static Library: ON
 Build Static Library with Position Independent Code: OFF

Configuring done

日志中可以确定当前工程配置选择开关属性,也可以在界面中查看:

cmake 属性

这里显示红色,代表需要你选择自己的配置信息,并不代表配置错误,大家不要过分担心。大部分的配置其实 CMake 已经自动检测完成无需修改,这里面因为需要静态编译,所以请确保勾选 SDL_STATIC ,这里因为不需要动态库,所以移除 SDL_SHARED 选项。剩下的暂时无需改动,再次按下 Configure 按钮,确保生成的配置和我们期望的一致。

生成完毕后,界面不会在显示红色,这时候可以点击 Generate 按钮,生成我们的工程文件。如果生成成功,则旁边的 Open Project 按钮会从禁用状态变为可用,可以直接点击该按钮打开工程,也可以自己去 _build 目录寻找 SDL2.sln 自行打开。

3. 编译 SDL2 静态库

我们的最终目的是为了生成静态库,但是按照 Debug/Release 和 /MT 以及 /MD 之分,至少可以组合四种配置,所以我们分别选择不同的配置属性,生成最后的四种库文件,并将它们放到不同的目录下。具体的配置方法可以查看 运行时库详解 这篇文章,每次修改配置都编译一次工程,编译成功后,将生成的结果放到一开始设定的目录下,最后的目录结构如下:

---
 |--- include //放头文件
 |--- lib
       |--- Debug
       |      |--- MDd
       |      |     |-- SDL2d.lib
       |      |     |-- SDL2maind.lib
       |      |
       |      |--- MTd
       |            |-- SDL2d.lib
       |            |-- SDL2maind.lib
       |
       |--- Release
              |--- MD
              |     |-- SDL2d.lib
              |     |-- SDL2maind.lib
              |
              |--- MT
                    |-- SDL2d.lib
                    |-- SDL2maind.lib

为了方便这里我打包了最后的结果,方便大家直接使用,不过这里只有 x64 版本,如果你的机器还是 32 位系统则无法使用。SDL2 静态库下载

这里有一点注意,在 include 头文件的目录里面需要加入 CMake 生成的 SDL_config.h 文件,这个文件默认生成在 _build/include/SDL_config.h 里面,如果忘记这个头文件,在使用 SDL库的时候,可能会因为无法找到 SDL_config.h 而无法编译通过。

求关注