Проблема здесь не столько в библиотеке, сколько в способе
библиотека связана. Конечно, iostream - это библиотека среднего размера, но я не
думаю, что он может быть настолько огромным, что заставить программу генерировать исполняемый файл
900KB
больше аналогичного, использующего функции C
. Тот, кто виноват
это не iostream
, а gcc
. Точнее, виноват static linking
.
Как бы вы объяснили эти результаты (с вашей программой):
g++ test.cpp -o test.exe SIZE: 935KB
gcc test.cpp -o test.exe -lstdc++ SIZE: 64.3KB
Различные размеры исполняемых файлов генерируются с одинаковым
Варианты сборки.
Ответ заключается в том, как gcc связывает объектные файлы.
Когда вы сравниваете результаты этих двух команд:
g++ -v test.cpp -o test.exe // c++ program using stream functions
gcc -v test.c -o test.exe // c program that using printf
вы обнаружите, что единственные места, где они различаются (кроме путей к
Временные объектные файлы) есть в используемых опциях:
C++(iostream) | C(stdio)
-------------------------------
-Bstatic | (Not There)
-lstdc++ | (Not There)
-Bdynamic | (Not There)
-lmingw32 | -lmingw32
-lgcc | -lgcc
-lmoldname | -lmoldname
-lmingwex | -lmingwex
-lmsvcrt | -lmsvcrt
-ladvapi32 | -ladvapi32
-lshell32 | -lshell32
-luser32 | -luser32
-lkernel32 | -lkernel32
-lmingw32 | -lmingw32
-lgcc | -lgcc
-lmoldname | -lmoldname
-lmingwex | -lmingwex
-lmsvcrt | -lmsvcrt
У тебя есть виновник прямо наверху. -Bstatic
это опция, которая приходит
точно после объектного файла, который может выглядеть примерно так:
"AppData\\Local\\Temp\\ccMUlPac.o" -Bstatic -lstdc++ -Bdynamic ....
Если вы поэкспериментируете с опциями и удалите «ненужные» библиотеки,
Вы можете уменьшить размер исполняемого файла с 934KB
до 4.5KB
max
в моем случае. Я получил это 4.5KB
, используя -Bdynamic
, флаг -O
и наиболее важные библиотеки, без которых ваше приложение не может жить, т.е.
-lmingw32
, -lmsvcrt
, -lkernel32
. Вы получите 25KB исполняемый файл на этом
точка. Раздень его до 10КБ и UPX до 4.5KB-5.5KB
.
Вот Makefile для игры, для ударов:
## This makefile contains all the options GCC passes to the linker
## when you compile like this: gcc test.cpp -o test.exe
CC=gcc
## NOTE: You can only use OPTIMAL_FLAGS with the -Bdynamic option. You'll get a
## screenfull of errors if you try something like this: make smallest type=static
OPTIMAL_FLAGS=-lmingw32 -lmsvcrt -lkernel32
DEFAULT_FLAGS=$(OPTIMAL_FLAGS) \
-lmingw32 \
-lgcc \
-lmoldname \
-lmingwex \
-lmsvcrt \
-ladvapi32 \
-lshell32 \
-luser32 \
-lkernel32 \
-lmingw32 \
-lgcc \
-lmoldname \
-lmingwex \
-lmsvcrt
LIBRARY_PATH=\
-LC:\MinGW32\lib\gcc\mingw32\4.7.1 \
-LC:\mingw32\lib\gcc \
-LC:\mingw32\lib\mingw32\lib \
-LC:\mingw32\lib\
OBJECT_FILES=\
C:\MinGW32\lib\crt2.o \
C:\MinGW32\lib\gcc\mingw32\4.7.1\crtbegin.o
COLLECT2=C:\MinGW32\libexec\gcc\mingw32\4.7.1\collect2.exe
normal:
$(CC) -c test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(DEFAULT_FLAGS) $(LIBRARY_PATH) -o test.exe
optimized:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(DEFAULT_FLAGS) $(LIBRARY_PATH) -o test.exe
smallest:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(OPTIMAL_FLAGS) $(LIBRARY_PATH) -o test.exe
ultimate:
$(CC) -c -O test.cpp
$(COLLECT2) -Bdynamic $(OBJECT_FILES) test.o -B$(type) -lstdc++ -Bdynamic $(OPTIMAL_FLAGS) $(LIBRARY_PATH) -o test.exe
strip test.exe
upx test.exe
CLEAN:
del *.exe *.o
Результаты (YMMV):
// Not stripped or compressed in any way
make normal type=static SIZE: 934KB
make normal type=dynamic SIZE: 64.0KB
make optimized type=dynamic SIZE: 30.5KB
make optimized type=static SIZE: 934KB
make smallest type=static (Linker Errors due to left out libraries)
make smallest type=dynamic SIZE: 25.6KB
// Stripped and UPXed
make ultimate type=dynamic (UPXed from 9728 bytes to 5120 bytes - 52.63%)
make ultimate type=static (Linker Errors due to left out libraries)
Возможная причина включения -Bstatic
в параметры сборки по умолчанию
для лучшей производительности. Я попытался построить astyle
с -Bdynamic
и получил
снижение скорости в среднем на 1 секунду, даже если приложение работало
меньше, чем оригинал (400 КБ против 93 КБ при UPXed).