The collector has at various times been compiled under Windows 95 & later, NT, and XP, with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with the GNU win32 tools, with Borland 4.5, with Watcom C, and recently with the Digital Mars compiler. It is likely that some of these have been broken in the meantime. Patches are appreciated. For historical reasons, the collector test program "gctest" is linked as a GUI application, but does not open any windows. Its output normally appears in the file "gctest.gc.log". It may be started from the file manager. The hour glass cursor may appear as long as it's running. If it is started from the command line, it will usually run in the background. Wait a few minutes (a few seconds on a modern machine) before you check the output. You should see either a failure indication or a "Collector appears to work" message. The cord test program has not been ported (but should port easily). A toy editor (cord/de.exe) based on cords (heavyweight strings represented as trees) has been ported and is included. It runs fine under either win32 or win32S. It serves as an example of a true Windows application, except that it was written by a nonexpert Windows programmer. (There are some peculiarities in the way files are displayed. The is displayed explicitly for standard DOS text files. As in the UNIX version, control characters are displayed explicitly, but in this case as red text. This may be suboptimal for some tastes and/or sets of default window colors.) In general -DREDIRECT_MALLOC is unlikely to work unless the application is completely statically linked. The collector normally allocates memory from the OS with VirtualAlloc. This appears to cause problems under Windows NT and Windows 2000 (but not Windows 95/98) if the memory is later passed to CreateDIBitmap. To work around this problem, build the collector with -DUSE_GLOBAL_ALLOC. This is currently incompatible with -DUSE_MUNMAP. (Thanks to Jonathan Clark for tracking this down. There's some chance this may be fixed in 6.1alpha4, since we now separate heap sections with an unused page.) [Threads and incremental collection are discussed near the end, below.] Microsoft Tools --------------- For Microsoft development tools, rename NT_MAKEFILE as MAKEFILE. (Make sure that the CPU environment variable is defined to be i386.) In order to use the gc_cpp.h C++ interface, all client code should include gc_cpp.h. For historical reasons, the collector test program "gctest" is linked as a GUI application, but does not open any windows. Its output appears in the file "gctest.gc.log". It may be started from the file manager. The hour glass cursor may appear as long as it's running. If it is started from the command line, it will usually run in the background. Wait a few minutes (a few seconds on a modern machine) before you check the output. You should see either a failure indication or a "Collector appears to work" message. If you would prefer a VC++.NET project file, ask boehm@acm.org. One has been contributed, but it seems to contain some absolute paths etc., so it can presumably only be a starting point, and is not in the standard distribution. It is unclear (to me, Hans Boehm) whether it is feasible to change that. Clients may need to define GC_NOT_DLL before including gc.h, if the collector was built as a static library (as it normally is in the absence of thread support). GNU Tools --------- The collector should be buildable under Cygwin with the "./configure; make check" machinery. MinGW builds (including for x86_64) are available via cross-compilation, e.g. "./configure --host=i686-pc-mingw32; make check" To build the collector as a DLL, pass "--enable-shared --disable-static" to configure (this will instruct make compile with -D GC_DLL). Parallel marker could be enabled via "--enable-parallel-mark". Memory unmapping could be enabled via "--enable-munmap" (not well supported on Cygwin currently). Borland Tools ------------- [Rarely tested.] For Borland tools, use BCC_MAKEFILE. Note that Borland's compiler defaults to 1 byte alignment in structures (-a1), whereas Visual C++ appears to default to 8 byte alignment (/Zp8). The garbage collector in its default configuration EXPECTS AT LEAST 4 BYTE ALIGNMENT. Thus the BORLAND DEFAULT MUST BE OVERRIDDEN. (In my opinion, it should usually be anyway. I expect that -a1 introduces major performance penalties on a 486 or Pentium.) Note that this changes structure layouts. (As a last resort, gcconfig.h can be changed to allow 1 byte alignment. But this has significant negative performance implications.) The Makefile is set up to assume Borland 4.5. If you have another version, change the line near the top. By default, it does not require the assembler. If you do have the assembler, I recommend removing the -DUSE_GENERIC. Digital Mars compiler --------------------- Same as MS Visual C++ but might require -DAO_OLD_STYLE_INTERLOCKED_COMPARE_EXCHANGE option to compile with the parallel marker enabled. Watcom compiler --------------- Ivan V. Demakov's README for the Watcom port: The collector has been compiled with Watcom C 10.6 and 11.0. It runs under win32, win32s, and even under msdos with dos4gw dos-extender. It should also run under OS/2, though this isn't tested. Under win32 the collector can be built either as dll or as static library. Note that all compilations were done under Windows 95 or NT. For unknown reason compiling under Windows 3.11 for NT (one attempt has been made) leads to broken executables. Incremental collection is not supported. cord is not ported. Before compiling you may need to edit WCC_MAKEFILE to set target platform, library type (dynamic or static), calling conventions, and optimization options. To compile the collector and testing programs use the command: wmake -f WCC_MAKEFILE All programs using gc should be compiled with 4-byte alignment. For further explanations on this see comments about Borland. If the gc is compiled as dll, the macro ``GC_DLL'' should be defined before including "gc.h" (for example, with -DGC_DLL compiler option). It's important, otherwise resulting programs will not run. Ivan Demakov (email: ivan@tgrad.nsk.su) Note from Ivan Maidanski: Special note for OpenWatcom users: the C (unlike the C++) compiler (of the latest stable release, not sure for older ones) doesn't force pointer global variables (i.e. not struct fields, not sure for locals) to be aligned unless optimizing for speed (eg. "-ot" option is set); the "-zp" option (or align pragma) only controls alignment for structs; I don't know whether it's a bug or a feature (see an old report of same kind - http://bugzilla.openwatcom.org/show_bug.cgi?id=664), so You are warned. Incremental Collection ---------------------- There is some support for incremental collection. By default, the collector chooses between explicit page protection, and GetWriteWatch-based write tracking automatically, depending on the platform. The former is slow and interacts poorly with a debugger. Pages are protected. Protection faults are caught by a handler installed at the bottom of the handler stack. Whenever possible, I recommend adding a call to GC_enable_incremental at the last possible moment, after most debugging is complete. No system calls are wrapped by the collector itself. It may be necessary to wrap ReadFile calls that use a buffer in the heap, so that the call does not encounter a protection fault while it's running. (As usual, none of this is an issue unless GC_enable_incremental is called.) Note that incremental collection is disabled with -DSMALL_CONFIG. Threads ------- This version of the collector by default handles threads similarly to other platforms. James Clark's code which tracks threads attached to the collector DLL still exists, but requires that both - the collector is built in a DLL with GC_DLL defined, and - GC_use_threads_discovery() is called before GC initialization, which in turn must happen before creating additional threads. We generally recommend avoiding this if possible, since it seems to be less than 100% reliable. Use gc.mak (a.k.a NT_THREADS_MAKEFILE) instead of NT_MAKEFILE to build a version that supports both kinds of thread tracking. To build the garbage collector test with VC++ from the command line, use nmake /F ".\gc.mak" CFG="gctest - Win32 Release" This requires that the subdirectory gctest\Release exist. The test program and DLL will reside in the Release directory. This version currently supports incremental collection only if it is enabled before any additional threads are created. Since 6.3alpha2, threads are also better supported in static library builds with Microsoft tools (use NT_STATIC_THREADS_MAKEFILE) and with the GNU tools. The collector must be built with GC_THREADS defined. (NT_STATIC_THREADS_MAKEFILE does this implicitly. Under Cygwin, ./configure --enable-threads=posix should be used.) For the normal, non-dll-based thread tracking to work properly, threads should be created with GC_CreateThread or GC_beginthreadex, and exit normally or call GC_endthreadex or GC_ExitThread. (For Cygwin, use standard pthread calls instead.) As in the pthread case, including gc.h will redefine CreateThread, _beginthreadex, _endthreadex, and ExitThread to call the GC_ versions instead. Note that, as usual, GC_CreateThread tends to introduce resource leaks that are avoided by GC_beginthreadex. There is currently no equivalent of _beginthread, and it should not be used. GC_INIT should be called from the main executable before other GC calls. We strongly advise against using the TerminateThread() win32 API call, especially with the garbage collector. Any use is likely to provoke a crash in the GC, since it makes it impossible for the collector to correctly track threads. To build the collector for Mingw32 Pthreads, use Makefile.direct and explicitly set GC_WIN32_PTHREADS. Use -DPTW32_STATIC_LIB for the static threads library.