256 lines
8.9 KiB
Markdown
256 lines
8.9 KiB
Markdown
---
|
||
title: "FLTK - упрощаем себе жизнь с msys2"
|
||
date: 2023-01-03T16:55:31+03:00
|
||
draft: false
|
||
categories: ["cpp"]
|
||
featured_image: thumb.png
|
||
---
|
||
|
||
Обновление статейки по созданию [приложений на FLTK](/fltk-apps), так как нынче установка
|
||
библиотек и компилятора стала проще.
|
||
|
||
<!--more-->
|
||
|
||
Содержание:
|
||
|
||
{{< 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 <cstdio>
|
||
#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) {
|
||
// Задаём тему для виджетов (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 -static-libgcc -static-libstdc++ -lfltk -lole32 -luuid -lcomctl32 -mwindows
|
||
```
|
||
|
||
**-DWIN32** – указываем FLTK, что мы под Windows.
|
||
|
||
**-mwindows** – убираем чёрное окошко у приложения и подключаем некоторые системные библиотеки.
|
||
|
||
**-static -static-libgcc -static-libstdc++** – статическая сборка, включить системные библиотеки в статическую сборку.
|
||
|
||
**-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(STATIC_BUILD AND MINGW)
|
||
set(BUILD_SHARED_LIBS OFF)
|
||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||
set(CMAKE_EXE_LINKER_FLAGS "-static -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.
|
||
Чтобы избавиться от необходимости его использования, необходимо выполнить всего лишь...
|
||
|