1 | [[tags: manual]] |
---|
2 | [[toc:]] |
---|
3 | |
---|
4 | |
---|
5 | == Cross Development |
---|
6 | |
---|
7 | Since CHICKEN generates C code, it is relatively easy to create |
---|
8 | programs and libraries for a different architecture than the one the |
---|
9 | compiler is executing on, a process commonly called ''cross |
---|
10 | compiling''. Basically you can simply compile Scheme code to C and |
---|
11 | then invoke your target-specific cross compiler. To automate the |
---|
12 | process of invoking the correct C compiler with the correct settings |
---|
13 | and to simplify the use of extensions, CHICKEN can be built in a |
---|
14 | special "cross-compilation" mode. |
---|
15 | |
---|
16 | Note: in the following text we refer to the "target" as being the |
---|
17 | platform on which the software is intended to run in the end. We use |
---|
18 | the term "host" as the system that builds this software. Others use a |
---|
19 | different nomenclature or switch the meaning of the words. |
---|
20 | |
---|
21 | === Preparations |
---|
22 | |
---|
23 | Make sure you have a cross-toolchain in your {{PATH}}. In this |
---|
24 | example, a Linux system is used to generate binaries for an ARM based |
---|
25 | embedded system. |
---|
26 | |
---|
27 | ==== Building the target libraries |
---|
28 | |
---|
29 | First you need a version of the runtime system ({{libchicken}}), |
---|
30 | compiled for the target system. Obtain and unpack a tarball of the |
---|
31 | CHICKEN sources, or check out the code from the official code |
---|
32 | repository, then build the libraries and necessary development files: |
---|
33 | |
---|
34 | make ARCH= \ |
---|
35 | PREFIX=/usr \ |
---|
36 | PLATFORM=linux \ |
---|
37 | HOSTSYSTEM=arm-none-linux-gnueabi \ |
---|
38 | DESTDIR=$HOME/target \ |
---|
39 | TARGET_FEATURES="-no-feature x86 -feature arm" \ |
---|
40 | libs install-dev |
---|
41 | |
---|
42 | This will build the CHICKEN libraries and install them in {{~/target}}, |
---|
43 | which we use as a temporary place to store the target files. A few things |
---|
44 | to note: |
---|
45 | |
---|
46 | * {{ARCH}} is empty, since we don't want the build process to detect the |
---|
47 | architecture (since the target-architecture is likely to be different). |
---|
48 | |
---|
49 | * {{PREFIX}} gives the prefix ''on the target system'', under which the |
---|
50 | libraries will finally be installed. In this case it will be {{/usr/lib}}. |
---|
51 | |
---|
52 | * {{PLATFORM}} determines the target platform. It must be one of the officially |
---|
53 | supported platforms CHICKEN runs on. |
---|
54 | |
---|
55 | * {{HOSTSYSTEM}} is an identifier for the target system and will be used as |
---|
56 | the name prefix of the cross C compiler (in this case {{arm-none-linux-gnueabi-gcc}}). |
---|
57 | If your cross compiler does not follow this convention, pass {{C_COMPILER}} and |
---|
58 | {{LIBRARIAN}} to the {{make(1)}} invocation, with the names of the C compiler and |
---|
59 | {{ar(1)}} tool, respectively. |
---|
60 | |
---|
61 | * {{DESTDIR}} holds the directory where the compiled library files will temporarily |
---|
62 | installeds into. |
---|
63 | |
---|
64 | * {{TARGET_FEATURES}} contains extra options to be passed to the target-specific |
---|
65 | Scheme translator; in this case we disable and enable features so that code like |
---|
66 | the following will do the right thing when cross-compiled: |
---|
67 | |
---|
68 | <enscript hightlight=scheme> |
---|
69 | (cond-expand |
---|
70 | (x86 <do this ...>) |
---|
71 | ...) |
---|
72 | </enscript> |
---|
73 | |
---|
74 | * If you obtained the sources from a source-code repository and not |
---|
75 | from an official release tarball, you will need a {{chicken}} |
---|
76 | executable to compile the Scheme sources of the runtime system. In |
---|
77 | this case pass yet another variable to the {{make(1)}} invocation: |
---|
78 | {{CHICKEN=<where the "chicken" executable is}}. |
---|
79 | |
---|
80 | * You can also put all those variables into a file, say {{config.mk}} |
---|
81 | and run {{make CONFIG=config.mk}}. |
---|
82 | |
---|
83 | You should now have these files on {{~/target}}: |
---|
84 | |
---|
85 | `-- usr |
---|
86 | |-- include |
---|
87 | | |-- chicken-config.h |
---|
88 | | `-- chicken.h |
---|
89 | |-- lib |
---|
90 | | |-- chicken |
---|
91 | | | `-- 5 |
---|
92 | | | `-- types.db |
---|
93 | | |-- libchicken.a |
---|
94 | | `-- libchicken.so |
---|
95 | `-- share |
---|
96 | |
---|
97 | You should now transfer {{libchicken.so}} to the target system, and place |
---|
98 | it in {{/usr}}. |
---|
99 | |
---|
100 | ==== Building the "cross chicken" |
---|
101 | |
---|
102 | Next, we will build another chicken, one that uses the cross C compiler to |
---|
103 | generate target-specific code that uses the target-specific runtime library |
---|
104 | we have just built. |
---|
105 | |
---|
106 | Again, unpack a CHICKEN release tarball or a source tree and run |
---|
107 | {{make(1)}} once again: |
---|
108 | |
---|
109 | make PLATFORM=linux \ |
---|
110 | PREFIX=$HOME/cross-chicken \ |
---|
111 | TARGETSYSTEM=arm-none-linux-gnueabi \ |
---|
112 | PROGRAM_PREFIX=arm- \ |
---|
113 | TARGET_PREFIX=$HOME/target/usr \ |
---|
114 | TARGET_RUN_PREFIX=/usr \ |
---|
115 | install |
---|
116 | |
---|
117 | * {{PREFIX}} gives the place where the "cross chicken" should be installed |
---|
118 | into. It is recommended not to install into a standard location (like {{/usr/local}} |
---|
119 | or {{$HOME}}) - some files will conflict with a normal CHICKEN installation. |
---|
120 | |
---|
121 | * {{TARGETSYSTEM}} gives the name-prefix of the cross C compiler. |
---|
122 | |
---|
123 | * {{PROGRAM_PREFIX}} determines the name-prefix of the CHICKEN tools to be created. |
---|
124 | |
---|
125 | * {{TARGET_PREFIX}} specifies where the target-specific files (libraries and |
---|
126 | headers) are located. This is the location where we installed the runtime |
---|
127 | system into. |
---|
128 | |
---|
129 | * {{TARGET_RUN_PREFIX}} holds the PREFIX that will be effective at runtime |
---|
130 | (so {{libchicken.so}} will be found in {{$TARGET_RUN_PREFIX/lib}}). |
---|
131 | |
---|
132 | * Make sure to use the same version of the CHICKEN sources for the target and |
---|
133 | the cross build. |
---|
134 | |
---|
135 | * If you build the cross chicken from repository sources, the same note |
---|
136 | about the {{CHICKEN}} variable applies as given above. |
---|
137 | |
---|
138 | In {{~/cross-chicken}}, you should find the following: |
---|
139 | |
---|
140 | |-- bin |
---|
141 | | |-- arm-chicken |
---|
142 | | |-- arm-chicken-bug |
---|
143 | | |-- arm-chicken-install |
---|
144 | | |-- arm-chicken-profile |
---|
145 | | |-- arm-chicken-status |
---|
146 | | |-- arm-chicken-uninstall |
---|
147 | | |-- arm-csc |
---|
148 | | `-- arm-csi |
---|
149 | |-- include |
---|
150 | | |-- chicken-config.h |
---|
151 | | `-- chicken.h |
---|
152 | |-- lib |
---|
153 | | |-- chicken |
---|
154 | | | `-- 5 |
---|
155 | | | : |
---|
156 | | | |
---|
157 | | |-- libchicken.a |
---|
158 | | |-- libchicken.so -> libchicken.so.5 |
---|
159 | | `-- libchicken.so.5 |
---|
160 | `-- share |
---|
161 | |-- chicken |
---|
162 | | |-- doc |
---|
163 | : ; : |
---|
164 | | | |
---|
165 | | `-- setup.defaults |
---|
166 | `-- man |
---|
167 | `-- man1 |
---|
168 | : |
---|
169 | |
---|
170 | To make sure that the right C compiler is used, we ask {{arm-csc}} to show |
---|
171 | the name of the cross C compiler: |
---|
172 | |
---|
173 | % ~/cross-chicken/arm-csc -cc-name |
---|
174 | arm-none-linux-gnueabi-gcc |
---|
175 | |
---|
176 | Looks good. |
---|
177 | |
---|
178 | === Using it |
---|
179 | |
---|
180 | ==== Compiling simple programs |
---|
181 | |
---|
182 | % ~/cross-chicken/arm-csc -v hello.scm |
---|
183 | /home/felix/cross-chicken/arm-cross-chicken/bin/arm-chicken hello.scm -output-file hello.c -quiet |
---|
184 | arm-none-linux-gnueabi-gcc hello.c -o hello.o -c -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -g -Wall \ |
---|
185 | -Wno-unused -I /home/felix/cross-chicken/arm-chicken/include |
---|
186 | rm hello.c |
---|
187 | arm-none-linux-gnueabi-gcc hello.o -o hello -L/home/felix/cross-chicken/arm-chicken/lib -Wl,-R/usr/lib -lm \ |
---|
188 | -ldl -lchicken |
---|
189 | rm hello.o |
---|
190 | |
---|
191 | Is it an ARM binary? |
---|
192 | |
---|
193 | % file hello |
---|
194 | hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.16, dynamically linked (uses shared libs), not stripped |
---|
195 | |
---|
196 | Yes, looks good. |
---|
197 | |
---|
198 | ==== Compiling extensions |
---|
199 | |
---|
200 | By default, the tools that CHICKEN provides to install, list and uninstall |
---|
201 | extensions will operate on both the host and the target repository. |
---|
202 | So running {{arm-chicken-install}} will compile and install the extension |
---|
203 | for the host system and for the cross-target. To selectively install, uninstall |
---|
204 | or list extensions for either the host or the target system use the |
---|
205 | {{-host}} and {{-target}} options for the tools. |
---|
206 | |
---|
207 | === "Target-only" extensions |
---|
208 | |
---|
209 | Sometimes an extension will only be compilable for the target platform |
---|
210 | (for example libraries that use system-dependent features). In this |
---|
211 | case you will have to work around the problem that the host-compiler |
---|
212 | still may need compile-time information from the target-only |
---|
213 | extension, like the import library of modules. One option is to copy |
---|
214 | the import-library into the repository of the host compiler: |
---|
215 | |
---|
216 | # optionally, you can compile the import library: |
---|
217 | # ~/cross-chicken/arm-csc -O3 -d0 -s target-only-extension.import.scm |
---|
218 | cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/5 |
---|
219 | |
---|
220 | === Final notes |
---|
221 | |
---|
222 | Cross-development is a very tricky process - it often involves countless |
---|
223 | manual steps and it is very easy to forget an important detail or mix |
---|
224 | up target and host systems. Also, full 100% platform neutrality is |
---|
225 | hard to achieve. CHICKEN tries very hard to make this transparent, but |
---|
226 | at the price of considerable complexity in the code that manages |
---|
227 | extensions. |
---|
228 | |
---|
229 | |
---|
230 | ---- |
---|
231 | Previous: [[Deployment]] |
---|
232 | Next: [[Data representation]] |
---|