Как сделать так, чтобы неиспользованные символы не были связаны с конечным исполняемым файлом? - PullRequest
0 голосов
/ 26 ноября 2010

Прежде всего мои извинения тем из вас, кто следил за моими вопросами, опубликованными в последние несколько дней. Это может показаться немного повторяющимся, так как я задавал вопросы, связанные с -ffunction-section & -fdata-секции, и этот вопрос находится на одной линии. Эти вопросы и ответы на них не решили мою проблему, поэтому я понял, что лучше всего изложить здесь всю проблему и позволить экспертам SO обдумать это. Извините, что не сделал этого раньше.

Итак, вот моя проблема:

Я создаю набор статических библиотек, которые предоставляют множество функций. Эти статические библиотеки будут предоставлены многим продуктам. Не все продукты будут использовать все функции, предоставляемые моими библиотеками. Проблема в том, что размеры библиотек довольно велики, и продукты хотят, чтобы они были уменьшены. Основная цель - уменьшить конечный размер исполняемого файла, а не сам размер библиотеки.

Теперь я провел некоторое исследование и обнаружил, что, если в исходном файле есть 4 функции и только одна функция из них используется приложением, компоновщик все равно включит остальные 3 функции в конечный исполняемый файл. поскольку все они принадлежат одному объектному файлу. Далее я проанализировал и обнаружил, что -ffunction-section, -fdata-секции и -gc-секции (эта опция является компоновщиком) гарантируют, что будет связана только одна функция.

Но эти опции по некоторым причинам, не зависящим от меня, теперь не могут быть использованы.

Есть ли другой способ, которым я могу гарантировать, что компоновщик будет связывать только функцию, которая строго обязательна, и исключать все другие функции, даже если они находятся в одном объектном файле?

Есть ли другие способы решения проблемы?

Примечание. Реорганизация моего кода практически исключена, поскольку он является устаревшим и большим.

Я имею дело в основном с VxWorks & GCC.

Спасибо за любую помощь!

1 Ответ

3 голосов
/ 26 ноября 2010

В конечном счете, единственный способ убедиться, что связаны только те функции, которые вам нужны, состоит в том, чтобы каждый исходный файл (объект) в библиотеке экспортировал только один символ функции - одну (видимую) функцию на файл.Как правило, есть некоторые файлы, которые экспортируют несколько функций, которые всегда все используются вместе - например, функции инициализации и финализации для пакета.Кроме того, часто есть функции, используемые экспортируемой функцией, которые не должны быть видны вне файла источника (объекта) - убедитесь, что они static.

Если вы смотрели на Plauger's * Стандартная библиотека C", вы обнаружите, что каждая функция реализована в отдельном файле, даже если длина файла составляет 4 строки (один заголовок, одна строка функции, открытая скобка, одна строка кода изакрой скобку).


Джей спросил:

В случае большого проекта, не станет ли трудно управлять таким количеством файлов?Кроме того, я не нахожу много проектов с открытым исходным кодом, следующих этой модели.OpenSSL является одним из примеров.

Я не говорил, что он широко использовался - это не так.Но это способ убедиться, что двоичные файлы сведены к минимуму.Компилятор (компоновщик) не сделает минимизацию за вас - по крайней мере, я не знаю ни одного, что делает.В большом проекте вы проектируете исходные файлы так, чтобы тесно связанные функции, которые обычно все будут использоваться вместе, группировались в единые исходные файлы.Функции, которые используются только изредка, должны быть помещены в отдельные файлы.В идеале, редко используемые функции должны быть в отдельном файле;если это не удалось, сгруппируйте их в небольшие (но не минимальные) файлы.Таким образом, если используется одна из редко используемых функций, вы получаете только ограниченное количество дополнительного неиспользуемого кода, связанного.

Что касается количества файлов - да, используемая методика действительно означает много файлов.Вы должны взвесить нагрузку, связанную с управлением (именованием) большого количества файлов, с преимуществами минимального размера кода.Автоматические системы сборки снимают большую часть боли;Системы VCS обрабатывают множество файлов.

Другой альтернативой является помещение кода библиотеки в общий объект - или динамически подключаемую библиотеку (DLL).Затем программы связываются с общим объектом, который загружается в память только один раз и распределяется между программами, использующими его.(Непостоянные) данные реплицируются для каждого процесса.Это уменьшает размер программ на диске за счет исправлений в процессе загрузки.Однако вам не нужно беспокоиться о размере исполняемого файла;исполняемые файлы не включают общие объекты.И вы можете обновить библиотеку (если вы осторожны), не перекомпилировав основные программы, которые ее используют.Уменьшенный размер исполняемых файлов - одна из причин популярности разделяемых библиотек.

...