Reducing the EXEs sizes

Reducing the EXEs sizes

Postby Antonio Linares » Wed Feb 20, 2019 5:24 am

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 ;-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Wed Feb 20, 2019 5:49 am

Building files.dbf

dbfs.prg
Code: Select all  Expand view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Wed Feb 20, 2019 6:04 am

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 view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Wed Feb 20, 2019 6:17 am

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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Wed Feb 20, 2019 6:30 am

We could simply do:

nm fivehg.lib > fivehg.txt

and get all the info from one single txt file...
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Thu Feb 21, 2019 6:48 am

Much better:

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

nm fivehg.lib > fivehg.txt

dbfs.prg
Code: Select all  Expand view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Thu Feb 21, 2019 7:19 am

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 view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Fri Feb 22, 2019 9:17 am

Rao has implemented this great viewer on these generated DBFs:

viewer.prg
Code: Select all  Expand view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Mon Feb 25, 2019 8:37 am

Getting closer...

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

related.prg
Code: Select all  Expand view
#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 ] } )
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Antonio Linares » Tue Feb 26, 2019 12:56 pm

DBFs for fivehgc.lib

From Windows bash:

nm fivehgc.lib > fivehgc.txt

dbfs_c.prg
Code: Select all  Expand view
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Enrico Maria Giordano » Sat Mar 16, 2019 10:07 am

In the end, how to reduce the EXEs sizes? :-)

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8330
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Reducing the EXEs sizes

Postby Antonio Linares » Sun Mar 17, 2019 12:43 pm

Enrico,

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

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41321
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Reducing the EXEs sizes

Postby Enrico Maria Giordano » Sun Mar 17, 2019 2:11 pm

Great! Keep us updated! :-)

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8330
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia



Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 12 guests