用ECL编译字符游戏的跨平台(Linux/OSX/WINDOWS)可执行文件
说明
前面我们用 CLISP
写了一个代码超简短的字符游戏, 不过每次运行时都需要通过 Common Lisp
来加载, 本文介绍一种可以把 Common Lisp
代码编译为可执行文件的方法: 用 ECL
把 Common Lisp
程序编译为可执行文件.
这里稍微介绍一下 ECL
-Embedded Common Lisp
, 也就是嵌入式 Common Lisp
, 它采用了一种不同于其他 Common Lisp
实现的内部处理, 具体说就是把 Common Lisp
代码翻译为标准 C
代码, 然后调用系统上的 gcc
进行编译. 所以使用 ECL
的前提是安装好 gcc
编译器.
正因为 ECL
的这种内部处理机制, 所以只要是符合 ANSI Common Lisp
标准的代码都可以由 ECL
编译为可执行文件.
而且因为调用了 gcc
进行实际的编译链接, 所以生成的可执行文件体积非常小.
相关编译命令
- 编译函数
compile-file
, 用于把Common Lisp
源代码编译为.fas
文件; - 构建函数
c:build-program
, 用于调用gcc
生成可执行文件; - 全局变量
c::*delete-files*
, 用于设置是否删除中间文件.
假设要编译的文件为 c11-cn.lisp
, 我们的编译构建命令如下:
(setf c::*delete-files* nil)(compile-file "c11-cn.lisp" :system-p t)(c:build-program "c11-cn" :lisp-files '("c11-cn.o"))(quit)
可执行文件
就以之前我们的那个字符游戏为例, 把它编译为可执行文件, 在 OSX
系统上执行上述命令后, 会生成可执行文件 c11-cn
, 如下:
Air:ecl admin$ ls -al c11-*-rwxr-xr-x 1 admin staff 16004 12 19 01:30 c11-cn-rw-r--r-- 1 admin staff 7898 12 19 01:30 c11-cn.c-rw-r--r-- 1 admin staff 1011 12 19 01:30 c11-cn.data-rw-r--r-- 1 admin staff 527 12 19 01:30 c11-cn.eclh-rw-r--r-- 1 admin staff 2389 12 19 01:28 c11-cn.lisp-rw-r--r-- 1 admin staff 33652 12 19 01:30 c11-cn.oAir:ecl admin$
看看执行的效果:
Air:ecl admin$ ./c11-cn| || || || A A || A || || || A || @ || A A || A A || || A || || || A |qwe/asd/zxc 用来移动, (t)eleport-瞬移, (l)eave-离开:
可以看到, 可执行文件非常小, 仅仅 16k
, 跟其他 Common Lisp
实现动辄生成几十M
的可执行文件相比, ECL
生成的十几K
可执行文件简直就是小到极点了(当然小了, 因为本来就是用 gcc
生成的).
但是该有的功能一点也不缺, 而且还具备跨平台的优势.
在树莓派的 Raspbian
系统下进行编译的命令是一样的, 不过可执行文件要稍微大一些, 48k
, 如下:
pi@rpi ~/code-staff/ecl $ ls -al c11-*-rwxr-xr-x 1 pi pi 48564 Dec 19 00:01 c11-cn-rw-r--r-- 1 pi pi 7184 Dec 19 00:01 c11-cn.c-rw-r--r-- 1 pi pi 990 Dec 19 00:01 c11-cn.data-rw-r--r-- 1 pi pi 527 Dec 19 00:01 c11-cn.eclh-rw-r--r-- 1 pi pi 2386 Dec 19 00:01 c11-cn.lisp-rw-r--r-- 1 pi pi 130 Dec 18 17:22 c11-cn-make.lisp-rw-r--r-- 1 pi pi 36344 Dec 19 00:01 c11-cn.o-rw-r--r-- 1 pi pi 114 Dec 18 21:01 c11-make.lisppi@rpi ~/code-staff/ecl $ ./c11-cn| || || A|| A || || A || A A || || @ A || A || A || || A || A || || |qwe/asd/zxc 用来移动, (t)eleport-瞬移, (l)eave-离开:
在 WINDOWS
下编译应该是一样的, 不过需要预先安装好 gcc
, 暂时没试验, 后面试验了再补充.