forked from alex-ilin/oo2c
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.WIN32
395 lines (291 loc) · 14.7 KB
/
README.WIN32
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
Using OOC under Win32
=====================
This document describes options for using OOC on Windows systems.
Currently, OOC requires the GNU C compiler (gcc). There are a couple of
implementations of gcc under Windows:
1) Mingw32 (www.mingw.org)
2) Cygwin (www.cygwin.com)
Mingw32 is a "minimalist" implementation of gcc for Win32 systems. Mingw32
applications link to Microsoft's own C run-time library (MSVCRTL.DLL),
which is installed as part of every Windows system. Some features of
Mingw32:
- Mingw32 environment is compact.
- Mingw32 applications are compact.
- Run-time library functions have "Windows" semantics.
- Some "Unix" functionality is not available.
Cygwin is an implementation of the Unix API for Windows. Cygwin
applications use GCC's run-time library as well as additional "emulation"
functions in a separate library (CYGWIN.DLL). Some features of Cygwin:
- Cygwin environment is very large.
- Cygwin applications require an additional large DLL.
- Run-time library functions have "Unix" semantics.
- Cygwin is only free for GPL code. Use with non-GPL code requires a
special contract with the vendors.
In many cases, Unix source code can run unmodified under Cygwin. Cygwin is
typically distributed with a large collection of Unix utilities, including:
- C compiler
- Bash shell
- ssh and cvs
- XWindows client libraries
- XWindows server
- inetd and friends (supporting ftp and telnet into Windows systems).
In addition, Cygwin supports the generation of Mingw applications via the
"-mno-cygwin" option.
OOC supports the following options:
- Cygwin
- Mingw stand-alone (with MSYS)
- Mingw under Cygwin
Note: Some of these configurations have not been extensively tested. Please
report any problems.
Path virtualisation
===================
The C compiler and associated utilities are Unix applications that have
been ported to run under Windows. Unix applications cannot be allowed to
see DOS file names, or they would fail to handle files properly. Each
application has its own file management procedures that assume Unix syntax.
To port such applications to Windows, the run-time environment MUST map all
DOS file paths to Unix syntax.
Applications compiled with Cygwin will see Unix-style paths. Applications
compiled with Mingw (or -mno-cygwin under Cygwin) will see Windows paths.
OOC will see different styles of paths according to which environment is
has been compiled under. However, the C compiler always sees virtual Unix
paths. For OOC and gcc to play nicely together:
It is ESSENTIAL that OOC and gcc SEE THE SAME PATHS TO SOURCE FILES.
Keep this in mind when installing the system. Try to avoid paths like "C:" and
"/C/" as these won't match between the two envionments. Use a mount to unify
the path names. For example, in the msys /etc/fstab, add an entry like:
c:/myname /myname
This allows you to completely omit the drive specifier in paths. Then to
configure pass "--prefix=/myname/local". Use the same prefix when installing
libraries like the GC. To tell the compiler where they are, use:
export LDFLAGS=-L/myname/local/lib
export CPPFLAGS=-I/myname/local/include
Note that OOC does not quote file names that are passed as arguments to the
C compiler, so:
PATHS TO SOURCE FILES MAY NOT INCLUDE WHITESPACE.
This may be an issue on Windows systems, in which the user's default working
directory is called something like "Documents and Settings/myname". To use OOC
under Windows, you will need a working directory that does not have spaces in
its name (eg. C:/users/myname").
Note that OOC uses an absolute path to name the "install" program. This means
that the path detected by "configure" may not be usable by the generated
compiler under mingw. To remedy this problem, specify the absolute path using
the INSTALL environment variable.
Installing the GC
=================
To do any serious work with OOC, you will need to install a garbage collector.
This is a separate library used by the compiler and OOC applications for
memory management. OOC uses Hans Boehm's GC, available here:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
Follow the installation instructions for the GC. The following discussion
applies for modern releases. It is recommended to use at least version
6.3alpha2.
1) Build the GC library.
./configure
make
2) Ensure that the GC is working correctly.
Under Cygwin:
make gctest
./gctest
Under MingW32, the test application is a Win32 application and writes its
output to a file "gc.log" rather than standard output.
make gctest.exe
./gctest
cat gc.log
3) Install the GC library
make install
4) Review possible configuration settings for OOC
Path issues:
Unless you specify another location to "configure" via the --prefix option,
the libraries will be installed in /usr/local/{lib,include}. Depending on
your local settings, this may not be the C compiler's search path. To ensure
that OOC finds the GC, you may need to use these settings:
CPPFLAGS=-I/usr/local/include
LDFLAGS=-L/usr/local/lib
It appears that these are necessary for MingW32/MSYS.
Threading issues:
Versions of the GC differ in how threads are handled under Win32.
For modern releases of the GC, "configure" builds a threaded GC under
MingW32. This requires locks to be statically allocated by the GC. Under
Win32, this only works correctly if client code defines the symbol:
GC_WIN32_THREADS
In summary, for MingW32/MSYS the following options are likely to be required
by the GC in order to build OOC:
"CPPFLAGS=-I/usr/local/include -DGC_WIN32_THREADS" \
LDFLAGS=-L/usr/local/lib
Installation
============
1) Make a directory `c:\usr\local\src', and extract the oo2c files here.
2) Under MSYS or Cygwin, ensure that `c:\usr\local' is mapped to the
logical path `/usr/local'. Normally, one would do:
mount c:/usr/local /usr/local
If you encounter problems with the "mount" tool, see additional comments
below.
3) `cd' to the directory containing the compiler source code.
4) Configure the package.
For Cygwin:
env CFLAGS=-O2 ./configure --disable-libs
For stand-alone Mingw32 (adjust path to "install.exe"):
env \
"INSTALL=c:/msys/1.0/bin/install.exe" \
LDFLAGS=-L/usr/local/lib \
CFLAGS=-O2 \
"CPPFLAGS=-I/usr/local/include -DGC_WIN32_THREADS" \
./configure --disable-libs
For Mingw32 under Cygwin:
env CPPFLAGS=-mno-cygwin CFLAGS=-O2 LDFLAGS=-mno-cygwin \
./configure --disable-libs
(depending on path settings, INSTALL path may be required as above)
5) Type `make' to compile the package.
6) Type `make install' to install the programs and any data files and
documentation. `make install-strip' will additionally remove any
debug information from the installed executables.
7) You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'.
Problems?
=========
1) In at least one version of MSYS it looks like the "mount" tool is
broken. If you keep getting "Function not implemented", you may need to
manually edit the MSYS fstab file (eg. C:\MSYS\1.0\etc\fstab). It should
look something like this:
c:/MinGW /mingw
c:/usr/local /usr/local
Note that MSYS must be restarted for any changes to take effect.
2) OOC couldn't find "install" during "make install"? Depending on path
settings, the detected path to "install" may not be valid for mingw
executables. See the explanation in "Path Virtualisation" and try setting
the INSTALL path before running "configure". For a quick fix, manually
adjust the "install" entries in the generated "rsrc/OOC/oo2crc.xml" and
re-run "make install".
3) While building OOC under MingW32, stage0/oo2c crashes abruptly? Most likely
you have a threaded GC, and have not defined "-DGC_WIN32_THREADS" during
configure. The crash is due to an uninitialised mutex in the GC. See
the section "Installing the GC".
4) You installed the GC under MingW32, but OOC did not find it? By default
mingw32/MSYS does not search in /usr/local/{lib,include} where the GC is
normally installed. You will need to explicitly specify these locations
to the compiler via the LDPATH and CPPFLAGS environment variables. See
the section "Installing the GC".
5) You have installed both cygwin and mingw32 toolchains, and the C compiler
is behaving strangely? Take care that you have the correct search paths
configured. As a general rule, you should not allow the MSYS shell to see
the cygwin compiler, and vice versa. The object files generated by the two
compilers are similar, but depend on different run-time libraries. If the
compiler sees the wrong object files at link-time you can expect to see
many undefined symbols.
Platform-specific issues
========================
This section discusses features of OOC relevant to the Win32 platform.
- Alignment. Many Win32 structure specify particular alignments. OOC
provides the following record flags to control the alignment of fields
within a record: ALIGN1 ALIGN2 ALIGN4 ALIGN8
Example:
tagMCI_WAVE_OPEN_PARMSA_struct* = RECORD [ALIGN1]
dwCallback* : DWORD;
wDeviceID* : MCIDEVICEID;
lpstrDeviceType* : LPCSTR;
lpstrElementName* : LPCSTR;
lpstrAlias* : LPCSTR;
dwBufferSeconds* : DWORD
END;
- Calling Conventions. Most functions in the Win32 API are declared to use
"Pascal" (or "stdcall") calling convention. For Pascal calls, the callee
removes any parameters from the stack before returning from the
procedure. In "C" calling convention (or "cdecl"), the caller removes
the parameters which permits the use of variable argument lists.
The "fastcall" calling convention is implemented by Microsoft's C compiler as
well as recent versions of GCC. Specifying "Fastcall" causes arguments to
functions to be passed in registers "where possible". For the x86, the first
two LONGINT or smaller arguments are passed (left to right) in the ECX and
EDX registers; all other arguments are passed right to left on the stack. The
callee removes arguments from the stack. On modern machines, the speed
benefits of fastcall are probably negligible, but it is occasionally used in
third-party application binary interfaces (ABIs) so it is included here for
compatibility with these libraries.
OOC allows calling convention to be specified in both Module declarations
and procedure declarations. For example, an interface module for a Win32
library is usually declared "Pascal":
MODULE WinApi [ INTERFACE "Pascal";
LINK LIB "kernel32"; LIB "user32"; LIB "gdi32" END];
Procedures or procedure types declared within the interface module will
inherit the specified calling convention.
WNDPROC* = PROCEDURE (p0 : HWND;
p1 : UINT; p2 : WPARAM; p3 : LPARAM) : LRESULT;
In the above example, WinApi.WNDPROC inherits the "Pascal" convention
declared in the module header. Exceptions from the module convention may
be declared per procedure. For example:
PROCEDURE wsprintfA* [ "C" ] (p0 : LPSTR; p1 : LPCSTR; ...) : LONGINT;
Regular Oberon-2 modules use the default calling convention, which is
compatible with "C". Oberon-2 functions to be used as Win32 call-backs
must therefore be explicitly declared "Pascal". For example:
IMPORT W := WinApi;
PROCEDURE MessageHandler ["Pascal"] (wnd : W.HWND;
msg : W.UINT; wParam : W.WPARAM; lParam : W.LPARAM) : W.LRESULT;
- C string assignment. Libraries written for the "C" language generally
represent text strings using the "char *" data type. The Oberon-2
equivalent is "POINTER TO ARRAY OF CHAR", which is not normally
compatible with Oberon strings types. The CSTRING pointer flag specifies
that "C"-style string assignments should be permitted. The following are
fragments from the Win32 API.
PCHAR* = POINTER [ CSTRING ] TO ARRAY OF CHAR;
...
LPCSTR* = PCHAR;
...
PROCEDURE MessageBoxA* (hWnd : HWND;
lpText : LPCSTR; lpCaption : LPCSTR; uType : UINT) : LONGINT;
The declaration of WinApi.MessageBoxA allows strings or character arrays
to be passed as the second and third parameters. For example:
IMPORT W := WinApi;
PROCEDURE TestMessage;
VAR result : LONGINT;
BEGIN
result := W.MessageBoxA(0, "Hello!", "This is a test Message", 0);
END TestMessage;
PROCEDURE MessageBox(title, message : ARRAY OF CHAR);
VAR result : LONGINT;
BEGIN
result := W.MessageBoxA(0, title, message, 0);
END;
Implementation Issues
=====================
1) File rename.
Windows file semantics do not allow open files to be renamed, or files to
be renamed over existing files. Cygwin emulates Unix behaviour, but not on
Win9X platforms.
- Files.File.Register uses unlink/rename/re-open
- IO:FileChannel uses the Win32 kernel function MoveFileEx to guarantee an
atomic rename operation. It is not clear which versions of Windows
support MoveFileEx.
2) ftruncate()
The ftruncate function is unavailable under Windows. This means that
PosixFileDescr.Truncate will always return an error.
3) Windows networking.
Windows networking functions are in a separate library, WSOCK32.DLL, which
is included if the relevant IO modules are used. The networking library is
configured as part of the initialisation for module IO:Socket. Note that
Windows sockets are not file descriptors and require a separate set of
functions to operate. For portable code, IO:SocketChannel should always be
used for sockets.
4) system()
There are many issues associated with the system() run-time function.
Under Unix, system() calls the Unix shell as its command interpreter.
Under windows, system() calls the Windows command interpreter. These
interpreters differ in their syntax and semantics. In addition, the
Microsoft C start-up code has its own rules for interpreting the command
line.
There appear to be some limitations in the Windows command interpreter that
prevent OOC passing long command lines to the C compiler (eg. as are
required for static linking). Therefore, OS:ProcessManagement.system does
not use the run-time library system() command. Instead, the command-line is
passed directly to the command using the Win32 kernel CreateProcess
function. This means that it is not possible to:
- use piping redirection with a system command
- specify substitutions using environment variables
An option exists to use an external shell `/bin/sh' for the system command.
This can be enabled by defining USE_SHELL in lib/src/OS/ProcessManagement.c.
With an external shell, such as `bash' installed in `C:\bin', system()
behaves the same as the Unix system() call. This configuration is necessary
to use the test framework from the OOC CVS repository.
-- Stewart Greenhill <sgreenhill@users.sf.net>