LINUX.ORG.RU

Утилита для «выдирания» зависимостей

 ,


1

2

Например, есть библиотека librsvg. Она зависит от многих разных библиотек.
Причём от каждой использует только часть функционала.
И, например, остальной функционал не нужен, потому что нужно только то что даёт librsvg.

Хочется иметь такую утилиту, которая из всех исходников «выдирает» только то, что используется конечной библиотекой.
По мере возможностей конечно.

Существует ли что-нибудь подобное? Если нет, то как считаете реально такое сделать?

★★★

Последнее исправление: CYB3R (всего исправлений: 2)

делали ldd по всем бинарникам пакета и после этого искали чего не хватает. далее выводили список - ннада эти либы, они есть в таких то пакетах.

дальше дело не пошло, сменилась концепция, но как раз подошли опять к вопросу контроля зависимостей.

irton ★★★★★
()

Было бы хорошо. Только, боюсь, неосуществимо это.

Eddy_Em ☆☆☆☆☆
()

Да, было такое (и не такое:)). Увы, сейчас не гуглится.

true_admin ★★★★★
()
Ответ на: комментарий от PolarFox

Такое есть, линкер называется.

Это не то. Нужно чтоб из исходников зависимостей выдиралось только то, что используется конечной библиотекой. То есть чтоб «лишние» исходные файлы вообще не компилировались. И, в идеале, чтоб в оставшихся файлах неиспользуемые функции удалялись.

LinuxUser ★★★
() автор топика

readelf -a filename

Если нет, то как считаете реально такое сделать?

gccxml

AGUtilities ★★★
()
Последнее исправление: AGUtilities (всего исправлений: 1)
Ответ на: комментарий от LinuxUser

И, в идеале, чтоб в оставшихся файлах неиспользуемые функции удалялись

Статически невозможно в общем случае, динамически возможно и реализовано (mmap).

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

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Даже если подавляющее большинство никогда не будет вызвано, их код вырезать нельзя, так как для таблицы нужны адреса.

Я предлагаю это делать с исходниками, а не с бинарниками.

Если в исходниках конечной библиотеки нет вызовов как-то функции, то её можно спокойно удалить.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Я предлагаю это делать с исходниками, а не с бинарниками.

А я говорил про исходники. Как ты представляешь себе работу такой утилиты в приведённом мной примере?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Что ты имеешь ввиду под «инициализацией библиотеки»?

Работу утилиты я представляю себе так:

1) Для каждого файла, каждой библиотеки вместо компилятора запускаем
   препроцессор, и анализируя полученный вывод, составляем:
  б) Для конечной библиотеки — список вызываемых внешних функций.
  в) Для зависимостей, для каждой функции — дерево вызовов внешних и внутренних функций.
2) Сопоставляя список с деревьями, находим функции, которые не будут вызываться.
Аналогичное можно проделать с переменными, константами, макроопределениями и типами.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от thesame

видел скрипт на пистоне, который это делает, если вспомню название, напишу

Вспомни, пожалуйста.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Лишние includes в коде на C++ ни одна утилита/IDE находить не умеет, а это казалось бы куда более востребовано.

kamre ★★★
()
Ответ на: комментарий от LinuxUser

Что ты имеешь ввиду под «инициализацией библиотеки»?

__attribute__((constructor))
void
library_constructor(void)
{
    printf("library loaded but no functions called.\n");
}

в) Для зависимостей, для каждой функции — дерево вызовов внешних и внутренних функций.

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

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от thesame

mklibs

Спасибо. Но это, к сожалению, не то.
Оно для готовых бинарников зависимости ищет.
А я говорю про исходники.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

++

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от i-rinat

Возможна ситуация, когда некоторая функция никогда не будет вызываться, но это нельзя определить по дереву вызовов.

Ничего страшного, таких мало, большинство зацеплю.

если вызывается функция по адресу. Один такой вызов — и уже никаких гарантий нет.

Ну где-то в коде этот адрес присваивается. Тупо включать в дерево все адреса функций присваиваемые в дереве, в смысле в функции, которая уже есть в дереве.

LinuxUser ★★★
() автор топика
Последнее исправление: LinuxUser (всего исправлений: 1)
Ответ на: комментарий от LinuxUser

Кстати, это нужно делать после линкования: на основе блоков symbols проанализировать, что за функции запускаются, поудалять неиспользуемые, а затем все нужное повыдирать из исходников библиотек.

По идее, задача вполне реализуема…

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

gcc умеет оптимизировать скомпилированный код (т.е. удалять невызываемые функции)

Умеет, но смысла в этом нет. Лет пять назад пытался это проделать. В результате выходной файл становился больше, а не меньше. А причиной было то, что gcc каждую функцию пихал в отдельную секцию.

Не знаю, может что с того времени изменилось.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Не знаю, может что с того времени изменилось.

Для ARM очень даже хорошо оптимизирует.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

чтобы уменьшить количество библиотек в системе, например.

А зачем? Записать на освободившееся место один фильм? Я не понимаю смысла экономии на бинарниках. У меня / на разделе в 13 гигов, из которых 2 свободно. Даже если сэкономить всё, получится +13 гигов места.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Например, предлагать альтернативные варианты: либо устанавливай 100500 библиотек, либо одну — сборную солянку.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от sanaris

Но постепенно autoscan потерял часть аудитории, убежавшей писать скан-скрипты на перле-питоне-етс. Не знаю как сейчас там оно, живёт да?

sanaris
()
Ответ на: комментарий от LinuxUser

Это не то. Нужно чтоб из исходников зависимостей выдиралось только то, что используется конечной библиотекой. То есть чтоб «лишние» исходные файлы вообще не компилировались. И, в идеале, чтоб в оставшихся файлах неиспользуемые функции удалялись.

man ld

anonymous
()

При статической линковке неиспользуемые функции не включаются.

anonymous
()

Не сработает, братюнь. Например, оно тянет либу xml-парсера, и пусть использует она из этой либы пару ф-й, всё равно нужен весь парсер, и 99% кода этой либы.

anonymous
()
Ответ на: комментарий от i-rinat

Да это для каких-нибудь embedded штук можно использовать, так-то смысла действительно мало.

Вон в SQLite вообще все исходники сваливают в кучу и потом одним файлом компилируют. Пишут что компиляторы лучше оптимизируют то что в одной единице трансляции (ну, в общем-то оно и понятно).

We have measured performance improvements of between 5 and 10% when we use the amalgamation to compile SQLite rather than individual source files

http://www.sqlite.org/amalgamation.html

Deleted
()
Ответ на: комментарий от Deleted

Ну так в SQLite гонятся за скоростью. А тут удаление мёртвого кода. С этим, говорят, отлично Intel C Compiler справляется, выкидывая огромные куски кода, результат которых не используется. Не могу сходу найти, но один человек тест компиляторов проводил, с перемножением матриц, если не ошибаюсь. Так icc выдал код в духе

mov eax, 0
ибо результат-то никуда не выводился, а стало быть и все вычисления не нужны.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.