Skip to content

Using OpenWatcom C with ELKS

Takahiro Yamada edited this page Jul 19, 2024 · 4 revisions

ELKS supports using the OpenWatcom C toolchain for creating and executing programs in small, medium, compact and large models. When compact or large models are built, ELKS supports the loading of multiple code and data segments, with a current adjustable default limit of five segments, allowing programs of 320k+ size to run.

In order to build programs using Watcom C, first either install OpenWatcom C v2 or clone the repo from https://github.com/open-watcom/open-watcom-v2.

The following are instructions to build OpenWatcom C on macOS (Linux not tested). Only two small changes are required, realpath doesn't exist on macOS and dosbox is required for the build. Here's the diff:

diff --git a/setvars.sh b/setvars.sh
index 81a0614a68..c822246db9 100755
--- a/setvars.sh
+++ b/setvars.sh
@@ -16,7 +16,7 @@
 # export "OWROOT=/home/ow/o w"
 #
 
-export OWROOT=$(realpath "`pwd`")
+export OWROOT=$(pwd)
 
 # Set OWTOOLS entry to identify your toolchain used by build process
 # supported values are WATCOM GCC CLANG
@@ -71,7 +71,7 @@ export OWDISTRBUILD=0
 # if DOSBOX emulator is used then OWDOSBOX variable must be set
 # Uncoment and set OWDOSBOX variable bellow to point to DOSBOX emulator executable
 
-# export OWDOSBOX=dosbox
+export OWDOSBOX=/Users/greg/net/elks-gh/dosbox-x-sdl2
 
 # Windows documentation build process requires Microsoft Help Compilers which can
 # work only on Windows host therefore by default this build is disabled on non-Windows

Running ./build.sh rel built the entire system, which then was copied into open-watcom-v2/rel/bino64.

After building or installing OpenWatcom, the WATCOM and WATDIR environment variables need to be setup by sourcing a script like the following with the full path to the OpenWatcom binary directory (WATCOM) and top-level directory (WATDIR). This is available in ELKS libc/wcenv.sh and executed via cd libc; . ./wcenv.sh. The WATDIR= line will need to be modified to the top directory of the OpenWatcom repository:
If OpenWatcom is installed from the installer to linux and the repository is not available,
then the WATDIR can be /bin/watcom and the WATCOM can be WATDIR/binl64.
Also, you may need to modify
INCLUDES += -I$(WATDIR)/bld/hdr/dos/h to
INCLUDES += -I$(WATDIR)/h
in elks/libc/watcom.inc

#!/usr/bin/env bash

# Set up Watcom build environment

export WATDIR=/Users/greg/net/open-watcom-v2
export WATCOM=$WATDIR/rel/bino64   # for macOS
#export WATCOM=$WATDIR/rel/binl    # for Linux-32
#export WATCOM=$WATDIR/rel/binl64  # for Linux-64

add_path () {
	if [[ ":$PATH:" != *":$1:"* ]]; then
		export PATH="$1:$PATH"
	fi
}

add_path "$WATCOM"

echo PATH set to $PATH

After that, the ELKS C library needs to be built using OpenWatcom. The default compilation model is large, but can be changed by editing the file elks/libc/watcom.model:

cd $TOPDIR            # ELKS top-level directory
cd libc
make -f watcom.mk     # creates elks/libc/libc.lib, used by `ewlink`

ELKS provides two scripts to more easily compile and link programs with OpenWatcom C. These are ewcc and ewlink - simple scripts to compile a single .c file for each file in a project, and then link them into a final executable. The executable format created is technically an OS/2 v1.x 16-bit binary; ELKS has the ability to natively load and execute these binaries. For the time being, the extension of OS/2-formatted binaries is ".os2".

The source for these scripts is in elks/tools/objtools/ewcc and ewlink.
If OpenWatcom is installed from the installer to linux,
you may need to modify
WATCINCLUDE=$WATDIR/bld/hdr/dos/h to
WATCINCLUE=$WATDIR/h
in the ewcc.

For a tested example, the following will build ELKS basic from scratch using OpenWatcom:

. ./wcenv.sh
cd $TOPDIR/libc
make -f watcom.mk clean
make -f watcom.mk            # produces $TOPDIR/libc/libc.lib, required for ewlink
cd $TOPDIR/elkscmd/basic
ewcc basic.c
ewcc host.c
ewcc host-stubs.c
ewlink basic.obj host.obj host-stubs.obj    # creates basic.os2
# optionally convert to ELKS a.out format (no longer needed)
#os2toelks -f elks -o basic basic.os2
cp basic.os2 $TOPDIR/elkscmd/rootfs_template/root

... then, in ELKS:

# ./basic.os2

Of course, the .os2 extension may be renamed or removed if desired, but is currently left on to differentiate OS/2 and ELKS a.out binaries. The file command can also be used to determine the type of executable, if desired.