Mike Ferrier

I beat code into submission.

Compiling EEE for Rubyscript2Exe on Mac OSX

If you’re having problems compiling EEE for Rubyscript2Exe or AllInOneRuby on OSX, this post will explain how to modify the source to compile properly.

Rubyscript2Exe is a framework to “transform your Ruby application into a standalone, compressed Windows, Linux or Mac OS X (Darwin) executable.” To do so, it depends on a little Pascal program called Environment Embedding Executable, or EEE. It doesn’t look like this stuff has been updated in a while, because I had problems compiling it on my OSX system. It seems that the EEE source code is not compatible with the latest FreePascal compiler.

After downloading and installing the latest fpc, compiling barfs out some errors:

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
$ fpc -Xs -B eee.pas
Free Pascal Compiler version 2.4.4 [2011/05/01] for i386
Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Darwin for i386
Compiling eee.pas
eee.pas(151,49) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(172,29) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(204,43) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(395,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(395,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(395,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(421,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(421,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(421,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(444,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(444,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(444,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(489,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(489,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(489,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(512,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(512,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(512,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(535,52) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(535,70) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(535,90) Error: Parameters cannot contain local type definitions. Use a separate type definition in a type block.
eee.pas(1164) Fatal: There were 21 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppc386 returned an error exitcode (normal if you did not specify a source file to be compiled)

$ 

Turns out fpc has a problem with local type definitions in function parameters, and it considers static-length string identifiers, such as string[255], to be type definitions. Apparently this was not so when eee.pas was first written, because the function definitions are full of string[1] and string[255].

To fix, we simply have to define both of those types on their own, and then replace all references to these types with the name of the defined types. Here’s how I did it.

First I added the types, one for string[1] and one for string[255]:

1
2
3
4
5
type
  string255 = string[255];

type
  string1 = string[1];

Then I replaced all occurences of string[1] with string1, and string[255] with string255, e.g.:

1
2
3
4
5
6
7
type

  header =  record
    klasse  : string1;
    tekst    : string255;
    datalength  : longint;
  end;

Once these changes are made, compiling is no problem:

1
2
3
4
5
6
7
8
9
10
$ fpc -Xs -B eee_fixed.pas
Free Pascal Compiler version 2.4.4 [2011/05/01] for i386
Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Darwin for i386
Compiling eee_fixed.pas
Assembling (pipe) eee_fixed.s
Linking eee_fixed
1169 lines compiled, 0.4 sec

$ 

You can download eee.pas with these changes made here.

My pascal is pretty rusty, so if anyone has any pointers on improving this code, please let me know in the comments.

Comments