Удалить мертвый код перед установкой ссылки

В проекте, который состоит из нескольких статически связанных объектных файлов, я заменяю один из них отдельной реализацией. Я хотел бы проверить свой код еще до того, как реализовал каждый символ, предоставленный замененным объектным файлом, поэтому я использую -Wl,--unresolved-symbols=ignore-all чтобы компоновщик не жаловался на отсутствующие символы.

Но когда я тестирую код, он просто вылетает при попытке использовать один из неопределенных символов. Поэтому я ищу способ сообщить компоновщику: "Пожалуйста, удалите весь код без ссылок перед связыванием, а затем скажите мне, если в коде, доступном с точки входа, все еще есть символы без ссылок". Это возможно?

1 ответ

Тщательно составив ответ, основываясь на комментариях, я нашел это в своей собственной кодовой базе и проверил, что метод работает нормально для меня.

int do_things(void);

int application_main(void)
{
  return do_things();
}

int test_main(void)
{
  return 42;
}

int main(void)
{
  return test_main();
}

Макет примерно отражает мой вариант использования. Данный блок IR может иметь две точки входа, одну для выполнения модульных тестов и одну для выполнения того, для чего используется код. Модульные тесты нуждаются в подмножестве символов, необходимых для всего модуля. Преимущество состоит в том, что вы можете собрать часть для модульного тестирования, не создавая ничего другого.

Deadstripping - это определенное улучшение по сравнению с моим предыдущим методом -Wl,--unresolved-symbols=ignore-all

clang demo.c     # undefined reference to `do_things'
clang -O3 demo.c # undefined reference to `do_things'
clang demo.c -c -emit-llvm -o demo.bc # OK

llvm-nm demo.bc 
---------------- T application_main
                 U do_things
---------------- T main
---------------- T test_main
clang demo.bc    # undefined reference to `do_things'

opt -o stripped.bc -internalize -internalize-public-api-list=main -globaldce demo.bc
llvm-nm stripped.bc 
---------------- T main
---------------- t test_main
clang stripped.bc # OK

Список открытых символов может быть получен из файлов ir (по крайней мере, в моем случае), поэтому вызов opt на самом деле

 opt -internalize -internalize-public-api-list=`llvm-nm -extern-only -defined-only -just-symbol-name some-file.bc` -globaldce -O2
Другие вопросы по тегам