У меня есть довольно простой проект C++, который использует повышение:: библиотека regex. Вывод, который я получаю, составляет 3.5 МБ в размере. Поскольку я понимаю, что статически связываю все повышение.CPP файлы, включая все функции/методы. Возможно, возможно так или иначе дать моему компоновщику команду использовать только необходимые элементы от повышения, не всех их?Спасибо.
$ c++ —version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659)
Это что size
говорит:
$ size a.out
__TEXT __DATA __OBJC others dec hex
1556480 69632 0 4296504912 4298131024 100304650
Я попробовал strip
:
$ ls -al
... 3946688 May 21 13:20 a.out
$ strip a.out
$ ls -al
... 3847248 May 21 13:20 a.out
PS. Это - то, как мой код организован (возможно, это - основная причина проблемы):
// file MyClass.h
class MyClass {
void f();
};
#include "MyClassImpl.h"
// file MyClassImpl.h
void MyClass::f() {
// implementation...
}
// file main.cpp
#include "MyClass.h"
int main(int ac, char** av) {
MyClass c;
c.f();
}
Что Вы думаете?
Вы компилировали с включенными отладочными символами? Это могло объяснить большую часть размера. Также как вы определяете размер двоичного файла? Предполагая, что вы работаете на платформе, подобной UNIX, используете ли вы прямую команду « ls -l
» или « size
». Эти два могут дать очень разные результаты, если двоичный файл содержит символы отладки. Например, вот результаты, которые я получаю при создании примера Boost.Regex " credit_card_example.cpp ".
$ g++ -g -O3 foo.cpp -lboost_regex-mt
$ ls -l a.out
-rwxr-xr-x 1 void void 483801 2010-05-20 10:36 a.out
$ size a.out
text data bss dec hex filename
73330 492 336 74158 121ae a.out
Аналогичные результаты возникают при простом создании объектного файла:
$ g++ -c -g -O3 foo.cpp
$ ls -l foo.o
-rw-r--r-- 1 void void 622476 2010-05-20 10:40 foo.o
$ size foo.o
text data bss dec hex filename
49119 4 40 49163 c00b foo.o
РЕДАКТИРОВАТЬ : добавлены некоторые результаты статической компоновки ...
Вот двоичный размер при статической компоновке. Это ближе к тому, что вы получаете:
$ g++ -static -g -O3 foo.cpp -lboost_regex-mt -lpthread
$ ls -l a.out
-rwxr-xr-x 1 void void 2019905 2010-05-20 11:16 a.out
$ size a.out
text data bss dec hex filename
1204517 5184 41976 1251677 13195d a.out
Также возможно, что большая часть большого размера поступает из других библиотек, от которых зависит библиотека Boost.Regex. На моем компьютере с Ubuntu зависимости для разделяемой библиотеки Boost.Regex следующие:
$ ldd /usr/lib/libboost_regex-mt.so.1.38.0
linux-gate.so.1 => (0x0053f000)
libicudata.so.40 => /usr/lib/libicudata.so.40 (0xb6a38000)
libicui18n.so.40 => /usr/lib/libicui18n.so.40 (0x009e0000)
libicuuc.so.40 => /usr/lib/libicuuc.so.40 (0x00672000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x001e2000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x001eb000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00110000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x009be000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00153000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x002dd000)
/lib/ld-linux.so.2 (0x00e56000)
Библиотеки ICU могут стать довольно большими. Помимо отладочных символов, возможно, именно они вносят основной вклад в размер вашего двоичного файла. Более того, в случае со статической связью кажется, что сама библиотека Boost.Regex состоит из больших объектных файлов:
$ size --totals /usr/lib/libboost_regex-mt.a | sort -n
0 0 0 0 0 regex_debug.o (ex /usr/lib/libboost_regex-mt.a)
0 0 0 0 0 usinstances.o (ex /usr/lib/libboost_regex-mt.a)
0 0 0 0 0 w32_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
text data bss dec hex filename
435 0 0 435 1b3 regex_raw_buffer.o (ex /usr/lib/libboost_regex-mt.a)
480 0 0 480 1e0 static_mutex.o (ex /usr/lib/libboost_regex-mt.a)
1543 0 36 1579 62b cpp_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
3171 632 0 3803 edb regex_traits_defaults.o (ex /usr/lib/libboost_regex-mt.a)
5339 8 13 5360 14f0 c_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
5650 8 16 5674 162a wc_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
9075 4 32 9111 2397 regex.o (ex /usr/lib/libboost_regex-mt.a)
17052 8 4 17064 42a8 fileiter.o (ex /usr/lib/libboost_regex-mt.a)
61265 0 0 61265 ef51 wide_posix_api.o (ex /usr/lib/libboost_regex-mt.a)
61787 0 0 61787 f15b posix_api.o (ex /usr/lib/libboost_regex-mt.a)
80811 8 0 80819 13bb3 icu.o (ex /usr/lib/libboost_regex-mt.a)
116489 8 112 116609 1c781 instances.o (ex /usr/lib/libboost_regex-mt.a)
117874 8 112 117994 1ccea winstances.o (ex /usr/lib/libboost_regex-mt.a)
131104 0 0 131104 20020 cregex.o (ex /usr/lib/libboost_regex-mt.a)
612075 684 325 613084 95adc (TOTALS)
Вы можете получить до ~ 600 КБ, поступающих только от Boost.Regex, если некоторые или все эти объектные файлы будут связаны в ваш двоичный файл.
Если вы статически связываете, то большинство компоновщиков будет включать только те объекты, которые необходимы.
3,5 МБ - это не так уж и много - в системе ПК, поэтому размер может зависеть от ОС и т. Д.
Флаг -O3
оптимизирует код не по размеру, а по скорости выполнения. Так что, возможно, например, некоторое разгрузка цикла приведет к большему размеру файла. Попробуйте скомпилировать с каким-нибудь другим флагом оптимизации. Флаг -Os
будет оптимизирован для небольшого исполняемого файла.
Если ваш порядок ссылок установлен правильно (наиболее зависимый, а затем наименее зависимый), компоновщик должен захватывать только те символы, которые фактически использует ваша программа. Кроме того, многие (но не все, и я не могу говорить о регулярных выражениях) функциональные возможности повышения только заголовков из-за использования шаблона.
Более вероятно, что отладочная информация / таблица символов и т. Д. Занимает место в вашем двоичном файле. Имена шаблонов (например, iostream и стандартные контейнеры) очень длинные и создают большие записи в таблице символов.
Вы не говорите, какую ОС вы используете, но если это вариант unix в качестве теста, вы можете фактически удалить
копию вашего двоичного файла, чтобы удалить всю лишнюю информацию и посмотреть, что осталось:
cp a.out a.out.test
strip a.out.test
ls -l a.out*
На одном двоичном файле, который я тестировал, он удалил около 90% размера файла. Обратите внимание, что если вы сделаете это, любые ядра будут бесполезны без копии нераспакованного двоичного файла для отладки - у вас не будет никаких имен символов или чего-либо еще, только сборка и адреса. 3,5 МБ - это действительно крошечный файл в наше время. Скорее всего, там просто столько отладочной / символьной информации даже из 10 КБ источника.
Вы говорите, что у вас 3 файла. Для меня MyClassImpl.h, вероятно, является .cpp, поскольку он содержит реализацию.
В любом случае, если вы фактически компилируете два файла, включая boost :: regex, вы получите в два раза больший размер boost :: regex (именно если вы используете одну и ту же функциональность в обоих файлах, у вас будет вдвое больше затрат в космосе).
Это связано с тем, что большинство функций повышения - это встроенные шаблоны.
лучший,
, если у вас есть ldd, вы можете использовать его, чтобы проверить, действительно ли вы связываетесь со всеми библиотеками boost.
Другая возможность состоит в том, что размер является побочным эффектом использования библиотек только для заголовков, многие библиотеки Boost имеют такой тип, и включение их может встраивать больше кода, чем вы могли бы поверить. Вы также можете создать своего рода комбинаторный взрыв из-за использования нескольких различных параметров шаблона.
Чтобы получить лучшую диагностику, вы должны попытаться создать действительно короткую программу с использованием регулярного выражения и посмотреть, какой размер вы получите. Если ваша программа действительно короткая, то 3,5 Месяца - это довольно много. Мой текущий исполняемый файл projet также использует BOOST (но не регулярное выражение) и имеет примерно такой же размер. Но я говорю примерно о 20000 строках C ++. Следовательно, где-то должна быть загвоздка.