Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to index page
Thread view  Board view
roytam

11.01.2013, 06:52
 

how to create small DJGPP binaries? (Developers)

Hi all,

Besides compressing with UPX, how can I create smaller DJGPP binaries?
or say, which DJGPP gcc creates smaller binaries? any compiler switches can reduce binary size without performance impact?
Can OpenWatcom C drop-in replacing DJGPP gcc here?

Regards,
Roy

RayeR

Homepage

CZ,
11.01.2013, 10:56

@ roytam
 

how to create small DJGPP binaries?

> Besides compressing with UPX, how can I create smaller DJGPP binaries?
> or say, which DJGPP gcc creates smaller binaries? any compiler switches can
> reduce binary size without performance impact?
> Can OpenWatcom C drop-in replacing DJGPP gcc here?

There's not much to do, you can revert to older versions of DJDEV and GCC as newer makes bigger code. I observed that during time the compressed size of simple exe growed about 15kB from old gcc 3.x to latest 4.7.2. It's not so much. You can save some space using CRT flags to disable some functions like command line processing - if you dont need e.g. wildcards expansion, environment... this can save some kB. Also you can implement your own better libc. Small command line utils I wrote are usually 50-60kB after compression, one complex tool about 100kB, not bad for me...

---
DOS gives me freedom to unlimited HW access.

roytam

12.01.2013, 14:27

@ RayeR
 

how to create small DJGPP binaries?

> > Besides compressing with UPX, how can I create smaller DJGPP binaries?
> > or say, which DJGPP gcc creates smaller binaries? any compiler switches
> can
> > reduce binary size without performance impact?
> > Can OpenWatcom C drop-in replacing DJGPP gcc here?
>
> There's not much to do, you can revert to older versions of DJDEV and GCC
> as newer makes bigger code. I observed that during time the compressed size
> of simple exe growed about 15kB from old gcc 3.x to latest 4.7.2. It's not
> so much. You can save some space using CRT flags to disable some functions
> like command line processing - if you dont need e.g. wildcards expansion,
> environment... this can save some kB. Also you can implement your own
> better libc. Small command line utils I wrote are usually 50-60kB after
> compression, one complex tool about 100kB, not bad for me...

hmm.
with old gcc 2.7.2.3, it does reduce a bit.

the final product, lha for Unix 1.14i-ac compiled and compressed and D3X-stubbed:
http://roy.orz.hm/soft/lha_d3x.exe 84,976 bytes

BTW I made D3X with apack compressed stubs working by accident! When I'm debugging why compressed stub not working by adding debug instructions in exitErr, it works compressed! so d3xd(the coff stub) is now 7KB! Sources and binary here:
http://roy.orz.hm/soft/d3x090h-apack.7z

D3X-apack-stubbed:
http://roy.orz.hm/soft/lha_d3x_.exe 81,904 bytes

Laaca

Homepage

Czech republic,
11.01.2013, 16:18

@ roytam
 

how to create small DJGPP binaries?

In czech diskmag got out many years ago an article about it.
Use the Google traslator for it:
http://nuane.com/vyhen/09/crt0.html

---
DOS-u-akbar!

RayeR

Homepage

CZ,
11.01.2013, 19:26

@ Laaca
 

how to create small DJGPP binaries?

> In czech diskmag got out many years ago an article about it.
> Use the Google traslator for it:
> http://nuane.com/vyhen/09/crt0.html

Vyhen, hell yeah, I remember well that ancient times when dowloading it from BBS via modem (no free internet yet), it took long time :)

---
DOS gives me freedom to unlimited HW access.

georgpotthast

Homepage

Germany,
11.01.2013, 22:27

@ RayeR
 

how to create small DJGPP binaries?

There is a page on the djgpp site that describes how to make the executables smaller:

http://www.delorie.com/djgpp/v2faq/faq8_14.html

Georg

Arjay

12.01.2013, 12:43

@ georgpotthast
 

how to create small DJGPP binaries?

> There is a page on the djgpp site that describes how to make the
> executables smaller:
> http://www.delorie.com/djgpp/v2faq/faq8_14.html
The first answer explains that debugging information is included by default.
(It is not recommended to strip the symbols except when distributing production programs, because this makes debugging very hard indeed; that is why -s is not passed to gcc by default.)

Why? I'm sorry DJ, but I fail to see why that is a good idea due to human nature in the sense that humans are on the whole fairly lazy. Personally I think it is better to EXCLUDE unnecessary data unless needed. Another good example are Excel files, 3 worksheets are created by default. Why? If you deleted the unnecessary worksheets the files are a lot smaller. Sometimes I wonder if there are shares being handed out by disk drive companies to well known software people to help ensure the storage of more empty space. Excel 95/97 (can't remember which) if you created a brand new blank file and then went to the very last cell on a pressed space then pressed backspace then save, you ended up with a huge spreadsheet as it saved "lots" of empty space.

RayeR

Homepage

CZ,
12.01.2013, 21:35

@ Arjay
 

how to create small DJGPP binaries?

> Why? I'm sorry DJ, but I fail to see why that is a good idea due to human
> nature in the sense that humans are on the whole fairly lazy. Personally I

Humans are lazy, they rather buy a bigger HDD instead of bothering file sizes :)
And HDD manufacturers enjoy theirs $ :)

---
DOS gives me freedom to unlimited HW access.

marcov

14.01.2013, 09:48

@ Arjay
 

how to create small DJGPP binaries?

> I'm sorry DJ, but I fail to see why that is a good idea due to human
> nature in the sense that humans are on the whole fairly lazy.

Humans are also quick to try to put the blame for own stupidity somewhere else :-)

> Personally I
> think it is better to EXCLUDE unnecessary data unless needed.

During development you do more builds than for final delivery. So in most cases it is potentially needed.

> Another good
> example are Excel files, 3 worksheets are created by default. Why?

Originally I assume to show the possibility. But that is IMHO a different matter.

> If you
> deleted the unnecessary worksheets the files are a lot smaller. Sometimes
> I wonder if there are shares being handed out by disk drive companies to
> well known software people to help ensure the storage of more empty space.

Yeah, all that spaced wasted together might even be 50 MB. That means 1/60000 of a modern HDD (3TB/50MB) wasted. I would buy stock if I were you, this is golden business :-)

Rugxulo

Homepage

Usono,
13.01.2013, 21:25

@ roytam
 

how to create small DJGPP binaries?

This is a discussion that could go on forever. Unfortunately, most people aren't interested, hence the difficulty in discovering good answers (sigh). Honestly, I wouldn't worry too too hard about it unless you're just super obsessed! ;-) BTW, OpenWatcom can indeed make smaller (esp. 16-bit) binaries, but it depends on what you're trying to do, how standard (C89, C99) you need support and how much OpenWatcom supports (esp. libc).

Here's just some rough ideas off the top of my head:

* check linker map (mkdir() function pulling in ctime.o without reason?)
* recompile (parts of) libs with -Os or -O1 ("ar rvs libblah.a smaller.o")
* recompile (parts of) libs with stripped functionality or hand-written assembly
* avoid printf (and related) in lieu of _dos_write (etc.)
* use empty cmdline glob function
* 2.03p2 (no true symlink support in libc)
* strip ("gcc -s" or "ld -s" or "strip blah.exe")
* compare various (-O1 or -Os or -O2) with UPX --ultra-brute --small
* -fomit-frame-pointer
* -fno-align-functions, -fno-align-labels, -fno-align-loops, -fno-align-jumps
* -march=i386, -march=i486, -march=i586
* don't bind DPMI host, use default 2 kb stub, leave CWSDPMI separate

roytam

14.01.2013, 04:52

@ Rugxulo
 

how to create small DJGPP binaries?

> This is a discussion that could go on forever. Unfortunately, most people
> aren't interested, hence the difficulty in discovering good answers (sigh).
> Honestly, I wouldn't worry too too hard about it unless you're just super
> obsessed! ;-) BTW, OpenWatcom can indeed make smaller (esp. 16-bit)
> binaries, but it depends on what you're trying to do, how standard (C89,
> C99) you need support and how much OpenWatcom supports (esp. libc).
>
> Here's just some rough ideas off the top of my head:
>
> * check linker map (mkdir() function pulling in ctime.o without reason?)
> * recompile (parts of) libs with -Os or -O1 ("ar rvs libblah.a smaller.o")
> * recompile (parts of) libs with stripped functionality or hand-written
> assembly
> * avoid printf (and related) in lieu of _dos_write (etc.)
> * use empty cmdline glob function
> * 2.03p2 (no true symlink support in libc)
> * strip ("gcc -s" or "ld -s" or "strip blah.exe")
> * compare various (-O1 or -Os or -O2) with UPX --ultra-brute --small
> * -fomit-frame-pointer
> * -fno-align-functions, -fno-align-labels, -fno-align-loops,
> -fno-align-jumps
> * -march=i386, -march=i486, -march=i586
> * don't bind DPMI host, use default 2 kb stub, leave CWSDPMI separate

How many of these you did in your djgpp203.7z?

Rugxulo

Homepage

Usono,
14.01.2013, 15:30

@ roytam
 

how to create small DJGPP binaries?

>
> How many of these you did in your djgpp203.7z?

Unfortunately, not many, due to time, complexities, or whatever. I mostly just recompiled everything with 2.03p2 with -march=i386 -O1 (or -Os) and let 7-Zip (solid LZMA compression) do the rest. I tried to keep it as sane, "modern", and stock (unmodified) but useful as possible. Despite nobody appreciating it but me, I still consider it a successful package, esp. for fitting (compressed) on one floppy (and unpacking on very low RAM machines).

> > * check linker map (mkdir() function pulling in ctime.o without reason?)

I noticed this with 7zdecode, when 9.x added subdir extraction via 'x', it bloated 10 kb. mkdir() accidentally was pulling in filetimestamp(). But nobody else really cared, so I never submitted a "perfect" patch for 2.03p2 or 2.04 or CVS trunk.

> > * recompile (parts of) libs with -Os or -O1 ("ar rvs libblah.a
> smaller.o")

Last I heard, some of it was using -O2, some -Os, etc. I never bothered looking too closely. I'm sure it could be more fine-grained, in smaller pieces, esp. since the linker isn't "smart", but I didn't see any obvious place to slim it down, at least nothing worth immediately doing. Again, check the linker map, it should show you the biggest pieces. But most of it doesn't really use exorbitant amounts or anything. Sure, it's not nearly as small as raw assembly, but you can't have everything.

EDIT: --gc-sections doesn't work on COFF.

> > * recompile (parts of) libs with stripped functionality or hand-written
> > assembly

If you don't need floating point support in printf(), you can shave off about 2 kb from _doscan().

> > * avoid printf (and related) in lieu of _dos_write (etc.)

Better to avoid printf() altogether if you don't majorly need it. Though I think OpenWatcom is slightly worse about this than DJGPP.

> > * use empty cmdline glob function

See djgpp203.7z's tiny.c, but it's rarely useful (and only saves about 6 kb). This is really only meant to mimic *nix shell default globbing.

> > * 2.03p2 (no true symlink support in libc)

I almost always prefer 2.04 for various (mostly unnecessary) reasons, even though it's bigger. But it does have better symlink support, which does bloat things up a bit more. If you don't need it, don't use it. At least recompiling UNZIP with 2.04 was worth it (to me) for that, though.

> > * strip ("gcc -s" or "ld -s" or "strip blah.exe")

gcc.exe is just a compiler driver, it doesn't actually do much anyways. cc1.exe is the real compiler proper. So "gcc -s" really is just "ld -s", which does strip. Hence I don't include separate strip.exe in djgpp203.7z because you don't need it!

The best way to save space is to not include what you don't need. :-)

> > * compare various (-O1 or -Os or -O2) with UPX --ultra-brute --small

--small is undocumented (IIRC) and doesn't save barely 1 kb (I think??). But yeah, sometimes -O1 is smaller after UPX, but sometimes -Os is instead. (BTW, GCC 2.7.2.x didn't have -Os, only -O2.)

> > * -fomit-frame-pointer

Normally this doesn't help and makes it slightly larger, but sometimes it's still good to compare with and without.

> > * -fno-align-functions, -fno-align-labels, -fno-align-loops,
> > -fno-align-jumps

These don't save much, so usually I don't bother. But perhaps that last little crumb of space can be saved here.

> > * -march=i386, -march=i486, -march=i586

I'm not 100% sure if these would save anything. 386 should be best, but maybe not. I know 486 was just extra alignment, so avoid that, but who knows how small it is "after" UPX.

> > * don't bind DPMI host, use default 2 kb stub, leave CWSDPMI separate

You don't (usually) need ten bazillion DPMI hosts bound to every single .EXE, so you can obviously save space by having it separate (and letting the default stub call it). While D3X is fairly good, CWSDPMI is slightly better in some ways (including the licensing, which I hate arguing about, but ...).

roytam

28.10.2021, 16:03

@ Rugxulo
 

how to create small DJGPP binaries?

> This is a discussion that could go on forever. Unfortunately, most people
> aren't interested, hence the difficulty in discovering good answers (sigh).
> Honestly, I wouldn't worry too too hard about it unless you're just super
> obsessed! ;-) BTW, OpenWatcom can indeed make smaller (esp. 16-bit)
> binaries, but it depends on what you're trying to do, how standard (C89,
> C99) you need support and how much OpenWatcom supports (esp. libc).
>
> Here's just some rough ideas off the top of my head:
>
> * check linker map (mkdir() function pulling in ctime.o without reason?)
> * recompile (parts of) libs with -Os or -O1 ("ar rvs libblah.a smaller.o")
> * recompile (parts of) libs with stripped functionality or hand-written
> assembly
> * avoid printf (and related) in lieu of _dos_write (etc.)
> * use empty cmdline glob function
> * 2.03p2 (no true symlink support in libc)
> * strip ("gcc -s" or "ld -s" or "strip blah.exe")
> * compare various (-O1 or -Os or -O2) with UPX --ultra-brute --small
> * -fomit-frame-pointer
> * -fno-align-functions, -fno-align-labels, -fno-align-loops,
> -fno-align-jumps
> * -march=i386, -march=i486, -march=i586
> * don't bind DPMI host, use default 2 kb stub, leave CWSDPMI separate

sorry for bumping, but since there is some years after this reply and I wonder if anything is changed in DJGPP 2.05.
and newer bash-4.1 seems working better.

kerravon

Ligao, Free World North,
28.10.2021, 21:45

@ roytam
 

how to create small DJGPP binaries?

> sorry for bumping, but since there is some years after this reply and I
> wonder if anything is changed in DJGPP 2.05.
> and newer bash-4.1 seems working better.

I don't know if you need DJGPP in particular, but
note that if you use HX, which supports DLLs, and
you use the MSVCRT.DLL provided by PDPCLIB for the
C library, and you use gccwin.exe or equivalent as
your C compiler, you can have a "hello world" of
about 3K.

BFN. Paul.

roytam

29.10.2021, 14:38

@ kerravon
 

how to create small DJGPP binaries?

> > sorry for bumping, but since there is some years after this reply and I
> > wonder if anything is changed in DJGPP 2.05.
> > and newer bash-4.1 seems working better.
>
> I don't know if you need DJGPP in particular, but
> note that if you use HX, which supports DLLs, and
> you use the MSVCRT.DLL provided by PDPCLIB for the
> C library, and you use gccwin.exe or equivalent as
> your C compiler, you can have a "hello world" of
> about 3K.
>
> BFN. Paul.

HX runtime is lot bigger than DPMI client alone.

kerravon

Ligao, Free World North,
29.10.2021, 15:54

@ roytam
 

how to create small DJGPP binaries?

> > > sorry for bumping, but since there is some years after this reply and
> I
> > > wonder if anything is changed in DJGPP 2.05.
> > > and newer bash-4.1 seems working better.
> >
> > I don't know if you need DJGPP in particular, but
> > note that if you use HX, which supports DLLs, and
> > you use the MSVCRT.DLL provided by PDPCLIB for the
> > C library, and you use gccwin.exe or equivalent as
> > your C compiler, you can have a "hello world" of
> > about 3K.
>
> HX runtime is lot bigger than DPMI client alone.

Sure, but it has the upside that your programs
will run under Windows (all versions since Win 95)
also.

What is your actual environment where you care
about the size of the HX runtime?

BFN. Paul.

tkchia

Homepage

30.10.2021, 07:29

@ kerravon
 

how to create small DJGPP binaries?

Hello kerravon, hello roytam,

> > HX runtime is lot bigger than DPMI client alone.
> Sure, but it has the upside that your programs
> will run under Windows (all versions since Win 95)
> also.

The problem at hand is how to get a small program that can run under MS-DOS.

Thank you!

---
https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI"

Rugxulo

Homepage

Usono,
01.11.2021, 14:03

@ roytam
 

how to create small DJGPP binaries?

> sorry for bumping, but since there is some years after this reply and I
> wonder if anything is changed in DJGPP 2.05.
> and newer bash-4.1 seems working better.

printf() is much bigger, so it should be avoided, if possible (!). (7ZDEC avoids it.) Symlink support in 2.05 (like in 2.04) adds some bloat.

I'm still not quite sure if --gc-sections is even accidentally supposed to work for DJGPP COFF, but it does halfway work (still), e.g. 7ZDEC (see my MAKEFILE.GNU "SMARTLINK=1"). I tried again this morning with GCC 10.3 and whatever latest BinUtils is, and it seems to save some noticeable space (although UPX'd makes it less pressing).

But DJGPP was never optimized well for size. They just never found the time or motivation. But I'm grateful for what we have.

Back to index page
Thread view  Board view
22049 Postings in 2034 Threads, 396 registered users, 130 users online (0 registered, 130 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum