Using SWI-Prolog on Cygwin
Author: Jan Wielemaker
E-mail: wielemak@science.uva.nl
Created: Jun 17 2001
Modified: Nov 21 2005
Nov 23, 2005 by Corinna Vinschen
Wat is Cygwin?
Cygwin is a POSIX emulation environment for Windows (95 and newer, NT 4 and newer). It consists of a DLL which provides POSIX functionality on top of Windows and ported (mostly GNU) toolchain and applications. For further info, see http://cygwin.com.
Why SWI-Prolog on Cygwin?
The original and primary development platform of SWI-Prolog is Unix (currently SuSE Linux). SWI-Prolog has been ported to MS-Windows using various emulators of the required basic POSIX functonality. First this was the WATCOM environment. Right now it is MSVC using the NT Posix layer with an additional library (src/win32/uxnt) to provide some additional functionality and work around some bugs and dubious features of the NT POSIX layer.
Cygwin provides a fairly complete emulation of the POSIX standard, while allowing access to the native Win32 API at the same time. The cygwin ports therefore uses almost exclusively the POSIX source. The only exception is the stack-allocation that uses the VirtualAlloc() API from Win32 because it is better and the mmap() emulation of cygwin is not good enough at the moment.
Cygwin is an excelent platform for porting native Unix applications to Windows without much work. Though the native Win32 version of SWI-Prolog can run under Cygwin, it is limited in this environment. It cannot load shared objects created in Cygwin and it doesn't use Cygwins POSIX extensions to the Windows filesystem (mount-points, symbolic links). Therefore only a Cygwin version of SWI-Prolog can use advanced POSIX behaviour, which is especially useful to realise portable advanced process and server management.
Drawbacks?
Cygwin is just `fairly complete', it doesn't support every POSIX call, mostly due to lack of manpower. Cygwin is big, so if SWI-Prolog is your only cygwin application it isn't very interesting. Cygwin is slow, notably handling calls for which you really want it such as fork().
So, it is useful if your boss says your application must run on Windows and the application uses lots of advanced Unix primitives. In all other cases I would recomment using a real Unix machine. They are cheaper and as easy to manage as windows machines these days.
Problems?
Most today Unix systems are based on the ELF executable format, while Windows uses XCOFF (eXtended COFF). This has some consequences for making foreign libraries for SWI-Prolog. With the cygwin port we've started to put all these system dependencies in plld, but it is still good to know the ins and outs.
- Linking pl.exe Linking the executable, such that it exports systems and you can import them in your foreign libraries is now fairly easy, since gcc and binutils have full support to create DLLs on Cygwin for some time now.
If you just make a default build, you will get just a static
library libpl.a in $(prefix)/lib/pl-<version>/lib/i686-cygwin,
and the binaries are all linked statically against this library.
If you choose to configure with --enable-shared and after calling
"make install", you'll get a DLL, called cygpl.dll in
$(prefix)/lib/pl-<version>/bin/i686-cygwin, as well as a link
library libpl.dll.a in $(prefix)/lib/pl-<version>/lib/i686-cygwin.
This file is used for linking stand-alone embedded executables
and foreign libraries against the cygpl DLL.
* Creating a foreign library
This is a bit complicated, but luckily hidden from you. The
basic sequence is
gcc -shared -o mylib.dll <input files> -lpl ...
plus a couple of system libraries.
To make life a bit easier in your Makefiles, we've put this
in plld, so you can do on any platform for which plld is
aware of the proper sequence:
plld -shared -o mylib <input files>
If you use the -v option as in
plld -v -shared ...
you can see what system libraries are necessary when linking.
Or simply ask pl:
pl -dump-runtime-variables | grep PLLIBS
Mixing cygwin and native SWI-Prolog?
It's not possible to use foreign libraries built using the above Cygwin sequence on the native SWI-Prolog and visa versa. This is caused by native SWI-Prolog using MSVCRT*.lib, which is mutually exclusive with the Cygwin POSIX library.
