Porting from Unix platforms
Introduction
This article will cover the basic steps for porting programs written for the Unix platform.
Only command line program will be covered, since porting the X window interface is a second step. If you are working on a GUI program, consider using the EverBlue Project or the WxWidgets (formerly WxWindows) project. Remind that the steps described here, probably still apply to your project.
System requirements
The most common enviroment used for porting Unix programs, is the EMX/GCC compiler&tools. It is based on gcc 2.8.1 and provides most of the required tools.
A new enviroment actually coming up, is the Innotek gcc compiler, based on gcc 3.2.2 for libc 0.5 level, on gcc 3.3.5 for the libc 0.6 release (currently in alpha test, soon in beta test). This is an enviroment currently in developement, but I consider it the preferrable way for starting.
To create an EMX basic enviroment you need to download the following files:
- Files required for developing programs with emx (part 1)
- Files required for developing programs with emx (part 2)
- The GNU C compiler, the GNU debugger, and other tools (part 1)
- The GNU C compiler, the GNU debugger, and other tools (part 2)
- Additional files for GCC required for compiling C++ programs
- libg++ 2.8.1.1a
- emxgnu.inf (emxgnu.doc in OS/2 .inf format)
- gnudiff.zip GNU diff v2.7.1 file differencer
- gnufutil.zip GNU file utilities v3.13
- gnugrep.zip GNU grep/egrep/fgrep 2.0
- gnututil.zip GNU text utilities v1.19
- gnupatch.zip GNU patch v2.5
- GNU Make 3.81rc2
- A shell (e.g. pdksh)
- GNU awk 3.0.6
- GNU sed 3.0.2
- GNU tar
- gzip 1.2.4
For an advanced enviroment, you need also:
- GNU Automake
- GNU Autoconf
- GNU M4 command processor
For using Innotek gcc (recommended), get also:
Get the above packages and install following the included instructions. I will add a scheme here sometimes. Since you can use GNU utilities with different enviroments, I suggest to put EMX core files into a different directory tree. So you can use the utilities and other tools with Innotek gcc without too much trouble.
Install compilers and tools in the same drive of your projects: this will make your like easier, since unix doesn't know about drive letters and most makefiles/scripts specify root as starting point (e.g. /bin/sh). So having different drive letters could require some effort in editing scripts or makefiles.
Getting the source code
First step is to get the program source code. I can't tell you where to find it, but SourgeForge is a good place for starting :-)
Usually source code comes as a 'tarball': that means all files are packed into a single file with tar (extension .tar) and most of the times also compressed (extension .tar.gz).
Untar the tarball with 'tar xzf place_here_my_tar.gz' and you will get all the sources extracted into a subdirectory (usually a tar file doesn't write files to the current directory).
If someone worked on the same program in the past, you can review the old work and use the old patches with your version. Keep in mind that old patches cannot always be applied to current source code, so a manual review is better in such cases.
Configuring the scripts
Since Unix is not a single platform, but has a wide range of choices (like Linux, various *BSD, Solaris, AIX, ...), most unix programs are coming with a so-called 'configure' script. This is a shell script that must be run to recognize the current system configuration, so the correct compiler switches, libraries path and tools will be used.
When configure is missing, you should modify makefile to add OS/2 specific changes.
The configure script is usually a very long script, and it takes really long to execute. When this script is created from recent autoconf releases (2.57 and later), it will work under OS/2 with minor (or nothing at all) modifications. Run it with
sh -c ./configure
Since default switches are not always optimal for the OS/2 enviroment, I use a customized startup script named configure.os2:
#! /bin/sh CFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \ CXXFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \ LDFLAGS="-s -Zmap -Zhigh-mem -Zomf -Zexe" \ LN_CP_F="cp.exe" \ RANLIB="echo" \ AR="emxomfar" \ ./configure --with-libdb-prefix=e:/usr/local/berkeleydb.4.2 --prefix=/usr/local/bogofilter
I place this script in the same directory of configure, so I run it with
sh -c ./configure.os2
My personal script will setup my preferred makefile parameters, tell which libraries link (like socket library), where to place installed binaries (--prefix) or where to find optional libraries (--with-berkeley-db).
A good way to execute scripts makes use of a config.site file: this script is automatically executed before configure, and it will adjust some variables for proper script parsing.
# This file is part of UnixOS/2. It is used by every autoconf generated # configure script if you set CONFIG_SITE=%UNIXROOT%/etc/unixos2/config.site. # You can add your own cache variables at the end of this file. # echo "Loading UnixOS/2 config.site" # LIBS="-lsocket" # # Executables end on ".exe". You may add other executable extensions. # Supported since autoconf 2.53 (?). test -n "$ac_executable_extensions" || ac_executable_extensions=".exe" # # Replace all '\' by '/' in your PATH environment variable ux2_save_IFS="$IFS" IFS="\\" ux2_temp_PATH= for ux2_temp_dir in $PATH; do IFS="$ux2_save_IFS" if test -z "$ux2_temp_PATH"; then ux2_temp_PATH="$ux2_temp_dir" else ux2_temp_PATH="$ux2_temp_PATH/$ux2_temp_dir" fi done export PATH="$ux2_temp_PATH" unset ux2_temp_PATH unset ux2_temp_dir unset ux2_save_IFS
You can place this file into \emx\share and add SET CONFIG_SITE=x:\emx\share\config.site to your enviroment setup command file.
There are at least two causes able to stop your running script: the required files are too old or you are missing some tools or libraries.
Required files are too old
Your scripts are too old to execute properly under OS/2, or they don't recognize OS/2 as a possible target. You need to replace config.sub, config.guess, mkinstalldirs with more recent versions (I get them from my other projects, so I can't suggest where to get them).
The configure script has been generated with an older autoconf/automake release: you must rebuild the script using autoconf and/or automake. In the same configure directory there is a file named configure.in: this is the input script for autoconf; autoconf will read the .in file and write a new configure file. The new file is supposed to execute better, so this doesn't means it will complete the required steps. Run
sh -c ./autoconf
in your current directory to rebuild.
Once autoconf completes his task, compare the new script with the old one: most of the times the new script is slightly longer (because of new stuffs); so if your new script is really shorter, that means you missed something during the build. In my experience, this is related to missing .m4 files or a different run command (e.g. Berkeley DB requires to run the s_conf script to properly rebuild configure).
You are missing something
Here the range of problems is quite wide: from 'unable to find a compiler' to 'you don't have xxx installed'.
When configure can't find your compiler, probably you need to update the files (see above), and the script will stop running almost at initial steps. This can be related to conflicting switches in configure.os2 (if used) like -Zomf.
When you don't have something installed, the solution can be different: if it turns out that you need another package to compile, like Berkeley DB, search for it, download and start porting it. Once you got the required files installed, go back to your main project. Most of the times, the required libraries are already existing for OS/2, so it is only a matter to download them, place somewhere and tell configure the correct path for them (like --with-berkeley-db above).
The best way to discover problems, is to check the config.log file: every check done by configure is logged into this file; look near the end of the file or search text using the failing test as key. Maybe the check failed because of wrong library order: libraries must be specified in the correct order, since every missing function is searched in the next library; e.g. syslog library must be placed before socket library (-lsyslog -lsocket).
Under EMX, it may happen that some compiler flags are incompatible with configure: I found -Zomf to conflict in some cases.
If you still get problems, consider rebuilding the configure script.
As I wrote, script execution is really long: for every needed tool, header, function or library the script will execute the compiler to verify its presence. This is a compile/link/execute sequence for every test.
Once completed, the configure script will write a config.status file; this is a shell script used to update all project files: makefiles at least, but also a config.h can be written (this header is supposed to contain constants for existing and non-existing functions in your enviroment), or dependent files can be created.