Как определить, какие объектные файлы действительно необходимы для связывания? - PullRequest
5 голосов
/ 09 июля 2010

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

Теперь я бы хотел сократить количество кода, который я создаю и связываю. Есть ли простой способ определить, какой из файлов с открытым исходным кодом мне действительно нужно скомпилировать? В пакете с открытым исходным кодом, скажем, 40 .c файлов. Я предполагаю, что мой код использует (или заставляет быть использованным) 20-й из этих файлов. В настоящее время я собираю их все и выкидываю все на компоновщик. Должен быть умный (и простой?) Способ определить, какие из них мне действительно нужны, верно?

Я рад предоставить дополнительную информацию, если это будет полезно. Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 09 июля 2010

Столкнувшись с этим, я либо просто взял команду final link, удалил все объекты и затем добавил обратно, пока она не заработала, либо обработал вывод команды nm.

Рабочий пример:

Глядя на вывод нм:

$ nm *.o

a.o:
00000000 T a
         U aa

b.o:
00000000 T b

t.o:
         U a
         U b
00000000 T main

ua.o:
00000000 T ua

ub.o:
00000000 T ub

Итак, я создаю следующий сценарий awk

# find-unused.awk
BEGIN {req["main"]="crt"}

/\.o\:$/{
    gsub(/\:/,"");
    modulename=$0;
}

$1=="U"{
    req[$2] = modulename;
}

/[0-9,a-f].* T/{
    def[$3] = modulename;
}

END{
    print "modules referenced:"
    for (i in req)
    {
        if (def[i] != "")
            print "    "def[i];
    }

    print "functions not found"
    for (i in req)
    {
        if (def[i] == "")
            print "    "i;
    }
}

и затем назовите это так;

$ nm *.o|awk -f find-unused.awk

это говорит мне:

modules referenced:
    t.o
    a.o
    b.o
functions not found
    aa

Что верно - потому что функции ua & ub в приведенном выше примере не используются.

2 голосов
/ 09 июля 2010

Посмотрите, сможете ли вы заставить стриптизершу мертвого кода сообщить вам, какие функции / символы были удалены во время ссылки. Тогда вы будете знать, какой исходный код вы можете безопасно удалить. Опция компоновщика GNU -map может быть полезна на этом фронте. Вы можете, например, скомпоновать один раз без разборки мертвого кода, затем снова связать с разбором мертвого кода и сравнить файлы выходных карт.

Если максимум 40 исходных файлов, стоит ли эта оптимизация вашего времени?

...