TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Byron Desnoyers
from: Ronald Van Iwaarden
date: 1995-04-15 09:37:30
subject: Borland and EMX ...

Byron Desnoyers said to All:

 BD> I am currently using Borland C/C++ v3.1 to compile my DOS
 BD> programs and EMX v0.9a to compile my OS/2 programs, but I
 BD> noticed a few peculiarities which I would like to have
 BD> cleared up.

 BD> First of all, the EMX program is well over 3 times larger
 BD> than the Borland version - and it is the *exact* same code. 
 BD> Is this due to the compiler or do OS/2 programs naturally
 BD> take up more room?

There could be many reasons, the biggest of which is all the debugging code
and not using optimization. I have a program that is 561k in the
development form and 167k in the release version.  Here is an article that
I read on the internet mailing list that has been very helpful to me:

/*> Begin included article */

From schwabe{at}rzaix530.rz.uni-leipzig.deMon Jan  9 13:16:07 1995
Date: Sun, 25 Dec 94 15:47:45 +0100
From: Johannes Schwabe 
Reply to: emx-list{at}eb.ele.tue.nl
To: Multiple recipients of list 
Subject: SmallOS2EXEswithEMX

 TIPS FOR MAKING OS/2 EXECUTABLES VERY SMALL
 [OS/2 specific -- not very useful for DOS users]

For some time, I had "fun" making OS/2 programs very small just
by recompiling
them with emx and a few tricks. emx is an unixoid environment for OS/2 and
DOS, but these tricks work only under OS/2. [A sentence with DOS bashing was
deleted] The tricks work with 0.8h (I haven't access to 0.9 yet) but should
work also with newer versions. They work with OS/2 2.x and should dito.
So my hope is that this info might be useful for developers and porters, thus
for all OS/2 users, they can need it with an OS/2 of 40M on their disk...
The "tricks" work especially good for little programs (tools,
filters). Just
compare a generated hello-world.exe with other exes! (Applicable to dlls also)

 - Use emxlibc.dll (or the replacements in 0.9a, emxlibcs.dll or emxlibcm.dll;
   see emx docfiles). The runtime library will not waste space in your
   program. If you link statically, only the runtime routines you need will
   be included in the executables; but a single printf seems to be very big.
   The problem with using the dlls is that the user of your program needs
   these dlls. But there are clearly advantages, and the DLLs seem to become
   an OS/2 standard for serious users. (They are freely distributable.) In
   version 0.8h, you can use the dlls with -Zomf -Zmtd (note that you must
   compile all object files with -Zomf -Zmtd, and don't forget to set
   errno=0; at the begin of your program when using the multi-threaded
   library). In 0.9, I don't know.
   Of course, a program /and/ the DLLs are together bigger than a statically
   linked program. But you usually have a few /ten/ emx programs. I prefer
   including NONE of the DLLs in a distribution archive, and to tell the
   user "emx dlls 0.xy or bigger required".
   The use of the DLL library is STRONGLY recommended for DLLs (otherwise,
   you will run into DLLs with their own printf linked in!). However, I am
   not sure under which conditions programs which don't use emxlibc*.dll can
   use DLLs which use emxlibc*.dll. Let all modules use emxlibc*.dll and you
   won't have this problem. However, a program using emxlibc*.dll seems to
   be able to use a DLL with other runtime (big overhead, but worked).
 - Use a module definition file (.def), see emx doc. I would propose the
   following typical one:
    NAME foo WINDOWCOMPAT   <---- or WINDOWAPI if PM program
                            <---- if no name (3 bytes!) use NAME '' WINDOW...
    STACKSIZE 20000         <---- don't know how big stack for 0.9 required
    STUB NONE               <---- compile without DOS trash header [*]
    BASE=0x10000            <---- to bind on 64K address (good only for EXEs)
                            <---- special DLL options might be required
   The BASE option is especially good. OS/2 LX EXEs are ALWAYS loaded at
   [virtual] 0x10000 (64K), thus they do not need any relocation info!
   [*] WARNING: If you want to include resources with RC (the OS/2 resource
   compiler), you can't use STUB NONE because RC breaks when it can't read
   a MZ stub. This is only a problem for PM programs.
   !!  WARNING: You have to include a WARNING in the doc files. If any user
       attempts to run an LX-EXE without MZ stub under DOS or in the DOSbox,
       the DOS will crash (the file is loaded as COMfile). Such EXEs should
       not be placed into a directory in the DOS path. DLLs, however, are
       no problem
 - Tell LINK386 to use suitable values. The arguments to LINK386 are:
    /alignment:4 /f /w /exepack /packcode /packdata
   I do not know whether all of them make sense, but they don't harm.
   Especially the /alignment:4 option prevents LINK386 from choosing the
   default, which is 512, and from putting many zeros into your exe file. Even
   IBM recommends to use /align:4 for 32-bit-progs, but the default is never-
   theless 512...
   Running the linker manually isn't left as an exercise for beginners. :-)
   gcc calls LINK386 if you use OS/2 linking. You can hardly pass parameters
   to LINK386 this way. But a good way exists: Put these options into the
   environment variable LINK386:
    SET LINK386=/alignment:4 /exepack /packcode /packdata /f /w
   before running gcc.
 - Use highest optimization for gcc: e.g.
    -O2 -fomit-frame-pointer -s
   (-s for stripping the symbol table !!!)
 - If you have a module which doesn't use the emx runtime library at all
   (seldom case, but applies for some PM programs or DLLs), you should not
   use the library. It is relativly complicated. I once did it.
   Look into the emx docs. Note that you won't
   even have command line parameters without the emx startup!! (You can get
   them the same way as the emx startup does, but it is not as easy as argc
   and argv). I think you compile the modules to .objs, and the main module
   to .o and then process with emxomf (for startup point). (Not totally sure)
   You won't have to run the linker manually, you can use gcc -nostdlib.
 - If you have a DLL with many functions, and you don't want to have the
   name table included in the DLL, use NONAME statements in the .def file.
   The function can not be called via runtime name import, then, because it
   has no name. The usual import works 'linktime - number'. If a function
   has no name, it can be called from every C program, but not from programs
   which import them by name (REXX, I believe, and some PM mechanisms).
 - If using RC, use option '-x' to pack resources.
 - If you develop a library for programs, put this library into a DLL.
 - a performance hint. Read-only tables (strings, as
   an example) should be declared as 'const'. Example:
    const BigString[] = "Just some internal tables or trash\
                              .
                              .";
   'const' variables will be stored in the 'text' (code) segment. The code
   segment is R/O, thus it needs not be written into the swap file (can be
   reloaded from the original .exe).

You may want to use makefiles. For programs which are not from me and which
come with makefiles for CSet or sth like this, I use a batch program which
automagically does the work for me.
Programmers should include C sources to allow recompiling with better compilers
or porting to other environment (e.g., PowerPC with OS/2).

Some examples:
 - the 'winback' program: less than 3K now (and does not need emx-dlls)
 - PC/2 1.30 (written by Roman Stangl) at about 30K
 - sysptr (PM program for altering mouse pointers and icons): 4K
    (was written by E.Demarin: mccoy{at}maya.dei.unipd.it)
 - unarj: 11K
 - 'showriff' program from c't [the german computer magazine]: <2K
If the doc file is bigger than the program, you are about the right way!!

Note that the program will 'expand' in memory (since memory is paged, and
a typical emx program contains at least 5 pages).

Happy module squeezing,
 - Johannes -

/*>  End included article  */


 BD> However, when I run the program for DOS, by typing "PORTDOS"
 BD> it will return the command line as ...
 BD> "G:\PROGRAM\PORTDOS.EXE"
 BD> Yet the OS/2 program (run by typing "PORTOS2") will return
 BD> it as ... "PORTOS2"

 BD> Although I get what I expect from EMX, I do prefer what the
 BD> DOS version returns.  At any rate, is there anyway to change
 BD> them so that they are both the same?

Hmmm.  Not sure.  I think the argv[0] value depends on whether or not you
run the program from the same directory.  That is, if g:\program was in the
path and I typed portdos.exe from c:\, then I think arg[0] would be
g:\program\portdos.exe as you would like.

TTYL,

=--Ron  TeamOS2

Fidonet:  Ronald Van Iwaarden 1:104/338{at}fidonet.org
OS2net:   Ronald Van Iwaarden 81:313/1{at}os2net.ftn
Internet: rvaniwaa{at}carbon.denver.colorado.edu
--- timEd/2-B9
* Origin: The OS/2 Source BBS [303]744-0373 (1:104/338)
SEEN-BY: 105/42 620/243 711/401 409 410 413 430 807 808 809 934 955 712/407
SEEN-BY: 712/515 628 704 713/888 800/1 7877/2809
@PATH: 104/338 730 1 3615/50 396/1 270/101 105/103 42 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.