Статическая компоновка Android против динамической компоновки против glibc

Я кросс-компилировал некоторые инструменты Linux (и часть моего собственного кода C) для Android, и одна из проблем, с которыми я сталкиваюсь, заключается в том, что в libc Android есть некоторые отсутствующие / лишенные компоненты, и я в конечном итоге исправляю свой код, чтобы он работал с Libc Android (например, для такой проблемы http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html).

Q1: Как мне выполнить статическое связывание с glibc (и другими зависимостями) во время кросс-компиляции с помощью инструментария arm (или ndk-build)?

Q2: Это хорошая идея - использовать статическую ссылку на glibc для двоичных файлов для Android? Стоит ли ожидать, что что-нибудь сломается, если я начну статически связываться? Есть ли проблемы с производительностью / памятью?

Я понимаю большинство плюсов и минусов статического и динамического связывания отсюда - Приложение C ++ - следует ли использовать статическое или динамическое связывание библиотек? и Статические и динамические ссылки

Поэтому я хочу знать, следует ли мне статически связывать glibc для Android при кросс-компиляции двоичных файлов.


person angadsg    schedule 30.04.2012    source источник


Ответы (2)


Сначала небольшое примечание о libc. Android libc - это Bionic libc (скорее, https://github.com/android/platform_bionic/) чем GNU libc (glibc). Таким образом, libc, содержащаяся в NDK, является Bionic, как и libc, доступная на устройствах Android.

Что касается glibc, его можно собрать с помощью NDK. Однако его имя будет конфликтовать с системной libc при установке на устройства Android. Обратите внимание, что это только в том случае, если вы собираетесь создавать динамическую библиотеку. Если вы создаете GNU libc как статическую библиотеку, тогда вся проблема, описанная выше, будет обойдена, поскольку вам никогда не нужно устанавливать статическую библиотеку.

Теперь отвечу на ваши вопросы:

  1. В1: Если вы создаете glibc с помощью NDK, то Android.mk использует переменную BUILD_STATIC_LIBRARY для создания статических библиотек. Однако, если вы не используете NDK, вам, вероятно, придется столкнуться с большой головной болью (не знаю, сколько). Я не могу рассказать вам больше об этом, так как я не пробовал сборки glibc, статической или динамической. Кроме того, кажется, что статическое связывание с glibc крайне не рекомендуется, по крайней мере, для немобильных платформ.

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

Что касается проблем с отсутствующей функциональностью bionic libc, вы можете использовать метод, используемый в большинстве программ GNU, то есть предоставить свою собственную реализацию функции на случай, если она отсутствует в системных библиотеках. Я скомпилировал file-5.11, GNU make 3.82, diffutils-2.8 для Android, передав набор инструментов NDK / includes / libs в autotools (./configure ...). Кажется, что эти программы содержат реализации большей части неосновных библиотечных функций, если стандартные библиотеки не предоставляют их (в данном случае Bionic).

Примечание: я попытаюсь создать статический glibc и обновлять ответ по мере успеха / неудачи.

person Samveen    schedule 01.05.2012
comment
Это не только использование на диске - также увеличивается использование памяти. Когда вы связываете библиотеки jni и приложения Android с Bionic libc, вы наследуете общий доступ только для чтения к копии, уже находящейся в памяти. - person Chris Stratton; 01.05.2012
comment
Не могли бы вы указать на ваш источник информации по этому поводу? Я хочу узнать больше, но ничего не могу найти по этому поводу. Я знаю, что если библиотеки содержат какие-либо данные, данные, кажется, не разделяются между процессами, однако это может быть просто репликацией страниц памяти с копированием при записи, если код библиотеки изменяет свои внутренние переменные данных. - person Samveen; 03.05.2012
comment
Я считаю, что Крис Страттон упоминает - случай статически связанной библиотеки libc. Каждый процесс будет иметь свою собственную полную копию ВСЕХ разделов одной и той же библиотеки. С динамической компоновкой вы правы @Samveen - person Tuxdude; 01.09.2012

Если вы собираетесь использовать glibc вместо bionic, возможно, стоит изучить использование инструментальной цепочки дистрибутива arm-linux (поколения совместимого ядра), а не ndk. Это было бы особенно верно, если бы вы создавали исполняемый файл командной строки. (Люди экспериментально перенесли среду chroot debian на устройства Android полностью обратно в G1)

Для jni sub (который остается единственным официально одобренным средством для нативного кода приложения) он может стать немного «интересным» с любой цепочкой инструментов, поскольку вы будете работать в процессе, который уже отображен и постоянно использует бионическую библиотеку libc. для поддержки Dalvik VM. Предположительно, если вы статически связываете собственные зависимости библиотеки, вы не столкнетесь с конфликтами имен, но я ожидаю, что какой бы путь вы ни выбрали, это будет познавательным опытом о внутренней работе - не то чтобы это обязательно плохо.

Вам нужны ncurses? Однажды я успешно построил проклятия для Android с помощью ndk. Также подумайте, серьезно ли это используется в программе (например, вы действительно выполняете существенное форматирование текста?) Или просто используете его для какой-то мелочи, потому что предполагалось, что оно будет доступно в целевых системах?

person Chris Stratton    schedule 01.05.2012
comment
Вы можете подойти и ответить на этот вопрос: stackoverflow.com/questions/10798357/ - person Prof. Falken; 29.05.2012