Open Watcom C/C++

Last modified: Sun Apr 26 14:15:11 EDT 2020

These are DWF's installation notes on Open Watcom C/C++ version 1.9, released in 2010.  The last update of the daily development snapshot sources occurred in 2015, but a fork is under active development.

Open Watcom can produce the full range of DOS executable types on either a DOS or Linux host, but its language implementations are a DOS-flavored dialect.


You will want one of these self-extracting archives that are available from

83945707  open-watcom-c-dos-1.9.exe
83959748  open-watcom-c-linux-1.9

You will also want DOS/32A version 9.1.2.


open-watcom-c-dos-1.9.exe offers to modify AUTOEXEC.BAT and CONFIG.SYS and drops a file called owsetenv.bat with examples for the environment variables.  open-watcom-c-linux-1.9 drops an analogous  Otherwise, a full installation unpacks the same files on a DOS or Linux host.  Alternately, the full archive can be extracted from the exe using Info-ZIP unzip.

Source code is also available from

Alternative binaries

The zip file that is included in the FreeDOS collection is the result of a selective installation that excludes documentation and support for non-DOS hosts and targets.

There is a fork calling itself version 2.0 on GitHub and SourceForge.  It is under active development.


The documentation that is linked on the Open Watcom web site is outdated, version 1.8.  Version 1.9 documentation is included in the self-extracting archives mentioned above.

A navigable text version of the documentation can be browsed with the Open Watcom Help program, WHELP.

The usage that is output by the tools themselves when run with no options or with -? disagrees with some details in the documentation.

Paul Hsieh's FAQ is a useful guide to the quirks of Watcom C/C++ (both the commercial and open versions).


Even if one is using Linux to host the compiler, the DOS binary for an extender or its associated stub is necessary to build 32-bit DOS programs.

The following files in directory binw belong to DOS/32A version 7.10 release 9, or version 7.2 (the markings are inconsistent):

 28,172  02-05-10 9:19a  DOS32A.EXE    Extender
  1,902  02-05-10 9:19a  LICENSE.D32   Documentation
 19,276  02-05-10 9:19a  README.D32    Documentation
 83,326  02-05-10 9:19a  SB.EXE        Protected Mode Bind Utility
 98,618  02-05-10 9:19a  SC.EXE        Protected Mode Compress Utility
108,280  02-05-10 9:19a  SD.EXE        Protected Mode Debugger
104,580  02-05-10 9:19a  SS.EXE        Protected Mode Setup Utility
    535  02-05-10 9:19a  STUB32A.EXE   Regular stub
    682  02-05-10 9:19a  STUB32C.EXE   Configurable stub
 20,914  02-05-10 9:19a  SVER.EXE      Version Report Utility

The distribution includes replacements for all except SD.EXE, the protected mode debugger that was abandoned in version 9.1.0.

Linux host setup

The Linux binaries are statically linked 32-bit ELF executables that run on any Linux with 32-bit support in the kernel.  The unpacked files can be put anywhere (e.g., /usr/local/ow-1.9), and then all you need are some environment variables:

# Open Watcom C/C++ 1.9
if [ -d /usr/local/ow-1.9 ]; then
  export WATCOM=/usr/local/ow-1.9
  # Need binw in PATH for wcl386 to find the DOS extenders and stubs.
  # Put binl at the front if you want Open Watcom vi instead of /usr/bin/vi.
  export PATH=${PATH}:${WATCOM}/binl:${WATCOM}/binw
  export DOS_INCLUDE=${WATCOM}/h
  export EDPATH=${WATCOM}/eddat    # For Open Watcom vi editor
  export WIPFC=${WATCOM}/wipfc     # For Open Watcom Help Compiler

DOS host setup

If using QEMU, start with the "basic DOS configuration" documented in QEMU config for running DOS compilers.

It is advisable to put the unpacked files in a directory with a short path that contains no spaces or long file names (e.g., the default location C:\WATCOM).

Additional lines for AUTOEXEC.BAT:


DOS/4GW replacement

The DOS binaries for the compiler are 32-bit LE executables prefixed by the DOS/4G Watcom stub.  This stub will load whichever DOS4G.EXE or DOS4GW.EXE extender is found first in its search path.  Unfortunately, the version that is included with the compiler distribution not only has a low limit on how much extended memory it will use, it also has a bug that can cause serious crashes and hangs if large amounts of memory are provided.

The following files in directory binw pertain to DOS/4GW version 1.97:

 21,490  02-05-10 9:19a  DOS4GW.DOC  Documentation
265,396  02-05-10 9:19a  DOS4GW.EXE  Extender
 99,336  02-05-10 2:19p  PMINFO.EXE  Protected Mode and Extended Memory Performance Measurement 5.00
 64,424  02-05-10 2:19p  RMINFO.EXE  DOS/16M Real Mode Information Program 5.00

Version 2.61 of DOS/4G is in circulation as copyright-encumbered abandonware, but it is probably better to substitute DOS/32A anyway.  After upgrading the DOS/32A binaries in binw, one can use the included bind utility to re-stub the compiler's executables:

FOR %f IN (bpatch.exe ctags.exe cvpack.exe ide2make.exe vi.exe wasaxp.exe wasm.exe wasppc.exe wbrg.exe wcc.exe wcc386.exe wd.exe wdis.exe whelp.exe wipfc.exe wlib.exe wlink.exe wmake.exe wpp.exe wpp386.exe wprof.exe wrc.exe) DO SB /RS %f

By default, the compiler will still prefix 32-bit binaries with the DOS/4GW stub (WSTUB.EXE).  This has to be avoided by specifying the correct target at build time.

The three faces of OW

There are essentially three different command-line interfaces to the compiler that use different syntax.  The first is the tools that actually generate code, which are documented in the C/C++ User's Guide (cguide.pdf):

The second is these wrappers that combine the compile and link steps.  They are documented instead in the C/C++ Tools User's Guide (tools.pdf):

The last is owcc, the "POSIX-like compiler driver," which is documented in the Tools Guide along with the previous two wrappers.  At first glance, owcc looks like a credible attempt to pass for gcc/g++.  Unfortunately, it ends up just being an obfuscation layer that you have to pound on to get the correct subcommands out of it.

Simplified usage and test

I have reduced the maze of possible options to four use cases.  The targeted arch is 80386 or higher CPU with support for 80387 floating point instructions.  Binaries are stripped and optimized for space.

16-bit COM (tiny memory model)

For simple apps that fit within 64 KiB.

wcl -3 -fpi87 -fp3 -os -d0 -mt -bt=dos -l=com


wcl -3 -fpi87 -fp3 -os -d0 -mt -bt=dos -fo=hello.obj -c
wcl -3 -fpi87 -fp3 -os -d0 -mt -l=com hello.obj

-rwxr-xr-x   1 dave users     9872 Apr 19 13:06

bash-4.3$ file DOS executable (COM)

Good morning, thou cruel world

16-bit EXE (huge memory model)

For apps that need between 64 KiB and 640 KiB.

wcl -3 -fpi87 -fp3 -os -d0 -mh -bt=dos -l=dos -fe=hello.exe


wcl -3 -fpi87 -fp3 -os -d0 -mh -bt=dos -fo=hello.obj -c
wcl -3 -fpi87 -fp3 -os -d0 -mh -l=dos -fe=hello.exe hello.obj

-rwxr-xr-x   1 dave users    24552 Apr 19 13:08 hello.exe

bash-4.3$ file hello.exe
hello.exe: MS-DOS executable

Good morning, thou cruel world

32-bit LX with DOS/32A standard stub (flat memory model)

For apps that need between 640 KiB and 4 GiB.

wcl386 -3 -fpi87 -fp3 -os -d0 -mf -bt=dos -l=stub32x -fe=hello.exe


wcl386 -3 -fpi87 -fp3 -os -d0 -mf -bt=dos -fo=hello.obj -c
wcl386 -3 -fpi87 -fp3 -os -d0 -mf -l=stub32x -fe=hello.exe hello.obj

-rwxr-xr-x   1 dave users    16956 Apr 19 13:09 hello.exe

bash-4.3$ file hello.exe
hello.exe: MS-DOS executable, LX for OS/2 (console) i80386

DOS/32A -- DOS Extender version 9.1.2
Copyright (C) 1996-2006 by Narech K.
Good morning, thou cruel world

32-bit Linux ELF

wcl386 -3 -fpi87 -fp3 -os -d0 -mf -bt=linux -l=linux -fe=hello


wcl386 -3 -fpi87 -fp3 -os -d0 -mf -bt=linux -fo=hello.o -c
wcl386 -3 -fpi87 -fp3 -os -d0 -mf -l=linux -fe=hello hello.o

-rwxr-xr-x   1 dave users    26279 Apr 19 13:10 hello

bash-4.3$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, not stripped

bash-4.3$ ./hello
Good morning, thou cruel world

If the host is DOS, the executable acquires an .ELF extension:

HELLO    CC            120  03-29-20  8:05p
HELLO    ELF        26,279  04-19-20  1:20p HELLO.ELF
HELLO    OBJ           549  04-19-20  1:20p HELLO.OBJ


The wcl[386] compiler option -bt merely chooses an operating system.  The documented choices are DOS, OS2, NT, QNX, LINUX, WINDOWS, and NETWARE.

The wcl[386] linker option -l, on the other hand, chooses one of many targets from the file binw/wlsystem.lnk that combine a grab-bag of interdependent factors:

The wcl[386] option -bcl and the owcc option -b are equivalent to specifying the same target to both -bt and -l.  This is useful only when the same name happens to identify the desired target for both (e.g., "dos", "linux").  owcc has no options to specify different targets to the compile and link stages, meaning that much of the time it is useless.

Various other compiler and linker options overlap with the choices made through -l:  calling convention is specified by the switches -3r, -3s, -4r, ..., -6s; application mode is specified with -bc, -bw, -bg, -bd; OS/2 protected-mode and DOS real-mode are chosen by -lp and -lr respectively; code generation for a Windows EXE is selected by -zw, -zW, -zWs.  I have only figured out what is sufficient for my four use cases.

Curiously, specifying a linker target where a compiler target is needed sometimes works and sometimes doesn't.  For example, owcc -b stub32a works on Linux:

bash-4.3$ owcc -v -b stub32a hello.c
        wcc386 hello.c  -bt=stub32a -fo=.o -fr
creating a DOS/32A DOS Extender w/ Standard stub (LE-style) executable

But on a DOS host, it invokes the 16-bit compiler and fails:

C:\TMP>owcc -v -b stub32a hello.c
        wcc HELLO.C  -bt=dos -fo=.o -fr
Warning! W1008: cannot open clibs.lib : file not found
Warning! W1008: cannot open math87s.lib : file not found
Warning! W1008: cannot open emu87.lib : file not found
Error! E2028: __STK is an undefined reference
Error! E2028: puts_ is an undefined reference
Error! E2028: _cstart_ is an undefined reference
Error! E2028: _small_code_ is an undefined reference
Error! E2028: __argc is an undefined reference
Warning! W1014: stack segment not found
Warning! W1023: no starting address found, using 0001:00000000
creating a DOS/32A DOS Extender w/ Standard stub (LE-style) executable
file HELLO.o(C:\TMP\HELLO.C): undefined symbol __STK
file HELLO.o(C:\TMP\HELLO.C): undefined symbol puts_
Error: Linker returned a bad status

Making libs

The Open Watcom analog of ar is wlib, the Open Watcom Library Manager.  It is documented in the Tools Guide.  There are options to specify different formats for the library produced.

wlib -n foobar.lib +foo.obj +bar.obj


Error! E1118: ***FATAL*** segment too large

The 16-bit compiler assumes that all of the functions from a given source file should fit into 64 KiB, even in the huge memory model.  If this isn't the case and you don't want to break the source file into smaller pieces, you can work around with the -zm compiler switch.

-zm  place functions in separate segments