LINUX.ORG.RU

Найти неиспользуемые объектные файлы

 , ,


1

1

Есть приложение, которое собирается из кучи .cpp-файлов, причём не каждый файл из этой кучи необходим для сборки. Задача: выделить только нужные .cpp. Эту задачу можно свести к поиску неиспользуемых .o (т.е. тех, что линкер может стрипнуть полностью). Как их найти?

Есть утилита nm, которая выводит список всех символов в бинарнике. Алгоритм мне видится таким: для каждого .o строим список символов, потом строим список символов для готового бинарника и сравниваем. Если ни одного символа из .o в бинарнике не видно, это лишний объектник. Только, по-моему, нужен ещё будет игнор-список для библиотечных функций, они могут тоже в выхлопе nm попадаться.

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

Вопрос толоко — зачем? При линковке все ненужные куски кода всё равно будет выкинуты.

И вообще-то это должна быть головная боль самого 'make', какой объект из какого файла собирать. (Если Makefile написан граматно, то и лишнего не собирается.)

beastie ★★★★★
()

При линкове можно указать флаг -M, покажет какие .o будет использовать. Хз как оно ведёт себя с LTO. И если бинарь собран с отладочной информацией, то можно посмотреть все сорцы (info sources в gdb), по ним можно догадаться что это были за объектники

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

-M

Парсить неудобно, но разобраться можно. Спасибо.

LTO

Ну собрать-то я могу и без оптимизаций, исходники-то есть.

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

Тоже вариант, но я надеялся, что будет готовый инструмент.

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

Чтобы выкинуть мёртвый код и лишние строчки из Makefile (он написано неграмотно, да).

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

Не проще (не автоматизируется). Вот получившийся костыль:

find_unused_obj()
{
        local -a OBJ=( "$@" )
        local TMPFILE=${TMPFILE:-deleteme}
        local file
        for file in "${OBJ[@]}";do
                OBJS=(${OBJ[@]//$file})
                g++ $LDFLAGS "${OBJS[@]}" -o "$TMPFILE" > /dev/null 2>&1 && echo "$file"   
        done
        rm -f $TMPFILE
}

find_unused_obj *.o
NeXTSTEP ★★
() автор топика
$ cat a.c 
int main() {}
$ cat b.c
void f(){}

$ gcc -c a.c
$ gcc -c b.c
$ gcc a.o b.o -o c -Wl,--gc-sections -Wl,--print-gc-sections
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../x86_64-pc-linux-gnu/bin/ld: Удаляется неиспользуемый раздел '.rodata.cst4' в файле '/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64/crt1.o'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../x86_64-pc-linux-gnu/bin/ld: Удаляется неиспользуемый раздел '.data' в файле '/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64/crt1.o'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../x86_64-pc-linux-gnu/bin/ld: Удаляется неиспользуемый раздел '.data' в файле '/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/crtbegin.o'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../x86_64-pc-linux-gnu/bin/ld: Удаляется неиспользуемый раздел '.text' в файле 'b.o'

Норм? :]

Для более детального вывода (по секции на функцию) у gcc есть CFLAGS -ffunction-sections и -fdata-sections. Так '-Wl,--print-gc-sections' даже про части неиспользуемых объектников говорить.

Сверху предлагали ругаться на неиспользуемые в других модулях символы. Есть такой костыль: https://github.com/trofi/uselex/blob/master/uselex.rb#L18

sf ★★★
()

function-level linking

Пацаны из оффтоп-конторы, в своём компиляторе сто лет в обед имеют ключ /Gy, который задействует так называемое «function-level linking» (наверно кроме используемого говнокода у них полно неиспользуемого, не то что в опенсорсе, где всё нужно).

Используя фразу в кавычках или из заглавия, и добавив ключевое слово gcc, можно гуглом найти велосипед http://stackoverflow.com/questions/7319125/function-level-linking-in-gcc

и два ключа для gcc.

Но, городить собственное, это же Ъ, правда?

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