Archive: Striping down NSIS


Striping down NSIS
I'm writing a small app that uses nsis.
It only requires a small list of features and since size is critical I would like to know how to strip nsis to the bare basics I’ve edit the config.h file but only managed to shave off 93KB on makensis. What else can i do to cut back?
And by the way you say 7z compression is on the works in witch version of nsis will it be added?


Function needed:
Install files and dirs
write/read registry (remember install folder)
show license, dir picker & progress
external ui & custom strings

Using NSIS 2.00b4 (CVS) 22/04/2003


Is the size of the generated installer the important thing or the size of makensis? If it's the size of the generated installer then it's the size of the executable header (bzip2 or zlib version) that you want to concentrate on reducing. KiCHiK or Joost will no doubt give you much much more information :)


The exe header is optimized for minial size, makensis is optimized for maximum speed therefore I don't have many tips for it but these two:


If I think of any more I'll let you know.

And by the way you say 7z compression is on the works in witch version of nsis will it be added?
It is planned to be implemented in the final version of NSIS 2.

Already using VC7 and i want to make both makensis and exehead smaller.

By the way in config.h removing #define NSIS_SUPPORT_CODECALLBACKS gives compile errors (current cvs build) why? if it's optional shouldn't it compile with out it? (but i'm no expert programer (just fouling around)).

but back to the topic can't i just take of unused dialogst or something else? there must be a way to srink it even more (with out using compression metods).
and what about my 7z question?

And thanks for the replies ;) it's good to be helped.


Fixed that compile error in latest CVS version.

Resources are removed according to config.h.

I have answered your 7z question.


Makensis.exe is the compiler that generates the installers. The overhead for the installer is only 34 KB. Or do you have to distribute the compiler?

See kichik's post: 7zip compression will be available before NSIS 2 final. You can use the 7zip SFX for now (but that will add about 100 KB).


kichik sorry, i didn't see it (probably toght it was you signature :confused:) and thanks for fixing the errors :).
I hope the nsis 7z exehead will be the same size or smaller then the current ones 100KB is way overkill (unless you realy need top compression on big files but still).
Joost Verburg, I need both the exehead and the makensis as small has possible.

Thanks for the help, i'm realy greatfull ;)


100 KB is definately not overkill if you have an installer of a few MB's. It can make it > 25% smaller.

The 7zip/LZMA compression won't make the NSIS exehead that large when it's integrated, it will be optimized. The SFX supports some other compression methods too.


You can also use UPX to compress makensis. It will strip down a few more KB :)


I always add this line:

!packhdr"C:\tmp.dat""c:\upx.exe--best--crp-ms=999999C:\tmp.dat"

in the .nsi file to pack the header of the installer while compiling. Remember to change the path to upx.exe or put it in c:

It saves you 10kB or so.

That helps for the final result. But you can use UPX (without including it in your package) to compress makensis.exe too. It will compress makensis.exe pretty good. It compresses the current CVS version from 400kb to 150kb.


I packed makensis.exe and the compiled .nsi has the same size. :?


That's because you've packed the compiler, not the output. I am talking of ways to make makensis.exe smaller, not only the exehead.


But DragonSoull wanted to make the installer smaller. And (If I understood correctly) he wanted to strip things inside makensis.exe forseeing a smaller compile.


He wanted to strip everything possible in order to make everything smaller, including makensis.exe.


ok, I misunderstood.


If anyone want to use 7zip anyway, I have stripped the 7za.exe file to 133kb (from 480kb). It supports extracting of 7z files with LZMA or BCJ. If you want it: http://gyrbo.yi.org/dl/extract7.exe

Some sample code if you want to use it in a project (thanks to whoever created the DeleteDetailViewItem function):


######################################
!define LVM_GETITEMCOUNT 0x1004
!define LVM_DELETEITEM 0x1008
######################################
; This function delete one element from the details view
; Push the index of the elemnet to delete before call
Function DeleteDetailViewItem
exch $0
push $1
FindWindow $1 "#32770" "" $HWNDPARENT
GetDlgItem $1 $1 0x3F8 ; This is the Control ID of the details view
SendMessage $1 ${LVM_DELETEITEM} $0 0
pop $1
pop $0
FunctionEnd

Section "MainGroup" SEC01
AddSize 41065
;DetailPrint "Unpacking Install Files..."
SetOutPath $PLUGINSDIR
Push 0
Call DeleteDetailViewItem
SetCompress Auto
SetOverwrite Off
;Modified 7za.exe (www.7-zip.org)
File "extract7.exe"
Push 0
Call DeleteDetailViewItem
SetCompress Off
SetOverwrite On
;7z'd files
File "files.7z"
Push 0
Call DeleteDetailViewItem
SetCompress Auto
; DetailPrint ""

DetailPrint "Creating Program Directory..."
CreateDirectory "$INSTDIR"
DetailPrint ""

DetailPrint "Installing Program Files..."
;Run extracter on files
nsExec::ExecToLog '"$PLUGINSDIR\extract7.exe" x "$PLUGINSDIR\files.7z" -y "-o$INSTDIR" * -r'
DetailPrint ""

;Other code

SectionEnd


Place extract7.exe and your compressed files in files.7z in the same dir when you compile and there you go: 7zip compression in NSIS.

Some results:
Source: 40.1MB
7-Zip File: 9.12MB
NSIS with 7-Zip: 9.24MB
NSIS with zlib: 14.2MB
NSIS with BZip2: 13.4MB

I think the results speak for themselfs.

Well bumping this oldy up again :)

got 2.0 RC1 and started to shave the fat again got into the falowing problems.


removing #define NSIS_CONFIG_PLUGIN_SUPPORT gives

d:\Home\Projects\saves\Source\makesaves\Source\script.cpp(785): error C3861: 'build_plugin_table': identifier not found, even with argument-dependent lookup

i commented it out and build worked again (but probably broke something)

removing #define NSIS_CONFIG_ENHANCEDUI_SUPPORT gives
d:\Home\Projects\saves\Source\makesaves\Source\script.cpp(3734): error C2065: 'TOK_SETBKCOLOR' : undeclared identifier

fixed by adding TOK_SETBKCOLOR to the token.h enum {}

removing #define NSIS_CONFIG_COMPONENTPAGE gives

makenssi error LNK2019: unresolved external symbol "private: void __thiscall CEXEBuild::PreperInstTypes(void)" (?PreperInstTypes@CEXEBuild@@AAEXXZ) referenced in function "public: int __thiscall CEXEBuild::write_output(void)" (?write_output@CEXEBuild@@QAEHXZ)

fixed by commenting out PreperInstTypes calls in the write_output function.

But now makensis crashes compiling my test script

I'm also using custom resource.rc so i'm including all the relevent files in a 7z archive.

Help please :)


Originally posted by n0On3
I always add this line:
!packhdr"C:\tmp.dat""c:\upx.exe--best--crp-ms=999999C:\tmp.dat"

in the .nsi file to pack the header of the installer while compiling. Remember to change the path to upx.exe or put it in c:

It saves you 10kB or so.
Interesting, but normally is the header compressed when the scrip is compiled or is it keepted in umcompressed format and if so could i upx them before inclusion in makensis?

Now to upx makensis itself would be a bit uselless since this would prevent normal compression using standart methods and i don't think upx can beat 7z (it didn't beat zip when i tested a year back)

As far as I know, you can't compress the entire header using normal means (7z, bzip, ...) because it's executable. You always need some way to decompress it. This decompression routine is very small with upx, plus I think it's optimized for executables.

Compressing makensis will only save space on your harddisk, because none of it gets included in the installer.


Originally posted by Gyrbo
As far as I know, you can't compress the entire header using normal means (7z, bzip, ...) because it's executable. You always need some way to decompress it. This decompression routine is very small with upx, plus I think it's optimized for executables.

Compressing makensis will only save space on your harddisk, because none of it gets included in the installer.
I see... so now all i need to find out is how (if it's possible that is) I compress the headers with upx before makensis is put together...

No need tp find out, I'm using the following in my scripts and it works perfect (d: is my biggest drive):
!packhdr "d:\header.dat" "d:\upx.exe -9 d:\header.dat"


Originally posted by DragonSoull
I see... so now all i need to find out is how (if it's possible that is) I compress the headers with upx before makensis is put together...
You can't, you'll have to use !packhdr as Gyrbo suggested. makensis needs to edit the resources of the exehead and can't do that when the exehead is compressed using UPX. If you really want you can edit the code and make makensis uncompress the exehead first and compress it back. The only problem is that you'll need UPX for that and that will surely overshadow any size savings you've gained by using a compressed exehead.

Well I could always offer upx has a optional downloadable component.

kichik, what about the compile errors and crash I got? is somebody already on it?

Also since now 7z is a reality i'm considering including just that compression method too simplify thing (and take some fat of too) but since my main hard drive is gone compiling is of the question :(


Oh sorry, missed that message. I'll look into it.


Thanks :)


Well, I have fixed the compile errors but I can't get it to crash. Make sure you've recompiled exedata.cpp after the exeheads were compiled. Best method would probably be using Rebuild All. If that doesn't work I'll need some more details, starting with the message you get.


Originally posted by kichik
Well, I have fixed the compile errors but I can't get it to crash. Make sure you've recompiled exedata.cpp after the exeheads were compiled. Best method would probably be using Rebuild All. If that doesn't work I'll need some more details, starting with the message you get.
Like i said before my hard drive broke, so compiling is out of the question, when i recieve a replacementeand and re-setup windows (and everything else) i'll try again :(

Well it's me again :), just wanted to say that I'm still with out my computer but i've been writing the Functional Specification of my app with resulted in several changes on it's design (keeps getting more complex with every draft :\).

Namely that i'll be trying to use CEXEBuild directly from inside my app (allowing to trim even more fat), I can coud on you guys for when ever I become confused ;).

Also I been meaning to ask if the dev team has a problem with the name "Saves (NSIS)". If you do I can remove it but it's there mostely to give you guys credit for most of the work :p


Make sure that your product can't be misrepresented as being the original version, so you should call it "based on NSIS" or something like that.


So can't use the (NSIS)... guess i'll just change the name all together.

Keeper "Built on NSIS Technology" sounds preaty good.