2023-01-03 18:45:08 +03:00
---
title: "FLTK - упрощаем с е б е жизнь с msys2"
date: 2023-01-03T16:55:31+03:00
draft: false
categories: ["cpp"]
2023-01-03 19:19:01 +03:00
featured_image: thumb.png
2023-01-03 18:45:08 +03:00
---
2023-01-07 19:28:08 +03:00
Обновление статейки по созданию [приложений на FLTK ](/fltk-apps ), так как нынче установка
библиотек и компилятора стала проще.
2023-01-03 18:45:08 +03:00
<!-- more -->
2023-01-07 19:28:08 +03:00
Содержание:
{{< toc > }}
## Часть первая – установка msys2
2023-01-03 18:45:08 +03:00
Начнём. Скачиваем установщик msys2 с [официального сайта ](https://www.msys2.org ):
![download ](download.png )
Устанавливаем. Я оставил все параметры по-умолчанию:
![install-msys2 ](install-msys2.png )
Вводим команду для обновления всех пакетов:
```bash
pacman -Syu
```
Соглашаемся с о всем. В конце msys2 попросит перезапустить себя:
![update-phase-1 ](update-phase-1.png )
2023-01-07 19:28:08 +03:00
Снова выполняем:
2023-01-03 18:45:08 +03:00
```bash
pacman -Syu
```
и обновляем оставшуюся часть пакетов:
![update-phase-2 ](update-phase-2.png )
Готово! msys2 и е г о компоненты теперь последней версии и готовы к работе.
2023-01-07 19:28:08 +03:00
## Часть вторая – установка инструментария разработчика
2023-01-03 18:45:08 +03:00
Осталось установить компилятор, базовые инструменты для компиляции, cmake, fltk.
Мне кажется, если вы выбрали fltk, то вас интересует поддержка старых машин. Поэтому устанавливаем 32-битные версии компилятора и библиотек. Если вас интересует платформа x64, то вместо **i686** в названиях пакетов используйте **x86_64** (например, mingw-w64-**x86_64**-fltk).
2023-01-07 19:28:08 +03:00
Выполняем:
2023-01-03 18:45:08 +03:00
```bash
pacman -S base-devel mingw-w64-i686-gcc mingw-w64-i686-cmake mingw-w64-i686-fltk
```
![install-devtools ](install-devtools.png )
2023-01-07 19:28:08 +03:00
## Часть третья - пишем и собираем приложения
2023-01-03 18:45:08 +03:00
2023-01-07 19:28:08 +03:00
### Пример приложения
2023-01-03 18:45:08 +03:00
2023-01-07 19:28:08 +03:00
В этот раз будет программа, считающая нажатия на кнопку:
2023-01-03 18:45:08 +03:00
```cpp
2023-01-03 19:19:01 +03:00
#include <cstdio>
2023-01-03 18:45:08 +03:00
#include <FL/Fl.H>
#include <Fl/Fl_Window.H>
#include <Fl/Fl_Box.H>
#include <Fl/Fl_Button.H>
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<MainWindow * >(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) {
2023-01-03 19:19:01 +03:00
// Задаём тему для виджетов (none, base, plastic, gtk+, gleam)
// Fl::scheme("gleam");
2023-01-03 18:45:08 +03:00
// Создаём окно
MainWindow *window = new MainWindow(200, 300, "i++");
// Показываем окно
window->show();
2023-01-03 19:19:01 +03:00
// Запускаем event loop
2023-01-03 18:45:08 +03:00
return Fl::run();
}
```
2023-01-07 19:28:08 +03:00
### Сборка напрямую
2023-01-03 18:45:08 +03:00
Для начала пробуем всё собрать напрямую компилятором, без систем сборки. Мой проект находится в D:/code. Поэтому нужно перейти в этот каталог.
```bash
cd /d/code
```
Пробуем собрать наше приложение. Меня в первую очередь интересовала статическая сборка, когда все зависимости интегрируются в один исполняемый файл.
```bash
2023-01-07 19:36:13 +03:00
g++ main.cpp -o main.exe -O2 -DWIN32 -static -lfltk -lole32 -luuid -lcomctl32 -mwindows
2023-01-03 18:45:08 +03:00
```
**-DWIN32** – указываем FLTK, что мы под Windows.
2023-01-07 19:36:13 +03:00
**-mwindows** – убираем чёрное окно команд у приложения и подключаем некоторые системные библиотеки.
2023-01-03 18:45:08 +03:00
2023-01-07 19:36:13 +03:00
**-static** – статическая сборка.
2023-01-03 18:45:08 +03:00
**-lfltk -lole32 -luuid -lcomctl32** – подключение необходимых библиотек.
Никакого вывода команда не выдаёт.
Проверяем, что наше приложение не требует никаких дополнительных библиотек.
```bash
ldd main.exe
```
Ничего кроме системных путей тут быть не должно:
![ldd ](ldd.png )
После этого можно запускать приложение.
![app ](app.gif )
2023-01-07 19:28:08 +03:00
### Сборка через 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
2023-01-07 19:36:13 +03:00
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")
2023-01-07 19:28:08 +03:00
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.
Чтобы избавиться от необходимости е г о использования, необходимо выполнить всего лишь...
2023-01-03 18:45:08 +03:00