Нужно ли повторно выполнять мой исполняемый файл, когда изменяется библиотека, используемая библиотекой, которую я использую?

Представьте, что у нас есть исполняемый exe- файл, который зависит от разделяемой библиотеки foo, которая, в свою очередь, зависит от панели разделяемой библиотеки: exe требуется libfoo.so, а foo - libbar.so. Затем полоса изменяется совместимым с источником способом (т.е. API-интерфейс остается неизменным), но не двоично-совместимым образом (то есть изменяется ABI). Поэтому мы должны пересвязать (или столкнуться с ошибками сегментации).

Вопрос в том, что именно нужно перекомпилировать / перекомпоновать?


Позвольте мне сделать это немного более конкретным. Чтобы связать exe, нам не нужно добавлять опцию компилятора "-lbar", тогда как нам нужна эта опция для связывания foo:

gcc -fPIC -shared -I. -Ibar -lbar -o libfoo.so foo.o
gcc -fPIC -I. -Ifoo -Ibar -lfoo -o exe exe.o
  1. Следовательно, достаточно ли связать foo и оставить exe как есть?

  2. Нужно ли перекомпиляции foo и exe (если bar изменен, но его API не изменился)?

Наконец, я попытался оставить foo без изменений, но пересмотрел exe с добавленной опцией компилятора "-lbar":

gcc -fPIC -I. -Ifoo -Ibar -lfoo -lbar -o exe exe.o

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

  1. Разрешено ли это делать, то есть оставить foo без изменений, но явно связать exe с bar?

Несколько связанных чтений: [ 1] [ 2] [ 3] [ 4] [ 5]

1 ответ

Пока эксперт не ответит, это мои собственные гипотезы:

  1. Учитывая, что компоновщик не требует "-lbar" для exe, я склонен сделать вывод, что exe не нуждается в повторной линковке, так как компоновщик, очевидно, не нуждается в bar. Тем не менее, я очень не уверен в этом, так как это предполагает, что компоновщик не находит панель через foo. (В конце концов, ldd libfoo.so покажет мне бар, поэтому я бы сказал, что компоновщик может обладать знаниями о том, что ему нужен бар.)

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

  3. Похоже, что это разрешено... Но я не уверен. Кроме того: любой исполняемый файл / библиотека, которая зависит от foo, кроме exe, все равно будет сталкиваться с ошибками сегментации, так что это будет плохой практикой, не так ли?

Другие вопросы по тегам