简体   繁体   English

用于最小可执行文件的 C++ Windows 编译器

[英]C++ Windows Compiler for smallest executables

guys I want to start programing with C++.伙计们,我想开始用 C++ 编程。 I have written some programs in vb6, vb.net and now I want to gain knowledge in C++, what I want is a compiler that can compile my code to the smallest windows application.我已经用 vb6、vb.net 编写了一些程序,现在我想获得 C++ 知识,我想要一个可以将我的代码编译成最小的 Windows 应用程序的编译器。 For example there is a Basic language compiler called PureBasic that can make Hello world standalone app's size 5 kb, and simple socket program which i compiled was only 12kb (without any DLL-s and Runtime files).例如,有一个名为 PureBasic 的 Basic 语言编译器,它可以使 Hello world 独立应用程序的大小为 5 kb,而我编译的简单套接字程序只有 12kb(没有任何 DLL-s 和运行时文件)。 I know it is amazing, so I want something like this for C++.我知道这太棒了,所以我想要 C++ 类似的东西。

If I am wrong and there is not such kind of windows compiler can someone give me a website or book that can teach me how to reduce C++ executable size, or how to use Windows API calls?如果我错了并且没有这种 Windows 编译器,有人可以给我一个网站或书籍来教我如何减少 C++ 可执行文件的大小,或者如何使用 Windows API 调用?

Microsoft Visual C++ compiler for example... You just have to turn off linking to the C runtime ( /NODEFAULTLIB ) and your executable will be as small as 5KB.例如 Microsoft Visual C++ 编译器...您只需关闭与 C 运行时 ( /NODEFAULTLIB ) 的链接,您的可执行文件将小至 5KB。 There's just one problem: you won't be able to use almost anything from the standard C and C++ library, nor standard features of C++ like exception handling, new and delete operators, floating point arithmetics, and more.只有一个问题:您将无法使用标准 C 和 C++ 库中的几乎任何东西,也无法使用 C++ 的标准特性,如异常处理、 newdelete运算符、浮点运算等。 You'll need to use only the pure OS features (eg create files with CreateFile , allocate memory with HeapAlloc , etc...).您只需要使用纯操作系统功能(例如,使用CreateFile创建文件,使用HeapAlloc分配内存等...)。

I had to do this many years ago with VC6.很多年前我不得不用 VC6 来做这件事。 It was necessary because the executable was going to be transmitted over the wire to a target computer, where it would run.这是必要的,因为可执行文件将通过线路传输到目标计算机,并在其中运行。 Since it was likely to be sent over a modem connection, it needed to be as small as possible.由于它很可能通过调制解调器连接发送,因此它需要尽可能小。 To shrink the executable, I relied on two techniques:为了缩小可执行文件,我依靠两种技术:

  1. Do not use the C or C++ runtime.不要使用 C 或 C++ 运行时。 Tell the compiler not to link them in. Implement all necessary functionality using a subset of the Windows API that was guaranteed to be available on all versions of Windows at the time (98, Me, NT, 2000).告诉编译器不要链接它们。使用 Windows API 的子集实现所有必要的功能,该子集保证在当时的所有 Windows 版本上都可用(98,Me,NT,2000)。
  2. Tell the linker to combine all code and data segments into one.告诉链接器将所有代码和数据段合并为一个。 I don't remember the switches for this and I don't know if it's still possible, especially with 64-bit executables.我不记得这个开关,我不知道它是否仍然可能,特别是对于 64 位可执行文件。

The final executable size: ~2K最终可执行文件大小:~2K

Reduction of the executable size for the code below from 24k to 1.6k bytes in Visual C++在 Visual C++ 中将以下代码的可执行文件大小从 24k 字节减少到 1.6k 字节

int main (char argv[]) {
  return 0;
}
  1. Linker Switches (although the safe alignment is recommended to be 512):链接器开关(尽管建议安全对齐为 512):

/FILEALIGN:16 /ALIGN:16 /文件对齐:16 /对齐:16

  1. Link with (in the VC++ project properties): LIBCTINY.LIB链接(在 VC++ 项目属性中):LIBCTINY.LIB

  2. Additional pragmas (this will address Feruccio's suggestion)额外的编译指示(这将解决 Feruccio 的建议)

However, I still see a section of ASCII(0) making a third of the executable, and the "Rich" Windows signature.但是,我仍然看到一段 ASCII(0) 构成了三分之一的可执行文件,以及“丰富的”Windows 签名。 (I'm reading the latter is not really needed for program execution). (我正在阅读后者并不是程序执行所真正需要的)。

#ifdef NDEBUG
#pragma optimize("gsy",on)
#pragma comment(linker,"/merge:.rdata=.data")
#pragma comment(linker,"/merge:.text=.data")
#pragma comment(linker,"/merge:.reloc=.data")
#pragma comment(linker,"/OPT:NOWIN98")
#endif // NDEBUG
int main (char argv[]) {
  return 0;
}

I don't know why you are interested in this kind of optimization before learning the language, but anyways...我不知道你为什么在学习语言之前对这种优化感兴趣,但无论如何......

It doesn't make much difference of what compiler you use, but on how you use it.它对你使用的编译器没有太大的影响,但你如何使用它。 Chose a compiler like the Visual Studio C++'s or MinGW for example, and read its documentation.例如,选择像 Visual Studio C++ 或 MinGW 这样的编译器,并阅读其文档。 You will find information of how to optimize the compilation for size or performance (usually when you optimize for size, you lose performance, and vice-versa).您将找到有关如何针对大小或性能优化编译的信息(通常当您针对大小进行优化时,您会失去性能,反之亦然)。

In Visual Studio, for example, you can minimize the size of the executable by passing the /O1 parameter to the compiler (or Project Properties/ C-C++ /Optimization).例如,在 Visual Studio 中,您可以通过将 /O1 参数传递给编译器(或 Project Properties/C-C++ /Optimization)来最小化可执行文件的大小。

Also don't forget to compile in "release" mode, or your executable may be full of debugging symbols, which will increase the size of your executable.另外不要忘记在“发布”模式下编译,否则您的可执行文件可能会充满调试符号,这会增加您的可执行文件的大小。

A modern desktop PC running Windows has at least 1Gb RAM and a huge hard drive, worrying about the size of a trivial program that is not representative of any real application is pointless.运行 Windows 的现代台式 PC 至少有 1Gb RAM 和巨大的硬盘驱动器,担心不代表任何实际应用程序的琐碎程序的大小是没有意义的。

Much of the size of a "Hello world" program in any language is fixed overhead to do with establishing an execution environment and loading and starting the code.任何语言的“Hello world”程序的大部分大小都是固定开销,用于建立执行环境以及加载和启动代码。 For any non-trivial application you should be more concerned with the rate the code size increases as more functionality is added.对于任何重要的应用程序,您应该更关心代码大小随着添加更多功能而增加的速度。 And in that sense it is likley that C++ code in any compiler is pretty efficient.从这个意义上说,任何编译器中的 C++ 代码都非常高效。 That is to say your PureBasic program that does little or nothing may be smaller than an equivalent C++ program, but that is not necessarily the case by the time you have built useful functionality into the code.也就是说,您的 PureBasic 程序很少或不执行任何操作可能比等效的 C++ 程序小,但是当您在代码中构建有用的功能时,情况不一定如此。

@user: C++ does produce small object code, however if the code for printf() (or cout<<) is statically linked, the resulting executable may be rather larger because printf() has a lot of functionality that is not used in a "hello world" program so is redundant. @user:C++ 确实会生成小目标代码,但是如果 printf() (或 cout<<) 的代码是静态链接的,则生成的可执行文件可能会更大,因为 printf() 有很多功能在“hello world”程序是多余的。 Try using puts() for example and you may find the code is smaller.尝试使用 puts() 例如,您可能会发现代码更小。

Moreover are you sure that you are comparing apples with apples?此外,您确定将苹果与苹果进行比较吗? Some execution environments rely on a dynamically linked runtime library or virtual machine that is providing functionality that might be statically linked in a C++ program.一些执行环境依赖于动态链接的运行时库或虚拟机,它们提供的功能可能在 C++ 程序中静态链接。

I don't like to reply to a dead post, but since none of the responses mentions this (except Mat response)...我不喜欢回复死帖,但由于没有回复提到这一点(除了 Mat 回复)......

Repeat after me: C++ != ( vb6 || vb.net || basic ).在我之后重复:C++ != ( vb6 || vb.net || basic )。 And I'm not only mentioning syntax, C++ coding style is typically different than the one in VB, as C++ programmers try to make things usually better designed than vb programmers...而且我不仅提到语法,C++ 编码风格通常与 VB 中的不同,因为 C++ 程序员试图让事情通常比 vb 程序员设计得更好......

PS: No, there is no place for copy-paste in C++ world. PS:不,在 C++ 世界中没有复制粘贴的地方。 Sorry, had to say this...对不起,不得不说这个……

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM