KEEP K.I.S.S.

tk's blog

Mingw + CMake + SDL2开发环境搭建

1. 安装 Mingw

如果已经安装有Mingw则可跳过此节。

这里推荐 TDM-GCC 的版本,在 Download 页面选择下载在线安装包 tdm-gcc-webdl.exe

运行在线安装包,默认选项一路Next。

安装完成后建议新打开一个命令行窗口,输入gcc --version 来检查Mingw是否已经在PATH路径中。

2. 安装 CMake

去CMake下载页面,选择 Latest Release 中的 Windows (Win32 Installer) 右侧的exe文件下载,安装时在 Install Options 界面,选择第2项 Add CMake to the system PATH for all user 或者第3项。

3. 安装 SDL2 开发库

本节参考 Setting up SDL 2 on MinGW

去SDL下载页面,选择下方的 Development Libraries 的 SDL2-devel-2.x.x-mingw.tar.gz (MinGW 32/64-bit)(当前版本是 2.0.3),下载完成后解压。

复制解压出的文件夹中的i686-w64-mingw32文件夹到某个位置,这里以D:\根目录为例,然后重命名 i686-w64-mingw32 为 mingw_dev_lib。以后类似其他的开发库也可以放在这里,便于集中管理。

SDL2.0.3的版本中有一个头文件依赖的bug,点此下载SDL_platform.h 覆盖掉目录include\SDL2中的同名文件[*]

4. SDL2 例子测试

下载压缩包 helloworld.zip 并解压,解压后文件夹应该有3个文件,分别是 CMakeLists.txtles1_hello.bmp 和 main.cpp,这里如果SDL2库安装的位置不是D:\mingw_dev_lib,则需要修改 CMakeLists.txt 中对应的路径为指定位置。

在解压后的文件夹中打开命令行窗口(Win7下Shift+鼠标右键,选择在此处打开命令窗口),
依次输入命令

mkdir build && cd build
cmake -G "MinGW Makefiles" ..
mingw32-make

如果没有任何报错,那么在文件夹中的 build 文件夹下会出现一个 main.exe,双击它然后你应该可以看到一个 Hello world 的界面。

至此,SDL2 的开发环境搭建完成。

link_directories位置问题

昨天在Win上整SDL2的编译环境,遇到一个问题。

用的编译器是MinGW(TDM-GCC),因为不想手写Makefile,所以构建工具用的是CMake。在安装好SDL2的头文件和库后,下载了一个示例代码测试。编写CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(hellosdl)
aux_source_directory(. DIR_SRCS)
include_directories("D:/mingw_dev_lib/include")
add_definitions("-Wall")
add_executable(main ${DIR_SRCS})
link_directories("D:/mingw_dev_lib/lib")
target_link_libraries(main mingw32 SDL2main SDL2)

mkdir build && cd buildcmake -G "MinGW Makefiles" ..之后mingw32-make,结果链接器ld报错,cannot find -lSDL2maincannot find -lSDL2

应该是链接器找不到SDL2的库文件。但是明明已经添加了link_directories了。

查找link_directories文档,赫然写着

The command will apply only to targets created after it is called.

link_directories这句放到add_executable之前就可以了。

PS: 其实可以通过查看build目录下CMakeFiles\main.dir中的link.txt文件中来确定最终链接器的参数。可以对比下修正前后该文件的内容。

PS2: 其实开始我是通过对比link.txt的文件内容才知道link_directories没有起作用,没有去查阅文档而是直接谷歌。 虽然最后问题解决了,但还是感觉有点2啊(┬_┬)。

C文件读写一个盲点

《C陷阱与缺陷》第5.2节说道

为了保持与过去不能同时进行读写操作的程序的向下兼容性,一个输入操作不能随后直接紧跟一个输出操作,反之亦然。如果要同时进行输入和输出操作,必须在其中插入fseek函数的调用。

这里指以读+写模式打开的文件,既要进行读操作,还要进行写操作时需要注意的。

那么原因是什么?这个“向下兼容性”是指什么?

想看英文的直接戳这里 why fseek or fflush is always required between reading and writing in the read/write “+” modes

解释说:文件流的实现中可能会有单独的输入缓冲区和输出的缓冲区,分别用于fread 和 fwrite两类操作的缓冲优化。当一个fread操作紧跟一个fwrite操作时,逻辑上,fwrite操作之前必须要保证输入缓冲区中的内容已经被处理完毕(缓冲区的内容都提交给应用程序处理,即缓冲区为空),否则fwrite操作后,缓存与实际就不同步了(试想一下接下来调用fread,因为输入缓冲区残留有上次的内容,那么这次读取的就不是当前位置的文件内容了)。但是fread操作后紧跟另外一个fread操作就不需要这种保证(缓冲区的意义所在)。反之亦然。

这种保证,在实际文件流实现中,如果每次fread/fwrite都去检查并刷新缓冲区(fread检查输出缓冲区,fwrite检查输入缓冲区),会导致实现代码变的复杂,而且也会降低性能。并且只有在复合模式(可以同时读入和写出)下才需要这种检查。只读和只写则无需考虑。

所以标准库把这种只在某些情况下才需要做的工作留给了库的使用者。我觉得这挺符合C的principle的

那么,其他高级语言有这个问题吗?比如CPython,Ruby MRI等,这些依赖C实现的。

答案是有。

Python: Mixing read() and write() on Python files in Windows

Ruby: ruby read and write/change the same file

但是在CPython和Ruby MRI自带文档中都没有找到这样的提示,依赖C实现,也是没有太多注意吧。

Debian安装后的一些配置备注

由于Sabayon升级后一直有一个奇怪的locale问题,最近又重新安装了 Debian Wheezy,这里记录一下安装后需要做的一些配置工作。

1. 修改源

网上搜到修改源的方法大多都是手动编辑/etc/apt/source.list,其实有更方便的做法。打开新立得包管理器,在设置里的软件库中选择下载源即可,建议同时取消勾选other software中的CD/DVD源。

2. 安装 sudo

输入 su 切换到root,安装sudo后,添加个人用户到sudo组:adduser xxx sudo 然后注销重新登录,sudo即可用。不需要手动编辑sudo配置文件。

3. Xfce 调整双击间隔

默认Xfce窗口是支持双击标题栏最大化最小化窗口的,但是默认安装后基本感觉没有效果,这是因为默认双击间隔是250ms,太短,在设置里的鼠标中调整双击阈值为400,即可。

 

待补充...

Vim中高亮不需要的空白符

本文提到的不需要的空白符有两类:

  1. 附在行尾的空白。行尾空白通常是由于不小心添加到的,在编辑器下也不可见,但它会对版本控制造成不必要的影响。这里有个需要注意的地方,标准 Markdown 语法里,行尾添加 2个以上空格表示段落内强制换行。

  2. 缩进中混用制表符和空白符。在代码缩进中混用制表符和空格不是个好习惯,会造成在不同编辑器、不同制表符设置下代码显示格式错乱,更别说 Python 这样对格式要求苛刻的语言了。

.vimrc 文件中添加如下代码

highlight ExtraWhitespace ctermbg=red guibg=red
autocmd BufWinEnter * match ExtraWhitespace /\s\+$\| \+\ze\t\+\|\t\+\zs \+/

就可以高亮提到的两类空白符,这里稍作解释。

  1. 会将行尾空白符和制表空格混排中的空格都高亮为红色
  2. 使用 autocmd BufWinEnter * 是因为 match 只能对当前窗口有效,具体可以查看 :help match
  3. 用于匹配的正则表达式分3个多选组,/\s\+$/ 用于匹配行尾空白符,/ \+\ze\t\+/ 用于匹配紧邻制表符前的空格,/\t\+\zs \+/ 用于匹配紧跟制表符后的空格。当然,也可以选择高亮混排中的制表符而不是空格,这样写,/ \+\zs\t\+//\t\+\ze \+/

参考资料

  1. Highlight unwanted spaces