Clean on Mac OS X

From Clean
Revision as of 22:31, 28 October 2010 by Sgielen (talk | contribs) (Add line I had forgotten earlier)
Jump to navigationJump to search

This page is a work-in-progress for building Clean on recent Mac OS X systems. There is an official build for Clean on Mac, but it's 32-bit PowerPC-based; a shame since the newest Macs are 64-bit Intel-based.

Another useful page for building Clean on recent Unices is the Clean2.2 on 64bit Xubuntu page.

This guide assumes basic knowledge of Terminal.app and the basics of UNIX. I am writing this during my fall 2010 Functional Programming course, using a MacBook Pro 2009 model running Mac OS X 10.6.4. You need to have XCode Tools installed before you begin. Please report back in the Discussion above what your results are.

Building the GNU assembler

Because XCode Tools contains an ancient version of the GNU assembler, we will start by building one ourselves. However, because `gas` does not seem to be able to write to 64-bit mach-o objectfiles at time of writing, we will build a version of gas that builds 64-bit ELF files, and we will convert them to Mach-O 64-bit (improvements to this process are very welcome). To start, download GNU binutils to your Downloads directory using your browser (or in your terminal if you have 'wget' or similar installed), then:

~$ mkdir /tmp/gas
~$ cd /tmp/gas
/tmp/gas$ mv ~/Downloads/binutils-2.20.1.tar.gz .
/tmp/gas$ tar -xzf binutils-2.20.1.tar.gz
/tmp/gas$ cd binutils-2.20.1/bfd
/tmp/gas/binutils-2.20.1/bfd$ ./configure --prefix="$HOME" --target="x86_64-apple-elf"
[...]
config.status: executing default commands
/tmp/gas/binutils-2.20.1/bfd$ make
[...]
touch stamp-lib
/tmp/gas/binutils-2.20.1/bfd$ cd ../opcodes
/tmp/gas/binutils-2.20.1/opcodes$ ./configure --prefix="$HOME" --target="x86_64-apple-elf"
[...]
config.status: creating po/Makefile
/tmp/gas/binutils-2.20.1/opcodes$ make libopcodes.la
[...]
/tmp/gas/binutils-2.20.1/opcodes$ cd ../libiberty
/tmp/gas/binutils-2.20.1/libiberty$ ./configure --prefix="$HOME"
[...]
/tmp/gas/binutils-2.20.1/libiberty$ make libiberty.a
[...]
else true; fi
/tmp/gas/binutils-2.20.1/libiberty$ cd ../gas
/tmp/gas/binutils-2.20.1/gas$ ./configure --prefix="$HOME" --target="x86_64-apple-elf"
[...]
config.status: executing default commands
/tmp/gas/binutils-2.20.1/gas$ make
[...]
/tmp/gas/binutils-2.20.1/gas$ make install
[...]
/tmp/gas/binutils-2.20.1/gas$ ~/bin/x86_64-apple-elf-as --version
[...]
This assembler was configured for a target of `x86_64-apple-elf'.
/tmp/gas/binutils-2.20.1/gas$ cd /tmp
/tmp$

We are ready to assemble to ELF. Now, to be able to assemble to Mach-O, our native format, we need objconv, a tool by Agner Fog. Download objconv.zip to your Downloads folder, then:

/tmp$ mkdir objconv && cd objconv
/tmp/objconv$ mv ~/Downloads/objconv.zip .
/tmp/objconv$ unzip objconv.zip
Archive:  objconv.zip
  inflating: objconv.exe             
  inflating: objconv-instructions.pdf  
 extracting: source.zip              
 extracting: extras.zip   
/tmp/objconv$ unzip source.zip
Archive: source.zip
[...]
 inflating: build.sh
/tmp/objconv$ g++ -o objconv -O2 *.cpp
[...]
/tmp/objconv$ file objconv
objconv: Mach-O 64 bit executable x86_64
/tmp/objconv$ cp objconv ~/bin/
/tmp/objconv$ cd /tmp
/tmp$

If you want, you can clean up your binutils and objconv build dirs, or it will happen automatically at next boot.

/tmp$ rm -rf gas
/tmp$ rm -rf objconv

Now we can finally assemble Intel gas x86-64 assembly files to 64-bit Mach-O files!

Downloading sources

Because a part of Clean is written in Clean, we need to take a 'bootstrap' package to build. This package contains some 'precompiled' Clean source (no machine-dependent object code, however). You can get it from the Download page (direct link).

Of course, the way of downloading and the place to download is up to you. I use wget and download to $HOME/clean.

~$ mkdir clean
~$ cd clean
~/clean$ wget http://clean.cs.ru.nl/download/Clean22/linux/Clean2.2_boot.tar.gz
[...]
2010-09-05 14:10:41 (429 KB/s) - '`Clean2.2_boot.tar.gz'' opgeslagen [5651786/5651786]

And unpack it...

~/clean$ tar -xzf Clean2.2_boot.tar.gz

Download some of my patches, which will hopefully be merged (after which this guide will be updated):

~/clean$ wget http://files.dazjorz.com/clean/clean_mac_runtimesystem.patch
~/clean$ wget http://files.dazjorz.com/clean/clean_mac_codegenerator.patch
~/clean$ wget http://files.dazjorz.com/clean/clean_mac_stdenvinclusion.patch
~/clean$ wget http://files.dazjorz.com/clean/clean_mac_clm.patch
~/clean$ md5sum *.patch
3fda955b8801fd1da98a55ba09d6a795  clean_mac_clm.patch
4bc56357ef14e1016a2955a987535350  clean_mac_codegenerator.patch
d0c7a14afcfc02566c81e027e1a0c329  clean_mac_runtimesystem.patch
e8bf18f68d336ddf879c5c8e11eaec56  clean_mac_stdenvinclusion.patch

Building the RuntimeSystem

Because the standard Makefile assumes we are using Linux, we will build the RuntimeSystem ourselves.

~/clean$ patch -p0 <clean_mac_runtimesystem.patch 
patching file clean/src/RuntimeSystem/Makefile.macosx
patching file clean/src/RuntimeSystem/Makefileprofile.macosx
patching file clean/src/RuntimeSystem/afileIO3.asm
patching file clean/src/RuntimeSystem/afileIO3.s
patching file clean/src/RuntimeSystem/areals.s
patching file clean/src/RuntimeSystem/scon.c
patching file clean/src/RuntimeSystem/ufileIO2.c
~/clean$ cd clean/src/RuntimeSystem
~/clean/clean/src/RuntimeSystem$ make -f Makefile.macosx
[...]
~/clean/clean/src/RuntimeSystem$ file _startup.a astartup.o
_startup.a: current ar archive
astartup.o: Mach-O 64-bit object
~/clean/clean/src/RuntimeSystem$ make -f Makefile.macosx proper
[...]

Building the Code Generator

~/clean$ patch -p0 <clean_mac_codegenerator.patch
patching file clean/src/CodeGenerator/Makefile.macosx
patching file clean/src/CodeGenerator/cg.c
patching file clean/src/CodeGenerator/cgaas.c
patching file clean/src/CodeGenerator/cgawas.c
patching file clean/src/CodeGenerator/cginput.c
patching file clean/src/CodeGenerator/cgport.h
~/clean$ cd clean/src/CodeGenerator
~/clean/clean/src/CodeGenerator$ make -f Makefile.macosx
[...]
gcc o/cg.o o/cginput.o o/cgcode.o o/cginstructions.o o/cgstack.o o/cgcalc.o o/cglin.o o/cgopt.o o/cgaas.o o/cgawas.o -arch x86_64 -framework Carbon -o cg
~/clean/clean/src/CodeGenerator$ make -f Makefile.macosx proper
rm o/cg.o o/cginput.o o/cgcode.o o/cginstructions.o o/cgstack.o o/cgcalc.o o/cglin.o o/cgopt.o o/cgaas.o o/cgawas.o
~/clean/clean/src/CodeGenerator$ file cg
cg: Mach-O 64-bit executable x86_64
~/clean/clean/src/CodeGenerator$ cd ..
~/clean/clean/src$ make ../exe/cg
cp CodeGenerator/cg ../exe/cg
~/clean/clean/src$ cd ../..
~/clean$

Compiling the system libraries

~/clean$ cd stdenv/Clean\ System\ Files
~/clean/stdenv/Clean System Files$ ../../exe/cg _system
~/clean/stdenv/Clean System Files$ file _system.obj
_system.obj: ACB archive data
~/clean/stdenv/Clean System Files$

Compiling patch_bin, clm and clms

We need to install patch_bin correctly first, before compiling clms. Clm will be built automatically while building patch_bin.

~/clean$ patch -p0 <clean_mac_clm.patch
patching file clean/src/tools/clm/Makefile.macosx
patching file clean/src/tools/clm/clm.c
~/clean$ cd clean/src/tools/clm
~/clean/clean/src/tools/clm$ make -f Makefile.macosx
[...]
~/clean/clean/src/tools/clm$ file patch_bin clm
patch_bin: Mach-O executable i386
clm:       Mach-O executable i386
~/clean/clean/src/tools/clm$ make -f Makefile.macosx clms
[...]
~/clean/clean/src/tools/clm$ file clms
clms: Mach-O executable i386
~/clean/clean/src/tools/clm$ cd ../..
~/clean/clean/src$ make ../bin/patch_bin
cp tools/clm/patch_bin ../bin/patch_bin
~/clean/clean/src$ make ../bin/clm
cp tools/clm/clm ../bin/clm
[...]
~/clean/clean/src$ cd ../..
~/clean$

Compiling the linker

~/clean$ patch -p0 <clean_mac_stdenvinclusion.patch
Patching file clean/src/Makefile
~/clean$ cd clean/src
~/clean/clean/src$ cp ../exe/cg tools/elf_linker
~/clean/clean/src$ make tools/elf_linker/linker
cd tools/elf_linker; \
	../clm/clms -nr -nt -h 20m -s 2m -I ia32 -I ../../libraries/ArgEnvUnix -I ../../compiler/main/Unix -I ../../../stdenv linker -o linker; \
	cp linker ../../../exe/linker; \
	../../../bin/clm -nr -nt -h 20m -s 2m -I ia32 -I ../../libraries/ArgEnvUnix -I ../../compiler/main/Unix linker -o linker
Generating code for linker
Generating code for ArgEnv
Generating code for set_return_code
Generating code for elf_linker
Generating code for StdClass
Generating code for StdString
B, C, F, I, P or R expected at line 255 (got 
)
cp: linker: No such file or directory
Compiling StdInt
Can't find StdInt.icl
make: *** [tools/elf_linker/linker] Error 1

And this is the error the Clean2.2 on 64bit Xubuntu ends with, too. Help from the list is required here.

Compiling cocl

TODO

Compiling htoclean

TODO

Installing and wrapping up

TODO