Как компоновщики решают что части библиотек включать?

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

Итак, да, экземпляр EC2 физически работает в этом месте.

Список регионов AWS доступен по адресу: Глобальная облачная инфраструктура | Регионы и Зоны доступности | АМС

9
задан Oliver Zheng 3 April 2009 в 20:04
поделиться

9 ответов

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

Также смотрите на реализацию LLVM (и раздел в качестве примера).

Я предлагаю, чтобы Вы также смотрели на Компоновщиков и Загрузчики John Levine - превосходное чтение.

9
ответ дан 4 December 2019 в 10:05
поделиться

Это зависит.

Если библиотека является общим объектом или DLL, то все в библиотеке загружается, но во время выполнения. Стоимость в дополнительной памяти (надо надеяться), смещается путем совместного использования библиотеки (действительно, кодовые страницы) между всеми процессами в памяти, которые пользуются той библиотекой. Это - большая победа для чего-то как libc.so, меньше для myreallyobscurelibrary.so. Но Вы, вероятно, не спрашиваете об общих объектах, действительно.

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

Задание компоновщика состоит в том, чтобы создать законченный исполняемый файл, который не имеет никаких остающихся неопределенных импортированных символов. (Я лежу, конечно, если динамическое подключение позволяется, но терпите меня.), Чтобы сделать это, это запускается с модулей, названных явно на командной строке ссылки (и возможно неявно в ее конфигурации), и предполагает, что любой модуль, именованный явно, должен быть частью законченного исполняемого файла. Это затем пытается найти определения для всех неопределенных символов.

Обычно, модули именованного объекта ожидают получать символы от некоторой библиотеки такой как libc.a.

В Вашем примере у Вас есть единственный модуль, который вызывает функцию a(), который приведет к компоновщику, ищущему модуль, который экспортирует a().

Вы говорите что библиотека под названием (на Unix, вероятно libA.a) предложения a() и b(), но Вы не указываете как. Вы подразумевали это a() и b() не называйте друг друга, которого я приму.

Если libA.a был создан из a.o и b.o где каждый определяет соответствующую единственную функцию, затем компоновщик будет включать a.o и проигнорируйте b.o.

Однако, если libA.a включенный ab.o это определило обоих a() и b() затем это будет включать ab.o в ссылке, удовлетворяя потребность в a(), и включая неиспользованную функцию b().

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

Что-то еще для знания - то, что большинство компоновщиков делает так мало передач, как они могут через файлы и библиотеки, которые называют на командной строке и создают их таблицу символов, когда они идут. На практике это означает, что это - хорошая практика, чтобы всегда указать библиотеки после всех объектных модулей на командной строке ссылки.

8
ответ дан 4 December 2019 в 10:05
поделиться

Обычно (статические) библиотеки состоят из объектов, созданных из исходных файлов. То, что обычно делают компоновщики, включают объект, если на функцию, которая обеспечивается тем объектом, ссылаются. если Ваш исходный файл только содержит одну функцию, чем только, что функция будет введена компоновщиком. Существуют более сложные компоновщики там, но большая часть C базировалась, компоновщики все еще работают как обрисованный в общих чертах. Существуют инструменты, доступные, которые разделяют источник C, которые содержат несколько функций в искусственно меньшие исходные файлы для создания статического подключения более прекрасным детализированный.

Если Вы пользуетесь совместно использованными библиотеками затем, Вы не влияете на Вас скомпилированный размер при помощи более или менее их. Однако Ваш размер во время выполнения будет включать их.

2
ответ дан 4 December 2019 в 10:05
поделиться

Это зависит от компоновщика.

например, Microsoft Visual C++ имеет опцию "Enable function level linking", таким образом, можно включить его вручную.

(Я предполагаю, что у них есть причина того, чтобы не просто разрешить всему этому время..., возможно, соединение медленнее или что-то),

1
ответ дан 4 December 2019 в 10:05
поделиться

Без любой оптимизации, да, это будет включено. Компоновщик, однако, смог оптимизировать путем статичного анализа кода и попытки удалить недостижимый код.

0
ответ дан 4 December 2019 в 10:05
поделиться

Эта лекция в Академической Земле дает довольно хороший обзор, с соединением говорят о близости более поздняя половина разговора, IIRC.

1
ответ дан 4 December 2019 в 10:05
поделиться

Это зависит от компоновщика, но в общем только функционирует, которые на самом деле называют, включены в заключительный исполняемый файл. Компоновщик работает путем поиска имени функции в библиотеке и затем использования кода, связанного с именем.

Существует очень немного книг о компоновщиках, который является странным, когда Вы думаете, насколько важный они. Текст для хорошего может быть найден здесь.

0
ответ дан 4 December 2019 в 10:05
поделиться

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

$ cat foo.c
int main(){}

$ gcc -static foo.c

$ size
   text    data     bss     dec     hex filename
 452659    1928    6880  461467   70a9b a.out

# force linking of libz.a even though it isn't used
$ gcc -static foo.c -Wl,-whole-archive -lz -Wl,-no-whole-archive

$ size
   text    data     bss     dec     hex filename
 517951    2180    6844  526975   80a7f a.out
0
ответ дан 4 December 2019 в 10:05
поделиться

Это зависит от компоновщика и как библиотека была создана. Обычно библиотеки являются комбинацией объектных файлов (библиотеки импорта являются основным исключением к этому). Компоновщики старшего возраста вытянули бы вещи в изображение выходного файла при гранулярности объектных файлов, которые были помещены в библиотеку. Таким образом, если функция a() и функция b() были оба в том же объектном файле, они оба были бы в выходном файле - даже если бы на только одну из 2 функций на самом деле сослались.

Это - причина, почему Вы будете часто видеть ориентированные библиотекой проекты с политикой единственной функции C на исходный файл. Тем путем каждая функция упаковывается в ее собственном объектном файле, и у компоновщиков нет проблемы при втягивании только, на что ссылаются.

Обратите внимание однако, что у более новых компоновщиков (конечно, более новые компоновщики Microsoft) есть способность втянуть только части объектных файлов, на которые ссылаются, таким образом, существует меньше потребности сегодня для осуществления one-function-per-source-file политики - хотя существуют разумные аргументы, что это должно быть сделано так или иначе для пригодности для обслуживания.

0
ответ дан 4 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: