Difference between revisions of "Clean on Mac OS X"

From Clean
Jump to navigationJump to search
(Add linker compilation patches + instructions (gives error, not sure how to solve yet))
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
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.
+
'''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.
  
A useful page for building Clean on recent Unices is the [[Clean2.2 on 64bit Xubuntu]] page, which ends in the same problems I end up with here.
+
Another useful page for building Clean on recent Unices is the [[Clean2.2 on 64bit Xubuntu]] page.  
  
I haven't started working with Clean itself yet, therefore I don't know very well all of its components; however I hope to find out what everything does and how it works together in the process.
+
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 (later 10.6.5). You need to have XCode Tools installed before you begin. Please report back in the Discussion above what your results are.
  
This guide assumes basic knowledge of Terminal.app and the basics of UNIX. I am running on a MacBook Pro 2009 model running Mac OS X 10.6.4. 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 [http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.gz GNU binutils] to your Downloads directory using your browser (or in your terminal if you have 'wget' or similar installed), then:
 +
 
 +
<pre>
 +
~$ 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$
 +
</pre>
 +
 
 +
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 [http://www.agner.org/optimize/#objconv Agner Fog]. Download [http://www.agner.org/optimize/objconv.zip objconv.zip] to your Downloads folder, then:
 +
 
 +
<pre>
 +
/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$
 +
</pre>
 +
 
 +
If you want, you can clean up your binutils and objconv build dirs, or it will happen automatically at next boot.
 +
 
 +
<pre>
 +
/tmp$ rm -rf gas
 +
/tmp$ rm -rf objconv
 +
</pre>
 +
 
 +
Now we can finally assemble Intel gas x86-64 assembly files to 64-bit Mach-O files!
  
 
== Downloading sources ==
 
== 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 Clean|Download page]] ([http://clean.cs.ru.nl/download/Clean22/linux/Clean2.2_boot.tar.gz direct link]).
+
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 Clean|Download page]] ([http://clean.cs.ru.nl/download/Clean23/linux/clean2.3_64_boot.tar.gz 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.
 
Of course, the way of downloading and the place to download is up to you. I use wget and download to $HOME/clean.
Line 16: Line 89:
 
~$ mkdir clean
 
~$ mkdir clean
 
~$ cd clean
 
~$ cd clean
~/clean$ wget http://clean.cs.ru.nl/download/Clean22/linux/Clean2.2_boot.tar.gz
+
~/clean$ wget http://clean.cs.ru.nl/download/Clean23/linux/clean2.3_64_boot.tar.gz
 
[...]
 
[...]
2010-09-05 14:10:41 (429 KB/s) - '`Clean2.2_boot.tar.gz'' opgeslagen [5651786/5651786]
+
2010-12-27 19:46:20 (89,4 KB/s) - '`clean2.3_64_boot.tar.gz'' opgeslagen [9231078/9231078]
 
</pre>
 
</pre>
  
Line 24: Line 97:
  
 
<pre>
 
<pre>
~/clean$ tar -xzf Clean2.2_boot.tar.gz
+
~/clean$ tar -xzf clean2.3_64_boot.tar.gz
 
</pre>
 
</pre>
  
Download some of [http://files.dazjorz.com/clean/ my patches], which will hopefully be merged (after which this guide will be updated):
+
Download some of [[User:Sgielen/Patches|my patches]], which will hopefully be merged (after which this guide will be updated):
  
 
<pre>
 
<pre>
Line 33: Line 106:
 
~/clean$ wget http://files.dazjorz.com/clean/clean_mac_codegenerator.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_stdenvinclusion.patch
 +
~/clean$ wget http://files.dazjorz.com/clean/clean_mac_clm.patch
 
~/clean$ md5sum *.patch
 
~/clean$ md5sum *.patch
b23bff5456fa29f5bad3c5f3c4879df7 clean_mac_codegenerator.patch
+
6d6f1af88c8401c53e71a12ba53ea59f  clean_mac_clm.patch
cb877dc83ecd1c0cd8d7307de255d22b clean_mac_runtimesystem.patch
+
d257e6736f67c811fa2459c69f176b27 clean_mac_codegenerator.patch
e8bf18f68d336ddf879c5c8e11eaec56 clean_mac_stdenvinclusion.patch
+
2e857ebe4295b00d6d725fa99c4ac6a9 clean_mac_runtimesystem.patch
 +
0adf558225538feeed2e5a20c6ada1c0 clean_mac_stdenvinclusion.patch
 
</pre>
 
</pre>
  
Line 46: Line 121:
 
patching file clean/src/RuntimeSystem/Makefile.macosx
 
patching file clean/src/RuntimeSystem/Makefile.macosx
 
patching file clean/src/RuntimeSystem/Makefileprofile.macosx
 
patching file clean/src/RuntimeSystem/Makefileprofile.macosx
patching file clean/src/RuntimeSystem/iprofile.s
+
patching file clean/src/RuntimeSystem/afileIO3.asm
 
patching file clean/src/RuntimeSystem/scon.c
 
patching file clean/src/RuntimeSystem/scon.c
 
patching file clean/src/RuntimeSystem/ufileIO2.c
 
patching file clean/src/RuntimeSystem/ufileIO2.c
Line 52: Line 127:
 
~/clean/clean/src/RuntimeSystem$ make -f Makefile.macosx
 
~/clean/clean/src/RuntimeSystem$ make -f Makefile.macosx
 
[...]
 
[...]
~/clean/clean/src/RuntimeSystem$ file _startup.o
+
~/clean/clean/src/RuntimeSystem$ file _startup.a astartup.o
_startup.o: Mach-O object i386
+
_startup.a: current ar archive
 +
astartup.o: Mach-O 64-bit object
 +
~/clean/clean/src/RuntimeSystem$ make -f Makefile.macosx proper
 +
[...]
 
~/clean/clean/src/RuntimeSystem$ make -f Makefileprofile.macosx
 
~/clean/clean/src/RuntimeSystem$ make -f Makefileprofile.macosx
 
[...]
 
[...]
~/clean/clean/src/RuntimeSystem$ file _startupProfile.o
+
~/clean/clean/src/RuntimeSystem$ file _startupProfile.a astartup.o
_startupProfile.o: Mach-O object i386
+
_startupProfile.a: current ar archive
</pre>
+
astartup.o: Mach-O 64-bit object
 
+
~/clean/clean/src/RuntimeSystem$ make -f Makefileprofile.macosx proper
<pre>
+
[...]
~/clean/clean/src/RuntimeSystem$ cd ..
+
~/clean/clean/src/RuntimeSystem$ cd ../../..
~/clean/clean/src$ make ../stdenv/Clean\ System\ Files/_startup.o
 
cp RuntimeSystem/_startup.o ../stdenv/Clean\ System\ Files/_startup.o
 
~/clean/clean/src$ make ../stdenv/Clean\ System\ Files/_startupProfile.o
 
cp RuntimeSystem/_startupProfile.o ../stdenv/Clean\ System\ Files/_startupProfile.o
 
~/clean/clean/src$ cd ../..
 
 
~/clean$
 
~/clean$
 
</pre>
 
</pre>
  
 
== Building the Code Generator ==
 
== Building the Code Generator ==
 +
 +
The Clean Code Generator turns intermediate Clean files (''.abc'') into objectfiles (''.o'') or assembly files (''.s'').
  
 
<pre>
 
<pre>
 
~/clean$ patch -p0 <clean_mac_codegenerator.patch
 
~/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$ cd clean/src/CodeGenerator
~/clean/clean/src/CodeGenerator$ mkdir o
+
~/clean/clean/src/CodeGenerator$ make -f Makefile.macosx
~/clean/clean/src/CodeGenerator$ make -f Makefile.macosx_intel
 
 
[...]
 
[...]
 +
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
 
~/clean/clean/src/CodeGenerator$ file cg
cg: Mach-O executable i386
+
cg: Mach-O 64-bit executable x86_64
 
</pre>
 
</pre>
  
Line 89: Line 172:
 
~/clean$
 
~/clean$
 
</pre>
 
</pre>
 
== Compiling the system libraries ==
 
 
<pre>
 
~/clean$ cd stdenv/Clean\ System\ Files
 
~/clean/stdenv/Clean System Files$ ../../exe/cg _system
 
Unknown parameter type 0
 
reg.r -6, -8
 
Internal error in function: as_move_instruction 2
 
</pre>
 
 
XXX This obviously does not work yet. XXX
 
  
 
== Compiling patch_bin, clm and clms ==
 
== Compiling patch_bin, clm and clms ==
Line 107: Line 178:
  
 
<pre>
 
<pre>
~/clean$ cd clean/src
+
~/clean$ patch -p0 <clean_mac_clm.patch
~/clean/clean/src$ make tools/clm/patch_bin
+
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$ file tools/clm/patch_bin tools/clm/clm
+
~/clean/clean/src/tools/clm$ file patch_bin clm
tools/clm/patch_bin: Mach-O 64-bit executable x86_64
+
patch_bin: Mach-O 64-bit executable
tools/clm/clm:       Mach-O 64-bit executable x86_64
+
clm:       Mach-O 64-bit executable
</pre>
+
~/clean/clean/src/tools/clm$ make -f Makefile.macosx clms
'''XXX seeing i386 here is fine too. Maybe I should update the Makefiles to be i386 anyway.'''
+
[...]
<pre>
+
~/clean/clean/src/tools/clm$ file clms
 +
clms: Mach-O 64-bit executable
 +
~/clean/clean/src/tools/clm$ cd ../..
 
~/clean/clean/src$ make ../bin/patch_bin
 
~/clean/clean/src$ make ../bin/patch_bin
 
cp tools/clm/patch_bin ../bin/patch_bin
 
cp tools/clm/patch_bin ../bin/patch_bin
Line 121: Line 197:
 
cp tools/clm/clm ../bin/clm
 
cp tools/clm/clm ../bin/clm
 
[...]
 
[...]
~/clean/clean/src$ make tools/clm/clms
 
[...]
 
~/clean/clean/src$ file tools/clm/clms
 
tools/clm/clms: Mach-O 64-bit executable x86_64
 
 
~/clean/clean/src$ cd ../..
 
~/clean/clean/src$ cd ../..
 
~/clean$
 
~/clean$
 
</pre>
 
</pre>
 +
 +
== Compiling the standard libraries ==
 +
 +
The 64 bit bootstrap package that is available since Clean 2.3 is perfect for our purposes. With it, we can easily build a 64 bit version of the Clean Standard Library from the 64 bit pre-generated abc files.
 +
 +
One thing about this bootstrap package is that it contains object code for ELF/Linux next to the intermediary Clean files - we will simply remove these, and then rebuild the Mac object files.
 +
 +
<pre>
 +
~/clean$ cd clean/stdenv/Clean\ System\ Files
 +
~/clean/clean/stdenv/Clean System Files$ rm *.o
 +
~/clean/clean/stdenv/Clean System Files$ cp ../../exe/cg .
 +
~/clean/clean/stdenv/Clean System Files$ cp ../../src/RuntimeSystem/_startup.a _startup.o
 +
~/clean/clean/stdenv/Clean System Files$ cp ../../src/RuntimeSystem/_startupProfile.a _startupProfile.o
 +
</pre>
 +
 +
Now, until I patch `clm` to build objects the way I want to build them on Mac, we'll have to build stdenv manually:
 +
 +
<pre>
 +
~/clean/clean/stdenv/Clean System Files$ for i in *.abc; do j=`perl -le '$_=shift;s/\.abc$//;print' $i`; echo "Compiling $j..."; ./cg $j -s $j.s; x86_64-apple-elf-as $j.s -o $j.elf || break; objconv -fmacho64 $j.elf $j.o; done
 +
Compiling StdArray...
 +
 +
Input file: StdArray.elf, output file: StdArray.o
 +
Converting from ELF64 to Mach-O Little Endian64
 +
 +
  0 Debug sections removed
 +
  0 Exception sections removed
 +
Compiling StdBool...
 +
StdBool.s: Assembler messages:
 +
StdBool.s:6: Error: alignment not a power of 2
 +
StdBool.s:25: Error: alignment not a power of 2
 +
StdBool.s:44: Error: alignment not a power of 2
 +
[...]
 +
</pre>
 +
 +
This, however, does not work yet. More to come!
  
 
== Compiling the linker ==
 
== Compiling the linker ==
 +
 +
'''This section is old and needs to be updated. Don't follow the instructions: it's useless.'''
 +
 +
We are going to need the .abc files from Linux again, so log into it. Because the build references 'clms', which seems to be the same as 'clm' except for optimalization (?), we need to make sure 'clms' is in our PATH as an alias to clm. The steps below may be different for you.
 +
 +
<pre>
 +
linux:~$ cd `dirname $(which clm)`
 +
linux:~/clean/bin$ ln -s clm clms
 +
linux:~/clean/bin$ clms
 +
Usage: clm [options] module_name [-o application_name]
 +
path options: -I path -IL library -P paths
 +
[...]
 +
linux:~/clean/bin$ cd
 +
linux:~$
 +
</pre>
 +
 +
Now that you have a working clm, continue the build.
 +
 +
<pre>
 +
linux:~$ cd boot/boot/clean/clean/src
 +
linux:~/boot/boot/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
 +
Compiling linker
 +
Warning [StdFile.abc,63,accFiles;34]: no inline code for this rule
 +
Warning [StdFile.abc,63,stdio;33]: no inline code for this rule
 +
Warning [linker,_match0]: function may fail
 +
Compiling elf_linker
 +
[...]
 +
Generating code for elf_relocations
 +
Generating code for elf_linker2
 +
Linking linker
 +
linux:~/boot/boot/clean/clean/src$
 +
</pre>
 +
 +
This linker is also useless, but the .abc files aren't! Copy the .abc files in "linux:~/boot/boot/clean/clean/src/tools/elf_linker/Clean System Files" to your Mac to continue. For example:
  
 
<pre>
 
<pre>
~/clean$ patch -p0 <clean_mac_stdenvinclusion.patch
+
~/clean$ cd src/tools/elf_linker
Patching file clean/src/Makefile
+
~/clean/src/tools/elf_linker$ scp "stitch:boot/boot/clean/clean/src/tools/elf_linker/Clean\ System\ Files/*.abc" Clean\ System\ Files
~/clean$ cd clean/src
+
~/clean/src/tools/elf_linker$ cd ../..
~/clean/clean/src$ cp ../exe/cg tools/elf_linker
+
~/clean/src$ make tools/elf_linker/linker
~/clean/clean/src$ make tools/elf_linker/linker
 
 
[...]
 
[...]
Unknown parameter type 0
 
reg.r -6, -8
 
Internal error in function: as_move_instruction 2
 
 
</pre>
 
</pre>
  
Same error. Maybe I don't get it in my other directory because that `cg` is x86_64.
+
The rest of this process is TODO
  
 
== Compiling cocl ==
 
== Compiling cocl ==

Latest revision as of 00:05, 28 December 2010

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 (later 10.6.5). 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/Clean23/linux/clean2.3_64_boot.tar.gz
[...]
2010-12-27 19:46:20 (89,4 KB/s) - '`clean2.3_64_boot.tar.gz'' opgeslagen [9231078/9231078]

And unpack it...

~/clean$ tar -xzf clean2.3_64_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
6d6f1af88c8401c53e71a12ba53ea59f  clean_mac_clm.patch
d257e6736f67c811fa2459c69f176b27  clean_mac_codegenerator.patch
2e857ebe4295b00d6d725fa99c4ac6a9  clean_mac_runtimesystem.patch
0adf558225538feeed2e5a20c6ada1c0  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/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
[...]
~/clean/clean/src/RuntimeSystem$ make -f Makefileprofile.macosx
[...]
~/clean/clean/src/RuntimeSystem$ file _startupProfile.a astartup.o
_startupProfile.a: current ar archive
astartup.o: Mach-O 64-bit object
~/clean/clean/src/RuntimeSystem$ make -f Makefileprofile.macosx proper
[...]
~/clean/clean/src/RuntimeSystem$ cd ../../..
~/clean$

Building the Code Generator

The Clean Code Generator turns intermediate Clean files (.abc) into objectfiles (.o) or assembly files (.s).

~/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 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 64-bit executable
clm:       Mach-O 64-bit executable
~/clean/clean/src/tools/clm$ make -f Makefile.macosx clms
[...]
~/clean/clean/src/tools/clm$ file clms
clms: Mach-O 64-bit executable
~/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 standard libraries

The 64 bit bootstrap package that is available since Clean 2.3 is perfect for our purposes. With it, we can easily build a 64 bit version of the Clean Standard Library from the 64 bit pre-generated abc files.

One thing about this bootstrap package is that it contains object code for ELF/Linux next to the intermediary Clean files - we will simply remove these, and then rebuild the Mac object files.

~/clean$ cd clean/stdenv/Clean\ System\ Files
~/clean/clean/stdenv/Clean System Files$ rm *.o
~/clean/clean/stdenv/Clean System Files$ cp ../../exe/cg .
~/clean/clean/stdenv/Clean System Files$ cp ../../src/RuntimeSystem/_startup.a _startup.o
~/clean/clean/stdenv/Clean System Files$ cp ../../src/RuntimeSystem/_startupProfile.a _startupProfile.o

Now, until I patch `clm` to build objects the way I want to build them on Mac, we'll have to build stdenv manually:

~/clean/clean/stdenv/Clean System Files$ for i in *.abc; do j=`perl -le '$_=shift;s/\.abc$//;print' $i`; echo "Compiling $j..."; ./cg $j -s $j.s; x86_64-apple-elf-as $j.s -o $j.elf || break; objconv -fmacho64 $j.elf $j.o; done
Compiling StdArray...

Input file: StdArray.elf, output file: StdArray.o
Converting from ELF64 to Mach-O Little Endian64

  0 Debug sections removed
  0 Exception sections removed
Compiling StdBool...
StdBool.s: Assembler messages:
StdBool.s:6: Error: alignment not a power of 2
StdBool.s:25: Error: alignment not a power of 2
StdBool.s:44: Error: alignment not a power of 2
[...]

This, however, does not work yet. More to come!

Compiling the linker

This section is old and needs to be updated. Don't follow the instructions: it's useless.

We are going to need the .abc files from Linux again, so log into it. Because the build references 'clms', which seems to be the same as 'clm' except for optimalization (?), we need to make sure 'clms' is in our PATH as an alias to clm. The steps below may be different for you.

linux:~$ cd `dirname $(which clm)`
linux:~/clean/bin$ ln -s clm clms
linux:~/clean/bin$ clms
Usage: clm [options] module_name [-o application_name]
path options: -I path -IL library -P paths
[...]
linux:~/clean/bin$ cd
linux:~$

Now that you have a working clm, continue the build.

linux:~$ cd boot/boot/clean/clean/src
linux:~/boot/boot/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
Compiling linker
Warning [StdFile.abc,63,accFiles;34]: no inline code for this rule
Warning [StdFile.abc,63,stdio;33]: no inline code for this rule
Warning [linker,_match0]: function may fail
Compiling elf_linker
[...]
Generating code for elf_relocations
Generating code for elf_linker2
Linking linker
linux:~/boot/boot/clean/clean/src$

This linker is also useless, but the .abc files aren't! Copy the .abc files in "linux:~/boot/boot/clean/clean/src/tools/elf_linker/Clean System Files" to your Mac to continue. For example:

~/clean$ cd src/tools/elf_linker
~/clean/src/tools/elf_linker$ scp "stitch:boot/boot/clean/clean/src/tools/elf_linker/Clean\ System\ Files/*.abc" Clean\ System\ Files
~/clean/src/tools/elf_linker$ cd ../..
~/clean/src$ make tools/elf_linker/linker
[...]

The rest of this process is TODO

Compiling cocl

TODO

Compiling htoclean

TODO

Installing and wrapping up

TODO