Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unused routines still result in huge .EXE
#1
I was looking this weekend on how to better manage my libraries.  One thought was to include most of my common routines in a single large file and simply load that.  What I found was that this caused the .EXE file size to grow considerably.  I created a .BAS file that did nothing but a print statement and included this large library, of which zero routines were actually used.  The file size was huge compared to using a very small library, of which zero routines were used.

Is there a switch or setting that I can use that will cause unused SUBs and Functions to be excluded at compile time if they are not used?
Reply
#2
Usually the linker is smart enough to only link those object files, which contain used references. In C/C++ you would just create one translation unit per function, hence getting a single .o file for every function. You may also collect those single object in a .a file, but even therein it remains a collection of single objects, they will not be concatenated on a binary level, but just saved in one file. However, ALL user code in a .bas program, i.e. all your main code and all SUBs/FUNCs go into one translation unit (doesn't matter if it's in the main file or $INCLUDE'd). The linker is not able to tear that unit to avoid unused code. If just one of the funtions in the unit is referenced, then the unit is linked in whole, and as your main code IS usually referenced it WILL be linked.

Saying that, the only way to achive what you want, is to split your libraries into one SUB/FUNC per include file (or maybe small collections of SUBs/FUNCs which are definitly used together) and $INCLUDE only those which you need in your program. That way you only have the really needed code in the big user code unit. Placing an $INCLUDEONCE in each include file will help to avoid double definition errors, if you nest $INCLUDEs to pull in other required SUBs/FUNCs.
Reply
#3
For working with lots of include files it would be awesome if we dropped the requirement that no (main)code is allowed between subs/functions.
Now I often need 2 includes: one with global declarations at the top of main code and one with subs/functions at the end...
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#4
I was under the impression that code included in libraries but not used would be ignored by the compiler. I remember a discussion about this, either on this forum or perhaps a previous one. Since the introduction of $INCLUDONCE I have broke down most of my large libraries into smaller individual routines to be included as needed. I did this because it makes code much easier to reuse but am glad to hear this also helps with ignoring unused code.

Here is an example of the libraries I have included in a project I'm currently working on. This approach makes much more sense to me.

Code: (Select All)
'$INCLUDE:'.\lib\common\lib_type_rect.bi'           TYPE_RECT
'$INCLUDE:'.\lib\common\lib_type_circle.bi'         TYPE_CIRCLE
'$INCLUDE:'.\lib\common\lib_type_line.bi'           TYPE_LINE
'$INCLUDE:'.\lib\common\lib_type_spoint.bi'         TYPE_SPOINT (SINGLE  x,y)
'$INCLUDE:'.\lib\collision\lib_circcollide.bi'      CircCollide% function
'$INCLUDE:'.\lib\collision\lib_linecollide.bi'      LineCollide% function
'$INCLUDE:'.\lib\collision\lib_pixelcollide.bi'     PixelCollide% function
'$INCLUDE:'.\lib\collision\lib_rectcollide.bi'      RectCollide% function
'$INCLUDE:'.\lib\collision\lib_circrectcollide.bi'  CircRectCollide% function
'$INCLUDE:'.\lib\image\lib_img_flip.bi' '           IMG_Flip subroutine
'$INCLUDE:'.\lib\image\lib_img_introtate.bi'        IMG_INTRotate subroutine (integer degrees calculated faster)
'$INCLUDE:'.\lib\fps\lib_fps.bi'                    FPS library (FPS_)
'$INCLUDE:'.\lib\math\lib_math_vec2deg.bi'          MATH_Vec2Deg function
'$INCLUDE:'.\lib\math\lib_math_deg2vec.bi'          MATH_Deg2Vec function
'$INCLUDE:'.\lib\math\lib_math_degp2p.bi'           MATH_DegP2P function
'$INCLUDE:'.\lib\math\lib_math_distancep2p.bi'      MATH_DistanceP2P function

' MAIN CODE HERE

'$INCLUDE:'.\lib\image\lib_img_flip.bm'             IMG_Flip subroutine
'$INCLUDE:'.\lib\image\lib_img_introtate.bm'        IMG_INTRotate subroutine (integer degrees calculated faster)
'$INCLUDE:'.\lib\image\lib_img_zoom.bm'             IMG_Zoom subroutine
'$INCLUDE:'.\lib\collision\lib_circcollide.bm'      CircCollide% function
'$INCLUDE:'.\lib\collision\lib_linecollide.bm'      LineCollide% function
'$INCLUDE:'.\lib\collision\lib_pixelcollide.bm'     PixelCollide% function
'$INCLUDE:'.\lib\collision\lib_rectcollide.bm'      RectCollide% function
'$INCLUDE:'.\lib\collision\lib_circrectcollide.bm'  CircRectCollide% function
'$INCLUDE:'.\lib\fps\lib_fps.bm'                    FPS library (FPS_)
'$INCLUDE:'.\lib\math\lib_math_fixdegree.bm'        MATH_FixDegree function
'$INCLUDE:'.\lib\math\lib_math_vec2deg.bm'          MATH_Vec2Deg function
'$INCLUDE:'.\lib\math\lib_math_deg2vec.bm'          MATH_Deg2Vec function
'$INCLUDE:'.\lib\math\lib_math_degp2p.bm'           MATH_DegP2P function
'$INCLUDE:'.\lib\math\lib_math_distancep2p.bm'      MATH_DistanceP2P function
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#5
(07-22-2024, 02:46 AM)dano Wrote: I was looking this weekend on how to better manage my libraries.  One thought was to include most of my common routines in a single large file and simply load that.  What I found was that this caused the .EXE file size to grow considerably.  I created a .BAS file that did nothing but a print statement and included this large library, of which zero routines were actually used.  The file size was huge compared to using a very small library, of which zero routines were used.

Is there a switch or setting that I can use that will cause unused SUBs and Functions to be excluded at compile time if they are not used?

You could try compressing the exe using upx.

https://upx.github.io/
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#6
(07-22-2024, 03:03 PM)grymmjack Wrote:
(07-22-2024, 02:46 AM)dano Wrote: I was looking this weekend on how to better manage my libraries.  One thought was to include most of my common routines in a single large file and simply load that.  What I found was that this caused the .EXE file size to grow considerably.  I created a .BAS file that did nothing but a print statement and included this large library, of which zero routines were actually used.  The file size was huge compared to using a very small library, of which zero routines were used.

Is there a switch or setting that I can use that will cause unused SUBs and Functions to be excluded at compile time if they are not used?

You could try compressing the exe using upx.

https://upx.github.io/
Holy crap...I never knew this existed!  Very cool!
Reply
#7
(07-22-2024, 03:15 PM)dano Wrote:
(07-22-2024, 03:03 PM)Holy crap...I never knew this existed!  Very cool! Wrote:
Alternatively, 'Alternate EXE Packer', a graphical interface for the UPX Packer, is also possible.
It does give me an error in Windows Defender, but I couldn't find anything. Everything is fine with me.
After the last update it still works with UPX 4.0.2, but you can simply copy the new UPX 4.2.4 into the working directory.
Or alternatively program your own interface in QB64.
Alternate EXE Packer
Reply
#8
(07-22-2024, 03:15 PM)dano Wrote: Holy crap...I never knew this existed!  Very cool!

Let us know your results Smile
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#9
Quote:I was under the impression that code included in libraries but not used would be ignored by the compiler.

me too! That seems ideal way instead of sorting stuff out.
b = b + ...
Reply
#10
Update:
I used UPX to compress my .EXE and the size went from 5,986,415 down to 2,025,583.   A HUGE difference.  Thanks for the suggestion!
Reply




Users browsing this thread: 2 Guest(s)