繁体   English   中英

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

[英]C++ Windows Compiler for smallest executables

伙计们,我想开始用 C++ 编程。 我已经用 vb6、vb.net 编写了一些程序,现在我想获得 C++ 知识,我想要一个可以将我的代码编译成最小的 Windows 应用程序的编译器。 例如,有一个名为 PureBasic 的 Basic 语言编译器,它可以使 Hello world 独立应用程序的大小为 5 kb,而我编译的简单套接字程序只有 12kb(没有任何 DLL-s 和运行时文件)。 我知道这太棒了,所以我想要 C++ 类似的东西。

如果我错了并且没有这种 Windows 编译器,有人可以给我一个网站或书籍来教我如何减少 C++ 可执行文件的大小,或者如何使用 Windows API 调用?

例如 Microsoft Visual C++ 编译器...您只需关闭与 C 运行时 ( /NODEFAULTLIB ) 的链接,您的可执行文件将小至 5KB。 只有一个问题:您将无法使用标准 C 和 C++ 库中的几乎任何东西,也无法使用 C++ 的标准特性,如异常处理、 newdelete运算符、浮点运算等。 您只需要使用纯操作系统功能(例如,使用CreateFile创建文件,使用HeapAlloc分配内存等...)。

很多年前我不得不用 VC6 来做这件事。 这是必要的,因为可执行文件将通过线路传输到目标计算机,并在其中运行。 由于它很可能通过调制解调器连接发送,因此它需要尽可能小。 为了缩小可执行文件,我依靠两种技术:

  1. 不要使用 C 或 C++ 运行时。 告诉编译器不要链接它们。使用 Windows API 的子集实现所有必要的功能,该子集保证在当时的所有 Windows 版本上都可用(98,Me,NT,2000)。
  2. 告诉链接器将所有代码和数据段合并为一个。 我不记得这个开关,我不知道它是否仍然可能,特别是对于 64 位可执行文件。

最终可执行文件大小:~2K

在 Visual C++ 中将以下代码的可执行文件大小从 24k 字节减少到 1.6k 字节

int main (char argv[]) {
  return 0;
}
  1. 链接器开关(尽管建议安全对齐为 512):

/文件对齐:16 /对齐:16

  1. 链接(在 VC++ 项目属性中):LIBCTINY.LIB

  2. 额外的编译指示(这将解决 Feruccio 的建议)

但是,我仍然看到一段 ASCII(0) 构成了三分之一的可执行文件,以及“丰富的”Windows 签名。 (我正在阅读后者并不是程序执行所真正需要的)。

#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;
}

我不知道你为什么在学习语言之前对这种优化感兴趣,但无论如何......

它对你使用的编译器没有太大的影响,但你如何使用它。 例如,选择像 Visual Studio C++ 或 MinGW 这样的编译器,并阅读其文档。 您将找到有关如何针对大小或性能优化编译的信息(通常当您针对大小进行优化时,您会失去性能,反之亦然)。

例如,在 Visual Studio 中,您可以通过将 /O1 参数传递给编译器(或 Project Properties/C-C++ /Optimization)来最小化可执行文件的大小。

另外不要忘记在“发布”模式下编译,否则您的可执行文件可能会充满调试符号,这会增加您的可执行文件的大小。

运行 Windows 的现代台式 PC 至少有 1Gb RAM 和巨大的硬盘驱动器,担心不代表任何实际应用程序的琐碎程序的大小是没有意义的。

任何语言的“Hello world”程序的大部分大小都是固定开销,用于建立执行环境以及加载和启动代码。 对于任何重要的应用程序,您应该更关心代码大小随着添加更多功能而增加的速度。 从这个意义上说,任何编译器中的 C++ 代码都非常高效。 也就是说,您的 PureBasic 程序很少或不执行任何操作可能比等效的 C++ 程序小,但是当您在代码中构建有用的功能时,情况不一定如此。

@user:C++ 确实会生成小目标代码,但是如果 printf() (或 cout<<) 的代码是静态链接的,则生成的可执行文件可能会更大,因为 printf() 有很多功能在“hello world”程序是多余的。 尝试使用 puts() 例如,您可能会发现代码更小。

此外,您确定将苹果与苹果进行比较吗? 一些执行环境依赖于动态链接的运行时库或虚拟机,它们提供的功能可能在 C++ 程序中静态链接。

我不喜欢回复死帖,但由于没有回复提到这一点(除了 Mat 回复)......

在我之后重复:C++ != ( vb6 || vb.net || basic )。 而且我不仅提到语法,C++ 编码风格通常与 VB 中的不同,因为 C++ 程序员试图让事情通常比 vb 程序员设计得更好......

PS:不,在 C++ 世界中没有复制粘贴的地方。 对不起,不得不说这个……

暂无
暂无

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

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