Я пытался создать приложение wxWidgets C++ под своей EndeavourOS (по своей сути это должен быть Arch Linux).
Моя среда рабочего стола — KDE Plasma (Wayland). Но те же проблемы возникают и в GNOME, и в XFCE.
Мне уже удалось скомпилировать C++-приложение wxWidgets под Windows.
Но в Linux моя скомпилированная простая программа:
// g++ main.cpp -o prog `wx-config --cppflags --libs`
#include <wx/wx.h>
class MyFrame: public wxFrame{
public:
MyFrame() : wxFrame(nullptr, wxID_ANY, "WxWidgets Linux Program") {
wxPanel* mainPanel = new wxPanel(this);
wxButton* cancel = new wxButton(mainPanel, wxID_ANY, "Cancel");
SetClientSize(500, 50); // it seems that this makes the program crash
Center(); // and this also
}
};
class App : public wxApp {
public:
bool OnInit() {
MyFrame* w = new MyFrame();
w->Show();
return true;
}
};
wxIMPLEMENT_APP(App);
...вылетает:
./prog: /usr/lib/libwx_gtk3u_core-3.2.so.0: no version information available (required by ./prog)
./prog: /usr/lib/libwx_baseu-3.2.so.0: no version information available (required by ./prog)
./prog: Symbol `_ZTV8wxButton' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV9wxControl' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV12wxButtonBase' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV11wxAnyButton' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV11wxPanelBase' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV7wxPanel' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV17wxMDIClientWindow' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV7wxFrame' has different size in shared object, consider re-linking
Speicherzugriffsfehler (Speicherabzug geschrieben)
// english translation: Memory access error (memory dump written)
Program terminated with signal SIGSEGV, Segmentation fault.
Это трассировка стека, которую я получаю с помощью GDB:
User
(gdb) bt
#0 0x00006e6f74747562 in ??? ()
#1 0x00007ffff7950f43 in wxWindow::PreCreation (this=this@entry=0x55555566ef80, parent=parent@entry=0x555555724500, pos=..., size=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/gtk/window.cpp:2953
#2 0x00007ffff79533f3 in wxWindow::Create (this=0x55555566ef80, parent=0x555555724500, id=-1, pos=..., size=..., style=2621440, name=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/gtk/window.cpp:2841
#3 0x00007ffff77abf16 in wxPanelBase::Create (this=0x55555566ef80, parent=<optimized out>, id=<optimized out>, pos=<optimized out>, size=<optimized out>, style=<optimized out>, name=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/common/panelcmn.cpp:98
#4 0x0000555555564da0 in wxPanel::wxPanel(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&) ()
#5 0x0000555555565b84 in MyFrame::MyFrame() ()
#6 0x0000555555565da0 in App::OnInit() ()
#7 0x0000555555563e79 in wxAppConsoleBase::CallOnInit() ()
#8 0x00007ffff70f1452 in wxEntry (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/common/init.cpp:481
#9 0x000055555556354b in main ()
Странно то, что следующий код работает нормально (за исключением того, что масштабирование окна иногда приводит к зависанию программы)
#include <wx/wx.h>
class App : public wxApp {
public:
bool OnInit() {
wxFrame* window = new wxFrame(NULL, wxID_ANY, "GUI Test", wxDefaultPosition, wxSize(600, 400));
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* text = new wxStaticText(window, wxID_ANY, "Well Done!\nEverything seems to be working",
wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL);
text->SetFont(wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
sizer->Add(text);
window->SetClientSize(300, 300);
window->SetSizer(sizer);
window->Show();
return true;
}
};
Мое первое подозрение заключалось в том, что вы комбинируете разные заголовки и библиотеки (т.е. они могут не совпадать).
@Igor Я использую версию 3.2.4.0 (согласно wx-config --version-full). ДЛЯ библиотеки - я установил wxwidgets через консоль, но это привело к ошибкам, которые я написал выше. Затем я сам собрал библиотеку (скачал самую последнюю версию с официального сайта wxWidgets), что привело к тем же проблемам. У меня та же версия wxwidgets в Windows, но это не имеет значения, поскольку предоставленный мной код запускался изолированно, в новом каталоге под Linux. К сожалению, я не очень понимаю, как собрать минимальный образец. По крайней мере, я нашел его сам (новичок здесь).
@ChristianStieber, судя по другим комментариям ниже, я сам теперь в это верю. Но как я могу проверить, где я ссылаюсь на неправильные библиотеки? Я очень озадачен тем, почему каждое руководство yt, в котором показано, как скомпилировать простую программу wxwidgets, не работает только на моей машине.
@tbone, используйте менеджер репозитория, который использует ваш дистрибутив, для удаления установленной вами библиотеки. Избавьтесь от него полностью. (Скорее всего, он находится внутри /usr/lib{64}/wx. Если вы запускали make install, запустите make distclean из каталога сборки. Или, если хотите, переустановите ОС. Загрузите исходные коды и соберите ее вручную. Дон не запускаю make install. Теперь выполните - "g++ *.cpp -o test ``/full/path/to/wx-config --cxxflags --libs`"
@tbone, идея состоит в том, чтобы на машине была только одна копия wxWidgets. В ответе я постараюсь дать вам пошаговые инструкции по сборке библиотеки и образца.





Я согласен с анализом, что, скорее всего, имеет место нарушение ODR. Скорее всего (с этим воспроизводителем) это вызвано конфликтом версий библиотек во время сборки и выполнения.
На моем компьютере NixOs я построил простую оболочку nix:
NixOs отлично справляется с разделением зависимостей, но в обычном Linux пути не будут уникальными, и вместо этого вы можете увидеть что-то вроде /usr/lib/x86_64/libwx_gtk...-.so, связанное с определенной версией. Если это не та версия, которую вы используете, вы рискуете UB из-за нарушения ODR.
Обратите внимание, что речь не обязательно идет о версиях Wx/GTK. Это может быть любая зависимость компоновщика во время выполнения.
Примечание:
interactive Gnome3/Wayland demo
interactive KDE Plasma5/Wayland demo
ПС. Я управляю Hyprland/Wayland. Также протестирую под Gnome/Wayland на случай, если помешает какая-нибудь странная ошибка Wx.
Нет проблем в Gnome/Wayland imgur.com/a/D7mybFT
Также нет проблем на Plasma5/Wayland imgur.com/a/D7mybFT . Я отмечаю, что жестко закодированный размер (500, 50) кажется меньше минимальной высоты в соответствии с интерактивным изменением размера Plasma5 (см. сами в видео). Вполне возможно, что это как-то связано с этим. Моя плазменная оболочка — v5.27.11. Возможно, в этой области уже исправлена ошибка GTK или оконного менеджера?
Почему вы игнорируете предупреждения о несовместимости ABI, которые вы получаете и которые явно указывают на проблему?
Вы ничего не говорите о том, как вы создаете свое приложение, но эти сообщения недвусмысленно показывают, что оно использует библиотеки, не соответствующие заголовкам, с которыми оно было скомпилировано. Вам необходимо исправить это, гарантируя, что вы связываетесь с правильными библиотеками и что во время выполнения обнаруживаются одни и те же библиотеки (а не какой-то другой вариант).
Уважаемый ВЗ., хм, кажется, сноску на моих вопросах "я во всем этом чертов новичок" удалили. Я не игнорировал предупреждения. Я просто не понимаю таких. Зачем быть таким токсичным? Как я могу обеспечить правильное связывание - как мне вообще узнать, какой файл библиотеки вызывает проблему?
@tbone VZ не токсичен. Он однозначно говорит, в чем проблема. Вместо того, чтобы обижаться, примите, что он прямо ответил на ваш заданный вопрос. Если вам нужна помощь в понимании ответа, просто попросите об этом.
Чтобы собрать библиотеку и минимальный образец:
cd wxWidgets
mkdir buildGTK
cd buildGTK
../configure --enable-debug --with-gtk && make -j4
cd samples/minimal
make
./minimal
Это должно собрать библиотеку и минимальный образец.
Сообщите нам, если во время этого процесса возникнут какие-либо ошибки.
Помните - это должно быть сделано в "чистой среде" - без установленной версии wxWidgets.
Затем, когда все будет завершено и у вас будет запущен минимальный образец, выполните:
g++ *.cpp -o test `/full/path/to/wx-config --cxxflags --libs`
Невероятно – это сработало! Что я еще сделал, так это удалил остатки других установок wx, но я просто использовал путь к папке buildGTK, когда дело дошло до части wx-config, и — бум! Однако собрать минимальный образец с помощью последней команды g++ не удалось, но, тем не менее, мой пример кода заработал! Я до сих пор не понимаю, что я мог сделать не так, установив wxwidgets, как указано во всех видео на YouTube. Что ж, думаю, теперь мне придется удалить все предыдущие wxwidgets и попытаться установить wxWidgets buildGTK где-нибудь на моем диске :)
@tbone, пожалуйста, поймите - я не предлагал создавать сэмплер minimal с помощью g++. Все, что я сделал, это посоветовал вам перейти в каталог buildGTK/samples/minimal и ввести команду make. Команда g++, на которую вы ссылаетесь, предназначена для вашего собственного кода. Но вам больше не нужно создавать образец. Просто сохраните библиотеку, которую вы собрали, и все будет в порядке.
@tbone, также имейте в виду, что создание образцов - это всегда хорошая идея: они покажут вам, на что способна текущая версия, и помогут вам проверить функциональность, если вам понадобится воспроизводитель для чего-то, что не удалось.
Ах, теперь я также вижу, что неправильно понял последнюю часть, где я думал, что мне нужно/можно использовать g++, чтобы снова построить минимальный образец. Но я знаю — мне не нужен минимальный пример для моих проектов. Вчера я взял вашу команду g++ и поместил ее в свой проект, и вуаля, она сработала :D Теперь я также понял важность этих примеров. Большое спасибо :)
@tbone, да, вот оно. Единственная причина, по которой я упоминаю инструкцию по сборке minimal, заключается в том, что люди путают Makwdile в каталоге примеров и каталоге сборки на nox. Но вам это не нужно, так как все работает.
какая у тебя версия wx? У вас такая же версия в винде? Вы сами собирали библиотеку или устанавливали ее из репозитория? Можете ли вы успешно собрать и запустить образец
minimal, предоставленный вам библиотекой?