Page 1 of 1

Reducing the EXEs sizes

Posted: Wed Feb 20, 2019 5:24 am
by Antonio Linares
As you may be aware Windows provides a Linux bash. Simply type bash from a cmd window.

https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/

From bash we can run the nm utility:

nm --defined-only fivehg.lib > defined.txt
nm --extern-only fivehg.lib > extern.txt
nm --defined-only fivehgc.lib > defined_c.txt
nm --extern-only fivehgc.lib > extern_c.txt

Now we are going to create 2 DBFs named files.dbf and symbols.dbf and feed them from those txt files.

I invite you to do the same with all the Harbour libs (for MinGW) and lets see if we can improve Harbour libs too ;-)

Re: Reducing the EXEs sizes

Posted: Wed Feb 20, 2019 5:49 am
by Antonio Linares
Building files.dbf

dbfs.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local aLines := HB_ATokens( MemoRead( "extern.txt" ), Chr( 10 ) )

   DbCreate( "files.dbf", { { "name", "c", 80, 0 } } )

   USE files
   
   AEval( aLines, { | cLine | If( At( ".o", cLine ) != 0,;
          ( DbAppend(), Files->name := StrTran( AllTrim( cLine ), ".o:", ".prg" ) ),) } )
         
   GO TOP      
   XBrowser

return nil

Re: Reducing the EXEs sizes

Posted: Wed Feb 20, 2019 6:04 am
by Antonio Linares
Feeding files.dbf and symbols.dbf

Please notice that this is a work in progress. Your tests, feedback and help are welcome :-)

dbfs.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local aLines := HB_ATokens( MemoRead( "extern.txt" ), Chr( 10 ) )
   local cLine, n

   DbCreate( "files.dbf", { { "name", "c", 80, 0 } } )
   DbCreate( "symbols.dbf", { { "name", "c", 80, 0 },;
                              { "filename", "c", 80, 0 } } )

   USE files
   USE symbols NEW
   SELECT files
   
   for n = 1 to Len( aLines )
      cLine = aLines[ n ]
      if At( ".o", cLine ) != 0
         files->( DbAppend() )
         files->name := StrTran( AllTrim( cLine ), ".o:", ".prg" )
      else
         if "HB_FUN_" $ cLine
            symbols->( DbAppend() )
            symbols->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            symbols->filename := files->name
         endif
      endif
   next  
         
   SELECT symbols
   GO TOP
   XBrowser

return nil

Re: Reducing the EXEs sizes

Posted: Wed Feb 20, 2019 6:17 am
by Antonio Linares
Given a symbol name we need to know where it is created and where it is used

Given a file name we need to know whay symbols define and what symbols import (externals)

Given a file name we need to know what other files get linked

Given a symbol name we need to know what file names get linked

Re: Reducing the EXEs sizes

Posted: Wed Feb 20, 2019 6:30 am
by Antonio Linares
We could simply do:

nm fivehg.lib > fivehg.txt

and get all the info from one single txt file...

Re: Reducing the EXEs sizes

Posted: Thu Feb 21, 2019 6:48 am
by Antonio Linares
Much better:

First create fivehg.txt this way (from Windows bash):

nm fivehg.lib > fivehg.txt

dbfs.prg

Code: Select all | Expand

#include "FiveWin.ch"

extern DBFCDX

function Main()

   local aLines := HB_ATokens( MemoRead( "fivehg.txt" ), Chr( 10 ) )
   local cLine, n

   DbCreate( "files.dbf", { { "name", "c", 80, 0 } } )
   DbCreate( "symbols.dbf", { { "name", "c", 80, 0 },;
                              { "filename", "c", 80, 0 } } )

   USE files VIA "DBFCDX"
   INDEX ON files->name TAG name
   USE symbols NEW VIA "DBFCDX"
   INDEX ON symbols->name TAG name
   INDEX ON symbols->filename TAG filename
   
   for n = 1 to Len( aLines )
      cLine = aLines[ n ]
      if ".o" $ cLine
         files->( DbAppend() )
         files->name := StrTran( AllTrim( cLine ), ".o:", ".prg" )
      else
         if SubStr( cLine, 10, 1 ) == "T"
            symbols->( DbAppend() )
            if "HB_FUN_" $ cLine
               symbols->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            else  
               symbols->name := SubStr( cLine, 12 ) + "()"
            endif
            symbols->filename := files->name
         endif
      endif
   next  
         
   SELECT symbols
   GO TOP
   XBROWSER AUTOSORT

return nil


Image

Re: Reducing the EXEs sizes

Posted: Thu Feb 21, 2019 7:19 am
by Antonio Linares
Now we create a child DBF that keeps where symbols are used from:

used.dbf get populated with more than 12.300 records !!!

dbfs.prg

Code: Select all | Expand

#include "FiveWin.ch"

extern DBFCDX

function Main()

   local aLines := HB_ATokens( MemoRead( "fivehg.txt" ), Chr( 10 ) )
   local cLine, n

   DbCreate( "files.dbf", { { "name", "c", 80, 0 } } )
   DbCreate( "symbols.dbf", { { "name", "c", 80, 0 },;
                              { "filename", "c", 80, 0 } } )
   DbCreate( "used.dbf", { { "name", "c", 80, 0 },;
                           { "filename", "c", 80, 0 } } )

   USE files VIA "DBFCDX"
   INDEX ON files->name TAG name
   USE symbols NEW VIA "DBFCDX"
   INDEX ON symbols->name TAG name
   INDEX ON symbols->filename TAG filename
   USE used NEW VIA "DBFCDX"
   INDEX ON used->name TAG name
   INDEX ON used->filename TAG filename
   
   for n = 1 to Len( aLines )
      cLine = aLines[ n ]
      if ".o" $ cLine
         files->( DbAppend() )
         files->name := StrTran( AllTrim( cLine ), ".o:", ".prg" )
      else
         if SubStr( cLine, 10, 1 ) == "T"
            symbols->( DbAppend() )
            if "HB_FUN_" $ cLine
               symbols->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            else  
               symbols->name := SubStr( cLine, 12 ) + "()"
            endif
            symbols->filename := files->name
         endif
         if SubStr( cLine, 10, 1 ) == "U"
            used->( DbAppend() )
            if "HB_FUN_" $ cLine
               used->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            else  
               used->name := SubStr( cLine, 12 ) + "()"
            endif
            used->filename := files->name
         endif
      endif
   next  
         
   SELECT symbols
   GO TOP
   XBROWSER AUTOSORT

return nil

Re: Reducing the EXEs sizes

Posted: Fri Feb 22, 2019 9:17 am
by Antonio Linares
Rao has implemented this great viewer on these generated DBFs:

viewer.prg

Code: Select all | Expand

#include "FiveWin.ch"

extern dbfcdx

function SymbolBrowse2()

   FIELD NAME

   USE SYMBOLS NEW SHARED VIA "DBFCDX"
   SET ORDER TO TAG NAME

   USE USED    NEW SHARED VIA "DBFCDX"
   SET ORDER TO TAG FILENAME

   SET RELATION TO NAME INTO SYMBOLS
   SET FILTER TO !EMPTY( SYMBOLS->NAME )
   GO TOP

   XBROWSER "USED" ;
      COLUMNS "FILENAME", "NAME", "SYMBOLS->FILENAME" ;
      AUTOSORT ;
      SHOW RECID ;
      SETUP (  oBrw:cHeaders :=  { "FILENAME", "SYMBOL", "DEFINED IN" }, ;
               oBrw:AutoFit() ;
            )

return nil


Image

Re: Reducing the EXEs sizes

Posted: Mon Feb 25, 2019 8:37 am
by Antonio Linares
Getting closer...

Warning: This example TAKES TIME to execute so be patient and wait for results

related.prg

Code: Select all | Expand

#include "FiveWin.ch"

extern dbfcdx

function Main()

   XBrowser( Related( "window.prg" ) )
   
return nil  

function Related( cFileName )

   local aFiles := {}
   local cAliasSymbols := cGetNewAlias( "symbols" )
   local cAliasUsed := cGetNewAlias( "used" )

   USE symbols NEW SHARED VIA "DBFCDX" ALIAS ( cAliasSymbols )
   SET ORDER TO "name"

   USE used NEW SHARED VIA "DBFCDX" ALIAS ( cAliasUsed )
   SET ORDER TO "filename"

   SET RELATION TO ( cAliasUsed )->name INTO ( cAliasSymbols )
   SET FILTER TO ! Empty( ( cAliasSymbols )->filename ) .and. Upper( AllTrim( ( cAliasUsed )->filename ) ) == Upper( cFileName )
   GO TOP
   
   while ! ( cAliasUsed )->( Eof() )
      If Len( aFiles ) == 0 .or. AScan( aFiles, { | aFile | aFile[ 1 ] == Upper( AllTrim( ( cAliasSymbols )->filename ) ) } ) == 0
         AAdd( aFiles, { Upper( AllTrim( ( cAliasSymbols )->filename ) ), Related( Upper( AllTrim( ( cAliasSymbols )->filename ) ) ) } )
      endif  
      ( cAliasUsed )->( DbSkip() )
   end
   
   ( cAliasSymbols )->( DbCloseArea() )
   ( cAliasUsed )->( DbCloseArea() )
   
return ASort( aFiles,,, { | aFile1, aFile2 | aFile1[ 1 ] < aFile2[ 1 ] } )
 

Re: Reducing the EXEs sizes

Posted: Tue Feb 26, 2019 12:56 pm
by Antonio Linares
DBFs for fivehgc.lib

From Windows bash:

nm fivehgc.lib > fivehgc.txt

dbfs_c.prg

Code: Select all | Expand

#include "FiveWin.ch"

extern DBFCDX

function Main()

   local aLines := HB_ATokens( MemoRead( "fivehgc.txt" ), Chr( 10 ) )
   local cLine, n, cName, cResult := ""

   DbCreate( "files_c.dbf", { { "name", "c", 80, 0 } } )
   DbCreate( "symbols_c.dbf", { { "name", "c", 80, 0 },;
                              { "filename", "c", 80, 0 } } )
   DbCreate( "used_c.dbf", { { "name", "c", 80, 0 },;
                           { "filename", "c", 80, 0 } } )

   USE files_c VIA "DBFCDX"
   INDEX ON files_c->name TAG name
   
   USE symbols_c NEW VIA "DBFCDX"
   INDEX ON symbols_c->name TAG name
   INDEX ON symbols_c->filename TAG filename
   
   USE used_c NEW VIA "DBFCDX"
   INDEX ON used_c->name TAG name
   INDEX ON used_c->filename TAG filename
     
   for n = 1 to Len( aLines )
      cLine = aLines[ n ]
      if ".o" $ cLine
         files_c->( DbAppend() )
         files_c->name := StrTran( AllTrim( cLine ), ".o:", ".c" )
      else
         if SubStr( cLine, 10, 1 ) == "T"
            symbols_c->( DbAppend() )
            if "HB_FUN_" $ cLine
               symbols_c->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            else  
               symbols_c->name := SubStr( cLine, 12 ) + "()"
            endif            
            symbols_c->filename := files_c->name
         endif
         if SubStr( cLine, 10, 1 ) == "U"
            used_c->( DbAppend() )
            if "HB_FUN_" $ cLine
               used_c->name := SubStr( cLine, At( "HB_FUN_", cLine ) + 7 ) + "()"
            else  
               used_c->name := SubStr( cLine, 12 ) + "()"
            endif            
            used_c->filename := files_c->name
         endif
      endif
   next  
   
   SELECT symbols_c
   SET ORDER TO "name"
   SELECT used_c
   SET ORDER TO "filename"
   SET RELATION TO used_c->name INTO symbols_c
   GO TOP

   cName = used_c->filename
   cResult += cName + CRLF + Space( 10 ) + used_c->name
   
   while ! Eof()
      SKIP
      if used_c->filename != cName
         cName = used_c->filename
         cResult += CRLF + cName
      else
         if ! Empty( symbols_c->filename ) .and. symbols_c->filename != cName
            cResult += CRLF + Space( 10 ) + AllTrim( used_c->name ) + " --> " + symbols_c->filename
         endif  
      endif  
   end
   
   // MemoWrit( "result.txt", cResult )
   // WinExec( "notepad result.txt" )
   
return nil

Re: Reducing the EXEs sizes

Posted: Sat Mar 16, 2019 10:07 am
by Enrico Maria Giordano
In the end, how to reduce the EXEs sizes? :-)

EMG

Re: Reducing the EXEs sizes

Posted: Sun Mar 17, 2019 12:43 pm
by Antonio Linares
Enrico,

We are working on this. Not finished yet :-)

Re: Reducing the EXEs sizes

Posted: Sun Mar 17, 2019 2:11 pm
by Enrico Maria Giordano
Great! Keep us updated! :-)

EMG

Re: Reducing the EXEs sizes

Posted: Thu Apr 04, 2019 8:16 am
by Enrico Maria Giordano
Any news?

EMG