今天我们来玩点没啥用的东西: 如何在Mac OS 9上开发App。
Mac OS 9是乔布斯1997年回归苹果后,Classic Mac的最后一代操作系统。当时苹果内部在寻求现代操作系统的更新方向,期间谈过几次可能的合作,包括曾经在苹果做过CEO的Jean-Louis Gassée创业做的BeOS系统等等,最后还是选择让乔帮主回归拯救世界。于是乔布斯带着他的NeXTSTEP系统回来了,最终整合成为Classic Mac的全新操作系统OS X,于2001年发布。
X是10的罗马数字,此后全新的Mac操作系统都基于OS X后面增加版本号,一直到2016年才改名为现在的"macOS"。
最后一台能运行Mac OS 9系统的硬件是2004年发布的iMac G5,它的上一代iMac G4就是那个著名的"台灯iMac"。这两代Mac都是用的PPC架构(PowerPC CPU),2006年后苹果正式迁移到Intel芯片。
因为最近朋友整了一台iMac G4所以我就想在上面做点东西玩玩,看看20多年前的Mac开发者都是怎么做App的,当然这也是一项现在看来毫无用处的技能,仅供诸君娱乐。
本来我尝试在Apple Silicon MacBook上跑QEMU失败了,这个想法就暂且搁置了。后来跟 @Livid 录节目他提到可以用UTM虚拟机于是我又重新燃起了热情。
声明: 本文使用CodeWarrior开发的部分跟随YouTube Channel Masters of the Void的影片[Retro: Programming a MacOS 9 app with CodeWarrior]()学习总结而作,感兴趣的小伙伴可以看看他的视频。
1. 准备工作
- 一台现代的Mac,最好是Apple Silicon的性能好一点的,因为要爬虚拟机
- UTM虚拟机: 因为大部分人都没有这么老的机器,所以我们需要用到虚拟机来跑。
- UTM Gallery中有Mac OS 9.2.1的image可以直接安装
- CodeWarrior 10 Gold: 这是在Classic Mac上的开发工具。
- ResEdit 2.1.3: 这是在Classic Mac上类似后来的Interface Builder(Nib/Xib/Storyboard)一样的开发工具。
2. 启动Mac OS 9和CodeWarrior
在UTM中安装好Mac OS 9之后,我们需要把下载下来的CodeWarrior光盘插入虚拟机的IDE Driver。
启动Mac OS 9,如果有需要配置的地方,直接默认配置即可。这个image不支持中文,我们全程使用英文开发就好。
打开CodeWarrior的光盘,然后找到IDE 1.7打开即可。打开之后,我们点左上角全局菜单的"File->New Project…"新建一个工程。
这里我们选择"MacOS->C/C++->Basic Toolbox PPC"
选MacOS因为我们要开发Mac OS 9的App。虽然看上去它支持C/C++,Pascal,但Classic Mac的开发文档都是用C的,所以如果用Pascal就需要我们精通C与Pascal两种语法才能顺利开发。PowerPlant则是CodeWarrior自带的C++框架,你如果选了这个他们会把整个framework代码都加入你的工程里。所以我们用C/C++就好。
Basic Toolbox PPC。68K选项是早期摩托罗拉68000系列芯片时期的遗留产物(XNU源码里还有对这东西的吐槽哈哈),我们直接选PPC就好了。
下一步选好存储位置,起个工程名字。我这里选择放在桌面的一个文件夹,工程名字填入"hello",这样就创建了一个Demo工程。
- Sources
- 这里面是源码,SillyBalls.c是自动创建的Main函数在这里。
- Resources
- 这里是静态资源。.rsrc文件是需要使用ResEdit来编辑的,跟后来的Interface Builder有一点像,但是功能上弱了很多,是一个原始版。
- Mac Libraries
- 这里的是Mac系统库,其中这个MWCRuntime.lib会帮你实现一个__start函数,这个是Classic Mac的App的入口,如过没有这个Lib他就会链接报错。(在macOS 内核之系统如何启动? 中我们也提到过这个符号。)
- InterfaceLib,包括Window, icon, Button之类的API都在里面
- MathLib,数学函数
- ANSI Libraries
- 这里面就是C++标准库之类的基础库
- 里面这个SIOUX.PPC.Lib这个库,包含了创建窗口,接受标准输入输出这样的实现。有这个库你就可以在Mac OS 9上写出printf之类的代码了,不过我们基本都会做一个GUI界面所以其实用不上。
如此我们创建好一个Demo工程之后,按下"Cmd+R"就可以愉快地跑起来了!
额并不能。链接错误,'hello'不能被写入,需要read/write权限。
原因是CodeWarrior默认会用我们刚才创建的Porject的名字"hello"来命名它的编译产出物,那这个文件我们已经打开着了,当然没有写入权限啦。
解决方案很简单,关掉CodeWarrior,我们把工程文件名字改一下,比如'hello.prj',保存再打开。
重启跑起来,这个Demo程序就是会生成很多个不同颜色的球,鼠标在window上点一下就自动退出,完美。
能把Demo工程跑起来,接下来就是安装ResEdit然后自己编写一个Window,里面加点Button就能用啦!
3. 其实已经25年了
Mac OS 9是1999年首次发布的,其实已经过去25年了。同时期微软已经发布Windows 98了。我原以为几十年过去很多东西会很“原始”,但真的用下来其实已经很现代了。
所以Mac OS 9还不够"原始",以后再回溯到Apple II之类的看看,感觉应该会很有意思。
最后给大家表演一个用MacBook触摸板在Mac OS 9里用ResEdit一点点画我台的Logo,然后CodeWarrior实现一个WIndow里面有几个假的Button装个样子,哈哈。