выборочно отключить удаление мертвого кода в библиотеке - PullRequest
0 голосов
/ 10 октября 2019

У меня много cpp-файлов, некоторые из которых имеют функции для самостоятельной подписки на события. К сожалению, большинство компоновщиков удаляют все символы из модулей компиляции, если в них нет явного вызова функции. Есть ли способ принудительно связать эти функции подписки? Я не хочу полностью отключать удаление мертвого кода, потому что я могу упустить множество возможностей других модулей перевода.

Subscriber.cpp:

Event &someEvent();

void doSomething()
{
  printf("doing something\n");
}

class Initializer
{
  public: Initializer()
  {
    // I need this function to be kept
    someEvent().subscribe(&doSomething);
  }
} initializer;

Main.cpp:

Event &someEvent();

int main()
{
  someEvent().dispatch();
}

Спасибо

РЕДАКТИРОВАТЬ:

Вот сборка репро: https://github.com/malytomas/deadCodeElimination (Спасибо Ayjay за помощь, даже если его / ее пример не воспроизводитпроблема.)

Проблема возникает только с библиотеками. (Спасибо наемному русскому за то, что подняли это.)

1 Ответ

2 голосов
/ 10 октября 2019

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

Вы ошибаетесь: компоновщик, который сделает это, будет сломанлинкер. Компоновщики не код для сбора мусора, который регистрирует глобальные конструкторы или деструкторы.

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

Обновление:

Теперь, когдамы видим репро, ваш актуальный вопрос не имеет ничего , связанного с удалением мертвого кода. Как я и подозревал, subscriber.o просто не извлекается из libsubscriber.a, потому что компоновщик не находит причин для этого.

Вот фактическая команда ссылки:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main libsubscriber.a

Здесьэто команда, которую вы хотите иметь:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main \
  -Wl,--whole-archive libsubscriber.a -Wl,--nowhole-archive

Я не знаю, как этого добиться с помощью CMake, извините.

В качестве альтернативы, вы также можете достичь желаемого эффекта с помощью:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main \
 -u _Z19forceLinkSubscriberv libsubscriber.a
...