Skip to content

Commit

Permalink
CMake reading updated and moved to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
victor-yacovlev committed Apr 7, 2020
1 parent e288f63 commit a0e19f6
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 100 deletions.
5 changes: 2 additions & 3 deletions 2019-2020-informatics.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
### Осень 2019

1. [Введение в Linux](practice/linux_basics/intro.md)
2. [Часть 1: Инструменты разработки в UNIX](practice/linux_basics/devtools.md)
[Часть 2: CMake TODO: вынести в отдельный ридинг](practice/linux_basics/cmake.md)
2. [Инструменты разработки в UNIX](practice/linux_basics/devtools.md)
3. [Часть 1: Целочисленная арифметика](practice/integers/)
[Часть 2: Вещественная арифметика](practice/ieee754/)
4. [Часть 1: Инструменты для ARM](practice/arm/)
Expand Down Expand Up @@ -38,7 +37,7 @@
7. [Указатели на функции и динамические библиотеки](practice/function-pointers/)
8. [Сокеты UDP и AF_PACKET](practice/sockets-udp/)
9. [Berkley Packet Filter](practice/bpf/)
10. Неделя с 6 по 11 апреля: [Протокол HTTP/1.1. Сборка с помощью CMake](practice/http-cmake/)
10. Неделя с 6 по 11 апреля: [Часть 1: Протокол HTTP/1.1 и cURL](practice/http-curl/) [Часть 2: Сборка с помощью CMake](practice/linux_basics/cmake.md)
11. Неделя с 13 по 18 апреля: [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
12. Неделя с 20 по 25 апреля: Файловые системы в POSIX. Файловые системы FUSE
13. Неделя с 27 апреля по 9 мая: **новых тем не будет, только прием задач**
Expand Down
104 changes: 7 additions & 97 deletions practice/http-cmake/README.md → practice/http-curl/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Протокол HTTP, библиотека cURL и система сборки CMake
# Протокол HTTP и библиотека cURL

## Протокол HTTP

Expand Down Expand Up @@ -93,12 +93,12 @@ API состоит из двух частей: полнофункциональ
```
#include <curl/curl.h>
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
```

Expand Down Expand Up @@ -167,93 +167,3 @@ int main(int argc, char *argv[]) {
```

## Система сборки `cmake`

Использование сторонних библиотек усложняет процесс воспроизводимости сборки. В случае, когда целевая операционная система одна, это не доставляет особых проблем и достаточно простого `Makefile`, но если предполагается разработка кросс-платформенного продукта, то возникают неоднозначности:
* какой компилятор используется для сборки (gcc, clang, cl.exe);
* расположение include-файлов библиотек для компиляции;
* рссположение файлов библиотек для компоновки.

По этой причине часто практикуется не распространение `Makefile`, написанного для конкретного стека инструментов, а его генерация по декларативному описанию в процессе сборки: `./configure`, `qmake`, или `cmake`.

Наиболее гибкой системой сборки, и при этом относительно простой, является [CMake](https://cmake.org/cmake/help/v3.2/), которая реализована с поддержкой не только UNIX-подобных систем, но и Windows.

Описание проекта находится в файле `CMakeLists.txt` и имеет примерно следующий вид:

```
# признак того, что это файл для cmake
# номер версии - это минимально требуемый для сборки проекта
# не стоит злоупотребять указанием самой свежей версии
# CMake, поскольку в консервативных Linux-дистрибутивах
# может быть что-то более старое
cmake_minimum_required(VERSION 3.2)
# имя проекта - не обязательно, обычно используется IDE
project(my_great_project)
# команда `set` устанавливает значение переменной
# некоторые переменные (их имена начинаются с CMAKE_)
# имеют специальное значение
# дополнительные опции компилятора Си
set(CMAKE_C_FLAGS "-std=gnu11")
# дополнительные опции компилятора C++
set(CMAKE_CXX_FLAGS "-std=gnu14")
# в переменной SOURCES будет храниться список файлов;
# если файлов не много, то можно этого не делать,
# но некоторым IDE это требуется для навигации по проекту
set(SOURCES
file1.c
file2.cpp
file3.cpp
)
# добавление цели для сборки - бинарного файла;
# синтаксис ${...} означает использование значения
# переменной, которая в данном примере будет раскрыта
# в список файлов, из которых собирается программа
add_executable(my_cool_program ${SOURCES})
```

Для сборки CMake-проекта необходимо выполнить две стадии:
1. Сгенерировать `Makefile`из `CMakeLists.txt`
2. Собрать проект обычнычным инструментом `make`.

Обычно в процессе генерации `Makefile` и при сборке проекта создается много временных файлов. По этой причине сборку принято проводить в отдельном каталоге, - чтобы не засорять каталог с исходными текстами.

```
$ mkdir build # создаем каталог для сборки
$ cd build # переходим в него
$ cmake ../ # генерируем Makefile
# аргумент cmake - это каталог, который
# содержит файл CMakeLists.txt
$ make # запуск компиляции
```

Для многих OpenSource библиотек в стандартной поставке CMake уже готовы модули поддержки, которые выполняют поиск библиотеки. В случае c UNIX этот поиск осуществляется с помощью запуска команд конфигурации, либо проверки различных вариантов написания имен файлов в `/usr/include` и `/usr/lib`. Для Windows просматривается системный реестр.

Список поддерживаемых библиотек можно найти в поставке CMake, для Linux это может быть каталог (в разных дистрибутивах они разные) `/usr/share/cmake/Modules`. Все файлы модулей имеют название `FindИМЯБИБЛИОТЕКИ.cmake`.

Подключение библиотеки, которая поддерживается "из коробки", осуществляется с помощью команды `find_package`. В случае, если необходимые файлы присутствуют, то определяются переменные `ИМЯБИБЛИОТЕКИ_INCLUDE_DIRS` и `ИМЯБИБЛИОТЕКИ_LIBRARIES`.

Пример для curl:
```
# найти библиотеку CURL; опция REQUIRED означает,
# что библиотека является обязательной для сборки проекта,
# и если необходимые файлы не будут найдены, cmake
# завершит работу с ошибкой
find_package(CURL REQUIRED)
# добавляет в список каталогов, которые превратятся в
# опции -I компилятора все каталоги, которые перечислены
# в переменной CURL_INCLUDE_DIRECTORIES
include_directories(${CURL_INCLUDE_DIRECTORIES})
add_executable(my_cool_program ${SOURCES})
# для цели my_cool_program указываем библиотеки, с которыми
# программа будет слинкована
target_link_libraries(my_cool_program ${CURL_LIBRARIES})
```
Loading

0 comments on commit a0e19f6

Please sign in to comment.