Одноименные классы в приложении и LIB вызывают проблемы * после * конвертации из Makefile в Cmake
-
10-10-2019 - |
Вопрос
Я пытаюсь преобразовать программу и ее плагин из пользовательских Makefiles в Cmake, с минимальными изменениями в коде.
И плагин, и приложение обмениваются кодом; #ifdef ... #else ... #endif используются там, где есть различия, и я уверен, что код составлен с правильными определениями. Общий код включает в себя класс под названием Toolimage. Когда код будет скомпилирован для приложения, конструктор Toolimage использует другой путь ресурса, чем когда он составлен для плагина.
#ifdef THE_APP
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(wxGetApp().GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#else
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(theApp.GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#endif
{
...
}
Когда программа и ее плагин были составлены с пользовательскими засощаниями, все работает так, как и ожидалось. Когда оба были скомпилированы с Cmake, используя серию файлов cmakelists.txt, которые я создал, есть проблема: плагин не может загружать растровые карты для панели инструментов.
Я отслеживал проблему в классе Toolimage. Номер строки, заданный GDB, говорит мне, что плагин использует неправильный конструктор. Стрэйс рассказывает мне то же самое (плагин ищет свои растровые карты в Dir Resource Resource, а не в Resource Resource). Чтобы убедиться, что у меня не было определений, я поместил #Error в ToolImage.CPP, внутри части #IFDEF, который должен быть составлен только для приложения - и плагин по -прежнему составлен без ошибок. Это говорит мне, что плагин компиляется с правильным кодом. Поскольку он использует неправильный путь, я думаю, что он использует класс и конструктор, скомпилированный в программу вместо своей собственной.
Как я могу гарантировать, что плагин использует свой собственный класс Toolimage вместо того, что в приложении?! Я не владею проектом, и я не хочу вносить огромные изменения только для поддержки здания с другой системой сборки.
Использование предварительногокомпейлера для создания двух версий класса кажется для меня плохим выбором. Если я должен внести изменения в код, есть ли у вас предложения по обходному пути?
Решение 2
Я исправил это, добавив флаг линкера -WL, -BSymbolic-функции в cmakelists.txt:
set_target_properties( heekscnc PROPERTIES LINK_FLAGS -Wl,-Bsymbolic-functions )
Другие советы
Ради эксперимента я бы добавил -спрятанность = скрыто при строительстве теаппа, для всех или, возможно, к некоторым конкретным источникам. Это должно скрыть Toolimage Application от плагина.
Это не универсальный метод, так как во многих случаях плагины используют разные символы из основного исполняемого файла.