--- title: "FLTK - упрощаем себе жизнь с msys2" date: 2023-01-03T16:55:31+03:00 draft: false categories: ["cpp"] featured_image: thumb.png --- Обновление статейки по созданию [приложений на FLTK](/fltk-apps), так как нынче установка библиотек и компилятора стала проще. Содержание: {{< toc >}} ## Часть первая – установка msys2 Начнём. Скачиваем установщик msys2 с [официального сайта](https://www.msys2.org): ![download](download.png) Устанавливаем. Я оставил все параметры по-умолчанию: ![install-msys2](install-msys2.png) Вводим команду для обновления всех пакетов: ```bash pacman -Syu ``` Соглашаемся со всем. В конце msys2 попросит перезапустить себя: ![update-phase-1](update-phase-1.png) Снова выполняем: ```bash pacman -Syu ``` и обновляем оставшуюся часть пакетов: ![update-phase-2](update-phase-2.png) Готово! msys2 и его компоненты теперь последней версии и готовы к работе. ## Часть вторая – установка инструментария разработчика Осталось установить компилятор, базовые инструменты для компиляции, cmake, fltk. Мне кажется, если вы выбрали fltk, то вас интересует поддержка старых машин. Поэтому устанавливаем 32-битные версии компилятора и библиотек. Если вас интересует платформа x64, то вместо **i686** в названиях пакетов используйте **x86_64** (например, mingw-w64-**x86_64**-fltk). Выполняем: ```bash pacman -S base-devel mingw-w64-i686-gcc mingw-w64-i686-cmake mingw-w64-i686-fltk ``` ![install-devtools](install-devtools.png) ## Часть третья - пишем и собираем приложения ### Пример приложения В этот раз будет программа, считающая нажатия на кнопку: ```cpp #include #include #include #include #include class MainWindow : public Fl_Window { public: MainWindow(int w, int h, char const *title) : Fl_Window(w, h, title), m_counter(0) { // Создаём кнопку m_button = new Fl_Button(34, 34, 133, 56, "i++"); // Присваиваем обработчик кнопки, при этом пробрасываем текущее окно m_button->callback(button_click, this); // Создаём надпись-счётчик m_label = new Fl_Box(34, 177, 133, 56); // Выставляем размер шрифта m_label->labelsize(50); // Сразу обновляем текст счётчика update_label(); // Заканчиваем добавлять виджеты end(); } protected: void update_label() { // Преобразуем число в строку std::snprintf(m_label_text, sizeof(m_label_text), "%d", m_counter); m_label->label(m_label_text); } static void button_click(Fl_Widget *w, void *data) { // Получаем окно, которое передали обработчику MainWindow *mw = static_cast(data); // Увеличиваем счётчик mw->m_counter++; // Обновляем надпись mw->update_label(); } private: Fl_Box *m_label; Fl_Button *m_button; char m_label_text[16]; int m_counter; }; int main(void) { // Задаём тему для виджетов (none, base, plastic, gtk+, gleam) // Fl::scheme("gleam"); // Создаём окно MainWindow *window = new MainWindow(200, 300, "i++"); // Показываем окно window->show(); // Запускаем event loop return Fl::run(); } ``` ### Сборка напрямую Для начала пробуем всё собрать напрямую компилятором, без систем сборки. Мой проект находится в D:/code. Поэтому нужно перейти в этот каталог. ```bash cd /d/code ``` Пробуем собрать наше приложение. Меня в первую очередь интересовала статическая сборка, когда все зависимости интегрируются в один исполняемый файл. ```bash g++ main.cpp -o main.exe -O2 -DWIN32 -static -lfltk -lole32 -luuid -lcomctl32 -mwindows ``` **-DWIN32** – указываем FLTK, что мы под Windows. **-mwindows** – убираем чёрное окно команд у приложения и подключаем некоторые системные библиотеки. **-static** – статическая сборка. **-lfltk -lole32 -luuid -lcomctl32** – подключение необходимых библиотек. Никакого вывода команда не выдаёт. Проверяем, что наше приложение не требует никаких дополнительных библиотек. ```bash ldd main.exe ``` Ничего кроме системных путей тут быть не должно: ![ldd](ldd.png) После этого можно запускать приложение. ![app](app.gif) ### Сборка через CMake #### Вариант 1 - внутри msys2 Для cmake хорошим тоном является создавать директорию сборки вне директории проекта. Поэтому немного изменим структуру нашего проекта: ``` D:\code ├───build └───fltk-app ├───CmakeLists.txt └───main.cpp ``` Создаём CmakeLists.txt, который также будет поддерживать статическую сборку: ```cmake cmake_minimum_required(VERSION 3.2) project(fltk-app) option(STATIC_BUILD "Enable static build" ON) # Конфигурируем статическую сборку для mingw if(MINGW) if(STATIC_BUILD) set(BUILD_SHARED_LIBS OFF) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() # Отключаем окно команд set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mwindows") endif() # Ищем библиотеку fltk в системе # При успешном поиске станут доступны переменные, описанные здесь: # https://cmake.org/cmake/help/latest/module/FindFLTK.html find_package(FLTK REQUIRED) # Указываем исходные файлы проекта add_executable(fltk-app main.cpp) # Добавляем путь к заготовкам fltk для компиляции (в случаях, когда они находятся в произвольном месте) target_include_directories(fltk-app PUBLIC ${FLTK_INCLUDE_DIRS}) # Подключаем библиотеки target_link_libraries(fltk-app ${FLTK_BASE_LIBRARY}) # Также добавляем необходимые библиотеки при сборке на windows if(WIN32) target_link_libraries(fltk-app comctl32) endif() ``` > Файл проекта пока что адаптирован только для windows. Переходим в каталог сборки: ```bash cd /d/code/build ``` Далее необходимо создать файлы для конкретной системы сборки. У нас это **MSYS Makefiles**: ```bash cmake -G "MSYS Makefiles" /d/code/fltk-app ``` ![cmake-msys-gen](cmake-msys-gen.png) Затем собираем проект: ```bash cmake --build . ``` ![cmake-msys-build](cmake-msys-build.png) Проверяем, не появилось ли зависимостей: ```bash ldd /d/code/build/fltk-app.exe ``` ![cmake-msys-ldd](cmake-msys-ldd.png) #### Вариант 2 - вне msys2 Сборка через msys2 удобна тогда, когда у нас уже есть готовый проект. Однако когда речь идёт о разработке, то мало какая IDE позволит себе роскошь запускать сборку в окружении msys2. Чтобы избавиться от необходимости его использования, необходимо выполнить всего лишь...