Skip to content

Latest commit

 

History

History
204 lines (157 loc) · 13.1 KB

presentation.md

File metadata and controls

204 lines (157 loc) · 13.1 KB

Содержание

Это обзорная лекция без деталей, четыре части:

  1. Что можно сделать с помощью сторонних библиотек
  2. Кто компилирует C++, что откуда устанавливать.
  3. Как устроена компиляция и какие ошибки компиляции бывают.
  4. Конкретные примеры библиотек (Qt рулит, но есть ещё и другие).

Успеем пройтись по верхам и посмотреть на небольшие примеры.


1.1. Что могут сторонние библиотеки

Это всё проекты или домашки наших студентов


2.1. Из чего состоит C++

Стандарты: C++98/C++03, C++11 (C++0x), C++14, C++17, C++20... (это тексты)

  • Язык: что такое for и int
  • Стандартная библиотека (не только STL): #include <algorithm>

Обязательное:

  • Компилятор: gcc, Clang (LLVM), Visual C++, Apple Clang, Intel C++ Classic...
  • Стандартная библиотека: libstdc++ (GNU), libc++, Microsoft STL...
  • Динамические библиотеки: Visual C++ Redistributable
  • Редактор кода: автодополнение, подсказки, подсветка синтаксиса

Опциональное:

  • Отладчик: gdb, lldb...
  • Система сборки: Makefile, проекты Visual Studio, проекты Code::Blocks
    • CMake генерирует проекты для систем сборки (привет, CLion)
  • Нестандартные библиотеки: GUI, мультимедиа, сеть...

2.2. Как настроить окружение для C++?

Основная проблема: несовместимость ABI (Application Binary Interface).

  • Один и тот же код можно скомпилировать по-разному
  • Если библиотека и приложение используют разное ABI, они в лучшем случае не скомпилируются вместе
  • У gcc/clang может быть множество несовместимых "сборок"

Особенности Linux и macOS: просто использовать:

  • Есть "стандартный" компилятор и "стандартное" ABI: gcc в Ubuntu, Apple Clang в macOS
  • Все популярные библиотеки уже скомпилированы, можно установить через apt в Ubuntu, HomeBrew в macOS
  • Можно поставить другие компиляторы (clang в Ubuntu, gcc в macOS) через apt/HomeBrew, должно работать

Под Windows:

  • Есть много сборок gcc/clang с разным ABI, не всегда от Visual Studio
  • Нет единого пакетного менеджера

2.3. Что ставить под Windows

Вещи в себе:

  • Code::Blocks со встроенным gcc 8.1.0 из mingw-w64
  • Qt Creator со встроенным gcc 8 из mingw-w64 и Qt (супер фреймворк!)
  • CLion со встроенным gcc 9 из mingw-w64 (бесплатно для школьников и студентов)

Компиляторы с пакетными менеджерами:

  • Visual Studio 2019 Community, использовать менеджер vcpkg
  • mingw-w64, использовать менеджер pacman
  • Поставить Windows Subsystem for Linux (WSL) и Ubuntu 20.04 внутрь

Отдельно ставить среду разработки (CLion, Qt Creator, независимо от компилятора) или текстовый редактор и запускать через консоль.


2.4. Итог

  • Если не хотите использовать нестандартные библиотеки, то ставьте что угодно.
  • Если хотите Qt (рекомендую!), то Qt Creator.
  • Под Linux используйте встроенный пакетный менеджер (apt/yum/pacman/emerge)
    • Обычно библиотека Foo будет называться libFoo-dev
  • Под macOS поставьте HomeBrew и используйте библиотеки из него
  • Под Windows используйте либо Linux, либо mingw-w64 и gcc, либо Visual Studio и vcpkg

Чего не делать:

  • Сборка библиотек из исходников (build from source): долго и нудно
    • Особенно остерегайтесь ./configure && make && make install
  • Использование библиотек, которых нет в пакетных менеджерах
  • Алхимия и переименование файлов: libboost.a и boost.lib несовместимы!

3.1. Программы из нескольких файлов

Компиляция C++ сделана как в языке Си из 1970-х годов. Памяти было мало, прочитать все файлы сразу нельзя.

Два шага: компиляция и линковка (компоновка).

┌────────────────────┐  ┌─────────────────────┐
│ main.cpp           │  │ say_hello.cpp       │
│                    │  │                     │
│ Использует:        │  │ Реализовано:        │
│ * void say_hello() │  │ * void say_hello(); │
└──────────┬─────────┘  └──────────┬──────────┘
           │       компиляция      │
           ▼                       ▼            Стандартные
        main.o                 say_hello.o      библиотеки
           │                       │                │
           └──────►линковщик◄──────┘◄───────────────┘
                       │
                       ▼
                    app.exe
  • Системы сборки это от вас скрывают (и правильно!).
  • Команда g++/clang++/cl умеет и компилировать, и линковать.
  • Продемонстрировать ключ -c для g++.

3.2. Объявление и определение функций

Чтобы main.cpp мог использовать функцию say_hello(), определённую в say_hello.cpp, ему надо про неё рассказать:

void say_hello();  // Объявление функции: нет {} с определением.
int main() { say_hello(); }

Ошибки на стадии линковки (не компиляции):

  • Если забыть реализовать say_hello() или прилинковать say_hello.cpp — undefined reference
  • Если дать две реализации say_hello() — multiple definition
  • Если слинковать командой gcc вместо g++, то не будет стандартной библиотеки C++ — undefined reference

Ошибка на стадии запуска:

  • Если запустить на "чистой" машине без нужных динамических библиотек — ошибка при запуске.
    • У меня под Windows для mingw-w64 нужна libstdc++-6.dll
    • Под Linux бывает при переезде между дистрибутивами

3.3. Заголовочные файлы и #include

#include <foo> родом из 1970: просто копирует файл foo в текущее место в коде.

  • Где ищутся такие файлы — настройка компилятора, обычно есть текущая папка и стандартная библиотека.
  • В заголовочных файлах пишут объявления функций и ещё кое-что
  • Показать -E для стандартной библиотеки

Если ставите библиотеку — надо, чтобы компилятор видел её заголовочные файлы.

  • Обычно можно добавить папку (include directory) в настройках проекта, ключом -I или target_include_directories в CMake.
  • Но лучше через пакетный менеджер или find_package/add_library в CMake.

Бывают header-only библиотеки:

  • Не надо ничего добавлять на этапе линковки
  • Сильно увеличивается время компиляции, но возможны трюки

3.4. Статические библиотеки

Но заголовочных файлов недостаточно:

  • Для некоторых библиотек нужен скомпилированный код
  • Обычно кладут не .o-файлы, а архив с именем вроде libboost_filesystem-mt.a.
  • Надо рассказать про этот архив линковщику (не компилятору!): в настройках проекта, ключ -lboost_filesystem-mt для gcc/clang, target_link_libraries в CMake.
  • Где ищутся такие архивы — настройка линковщика, обычно есть стандартная библиотека
  • Надо добавить папку с этим архимов (library directory): в настройках проекта, ключом -L для gcc/clang, target_link_directories в CMake

Иногда библиотека на самом деле динамическая: подгружается при запуске программы, тогда несколько программ могут использовать одну библиотеку на диске.

Тогда надо ещё и при запуске подсказать ОС, где искать библиотеку (обычно ищется в PATH).


3.5. Грабли

При написании кода:


4.1. Header-only библиотеки

4.2. Не-header-only библиотеки

Рекомедуется ставить через пакетный менеджер

  • Boost.Asio
  • Dear ImGui (потребовался SFML)

Общее:

  • Поддержка популярных форматов, графика, звук — это обычно несколько сложных библиотек вместе или фреймворк
  • Взаимодействие с ОС — обычно только сложные библиотеки, как минимум в нижнем слое