Классы с одинаковыми именами в app и lib вызывают проблемы * после * конвертации из Makefile в cmake

Я пытаюсь преобразовать программу и ее плагин из пользовательских 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
{
 ...
}

Когда программа и ее плагин скомпилированы с пользовательскими файлами Makefile, все работает как положено. Когда оба скомпилированы с использованием CMake, используя серию созданных мной файлов CMakeLists.txt, возникает проблема: плагин не может загружать растровые изображения для своей панели инструментов.

Я отследил проблему до класса ToolImage. Номер строки, данный gdb, говорит мне, что плагин использует неправильный конструктор. strace говорит мне то же самое (плагин ищет свои растровые изображения в директории ресурсов приложения, а не в директории ресурсов плагина). Чтобы убедиться, что у меня нет облажанных определений, я поместил #error в ToolImage.cpp, внутри части #ifdef, которая должна компилироваться только для приложения - и плагин все еще компилируется без ошибок. Это говорит мне, что плагин компилируется с правильным кодом. Поскольку он использует неправильный путь, я думаю, что он использует класс и конструктор, скомпилированные в программу, а не свои собственные.

Как мне убедиться, что плагин использует свой собственный класс ToolImage вместо класса в приложении?! Я не являюсь владельцем проекта и не хочу вносить значительные изменения просто для поддержки сборки с другой системой сборки.

Использование прекомпилятора для создания двух версий класса кажется мне плохим выбором. Если я должен внести изменения в код, есть ли у вас предложения для обхода?

2 ответа

Решение

Я исправил это, добавив флаг компоновщика -Wl,-Bsymbolic-functions в CMakeLists.txt:

set_target_properties( heekscnc PROPERTIES LINK_FLAGS -Wl,-Bsymbolic-functions )

Ради эксперимента я бы добавил -fvisibility=hidden при сборке приложения, ко всем или, возможно, к некоторым конкретным источникам. Это должно скрыть ToolImage приложения от плагина.

Это не универсальный метод, так как во многих случаях плагины используют разные символы из основного исполняемого файла.

Другие вопросы по тегам