作为程序员是不应该带有偏见的人,因为我们是创造者,我们吸取好的,摒弃不好的,努力的站在他人的肩膀上,使用咒语展现魔法的魅力和力量,美丽这个世界。

搭建Scheme环境

安装Vscode

  官方网站https://code.visualstudio.com/,下载对应需要安装的平台的软件,本教程是的平台是Win10。
安装Vscode中文插件Chinese (Simplified) Language Pack for Visual Studio Code,安装Scheme语法插件vscode-scheme,设置Vscode自带的颜色主题Ctrl+k Ctrl+t,选择Solarized Dark主题。

安装ChezScheme解释器

下载解释器

  访问官网https://www.scheme.com/,点击Chez Scheme Github project page,进入官网下载对应的版本,这里下载的是Win10的版本,默认安装路径。

设置环境变量

  打开ChezScheme安装的路径C:\Program Files\Chez Scheme 9.5\bin或C:\Program Files (x86)\Chez Scheme 9.5\bin,i3ntti3nt支持Inter的电脑,a6ntta6nt支持AMD的电脑,前面是支持32位,后面支持64位,根据自己电脑将相应的bin路径放入系统环境变量。

按装win下的scheme的打包tool

打包工具

测试实例Code

example
1
2
3
;; A helloworld demo
(dispaly "Helloworld\n")
(exit)

Unbunt16环境搭建

安装Linux依赖的文件

cmd
1
2
sudo apt-get install libghc-x11-dev
sudo apt install auto-apt checkinstall

使用auto-apt 和 checkinstall跟踪make install文件

cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#安装auto-apt和checkinstall
sudo apt install auto-apt checkinstall
#在源码目录中
auto-apt run ./configure -m=ta6le LDFLAGS=-liconv
make -j8
#这样会生成一个deb包,卸载和重新安装就非常方便了
checkinstall
#完全卸载 (packagename具体的名字在checkintall完成之后会有提示)
dpkg -r packagename
#用生成的deb包重新安装
dpkg -i ***.deb
#更多实用的命令
# 列出包中安装的文件位置dpkg -L packagename
# 检查是否安装成功dpkg -l | grep packagename
# 同上apt list --installed | grep packagename

关于在ARM上或者Android上编译参考
参考1
参考2

安装chez scheme

Libiconv的undefine问题
产生原因可参考,解决办法如下

cmd
1
2
# 让Gcc链接libiconv库的头文件时去链接/usr/include/iconv.h
sudo mv /usr/local/include/iconv.h /usr/local/include/iconv.h.bak

原因-对比两文件

Gcc优先查找的是/usr/local/include/iconv.h文件,导致预编译中有函数名字添加了lib字段

/usr/local/include/iconv.h
1
2
3
4
5
6
/* Allocates descriptor for code conversion from encoding ‘fromcode’ to
encoding ‘tocode’. */
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
extern iconv_t iconv_open (const char* tocode, const char* fromcode);
/usr/include/iconv.h
1
2
3
4
5
6
/* Allocate descriptor for code conversion from codeset FROMCODE to
codeset TOCODE.

This function is a possible cancellation point and therefore not
marked with __THROW. */
extern iconv_t iconv_open (const char *__tocode, const char *__fromcode);

安装Linux下的scheme的打包tool

打包工具

安装

cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
auto-apt run ./configure  -m=ta6le LDFLAGS=-liconv
make -j8
sudo checkinstall
sudo make install

#./configure -m = i3nt
# 安装线程版本,请使用-m = ti3nt
machine-type 是否启用线程 架构 位元 操作系统
ti3osx 是 x86 32 Darwin
ta6osx 是 x86 64 Darwin
i3osx 否 x86 32 Darwin
a6osx 否 x86 64 Darwin
ti3fb 是 x86 32 FreeBSD
ta6fb 是 x86 64 FreeBSD
i3fb 否 x86 32 FreeBSD
a6fb 否 x86 64 FreeBSD
tppc32le 是 PowerPC 32 Linux
ti3le 是 x86 32 Linux
tarm32le 是 ARM 32 Linux
ta6le 是 x86 64 Linux
ppc32le 否 PowerPC 32 Linux
i3le 否 x86 32 Linux
arm32le 否 ARM 32 Linux
a6le 否 x86 64 Linux
ti3nb 是 x86 32 NetBSD
ta6nb 是 x86 64 NetBSD
i3nb 否 x86 32 NetBSD
a6nb 否 x86 64 NetBSD
ti3ob 是 x86 32 OpenBSD
ta6ob 是 x86 64 OpenBSD
i3ob 否 x86 32 OpenBSD
a6ob 否 x86 64 OpenBSD
ti3qnx 是 x86 32 QNX
i3qnx 否 x86 32 QNX
ti3s2 是 x86 32 SunOS
ta6s2 是 x86 64 SunOS
i3s2 否 x86 32 SunOS
a6s2 否 x86 64 SunOS
ti3nt 是 x86 32 Windows
ta6nt 是 x86 64 Windows
i3nt 否 x86 32 Windows
a6nt 否 x86 64 Windows

测试chez Scheme程序

通过使用 make-boot-file 可以将 Chez Scheme 程序编译为单文件
文档如下:

procedure: (make-boot-file output-filename base-boot-list input-filename …)
returns: unspecified
libraries: (chezscheme)output-filename, input-filename, and the elements of base-boot-list must be strings.
make-boot-file writes a boot header to the file named by output-filename, followed by the object code for each input-filename in turn. If an input file is not already compiled, make-boot-file compiles the file as it proceeds.
The boot header identifies the elements of base-boot-list as alternative boot files upon which the new boot file depends. If the list of strings naming base boot files is empty, the first named input file should be a base boot file, i.e., petite.boot or some boot file derived from petite.boot.
Boot files are loaded explicitly via the –boot or -b command-line options or implicitly based on the name of the executable (Section 2.9).
See Section 2.8 for more information on boot files and the use of make-boot-file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;; lib/b.ss
(library (lib b)
(export y)
(import (rnrs))
(define y "Hello!\n"))

;; lib/a.ss
(library (lib a)
(export x)
(import (rnrs)
(lib b))
(define x y))

;; main.ss
(import (rnrs)
(lib a))

(display x)
cmd
1
2
3
4
5
6
7
8
9
# 编译
echo $'(make-boot-file "main.boot" \'("scheme" "petite") "lib/b.ss" "lib/a.ss" "main.ss")' | scheme -q
# 需要注意的是,input-filename 的顺序要和 import 的顺序一样,不然会无法找到
# 然后是关于 base-boot-list:

# In most cases, you can construct your application so it does not depend upon features of Chez Scheme (specifically, the compiler) by specifying only "petite" in the call to make-boot-file. If your application calls eval, however, and you wish to allow users to be able to take advantage of the faster execution speed of compiled code, then specifying both "scheme" and "petite" is appropriate.

# 运行
scheme --program main.boot

打包发布 Chez Scheme 程序

  Chez Scheme 程序编译为单文件, 不过仍然需要 Chez Scheme 或者是 Petite Chez Scheme 才能运行,发布的时候把 Chez Scheme 打包进去。

Chez Scheme 依赖两个文件,petite.boot 和 scheme.boot, 如果用的是Petite Chez Scheme就只依赖petite.boot,.boot文件请参考Section 9.15. Fasl Output

对于 Chez Scheme, 这两个文件的搜索路径是 ~/lib/csv%v/%m /usr/lib/csv%v/%m /usr/local/lib/csv%v/%m
具体的路径得看你安装在哪
如果 make 的时候没有指定, 那就在 /usr/lib/csv%v/%m
%v 和 %m 分别代表了 Chez Scheme 的版本和安装的 machine-type
获取版本用 scheme –version, 而获取 machine-type, 可以直接打开scheme,调用(machine-type)
比如我这里就是 /usr/lib/csv9.5/ta6le/petite.boot 和 /usr/lib/csv9.5/ta6le/scheme.boot
可以通过 –boot 或 -b 参数来加载这俩文件
然后把这几个 .boot 文件和 scheme 程序 libconvi动态库,再加个启动脚本打包分发就行了
启动脚本很简单

cmd
1
2
3
4
#!/bin/bash
./scheme -b ./petite.boot -b ./scheme.boot --program ./main.boot
# 类似这样的, 只需要根据实际情况改一下文件名, main.boot 是编译出来的主程序
# 如果考虑到动态链接库问题, 就把 Chez Scheme 静态编译, 或者把静态链接库也打包进去

参考

Github-docker-scheme仓库

使用Docker测试

1
2
3
4
docker pull matace/matace-dockerfile-pri-build:scheme
docker run -it matace/matace-dockerfile-pri-build
cd /root/scheme/
./scheme_run.sh