Commit c5d442f3 authored by Igor Zhirkov's avatar Igor Zhirkov
Browse files

Merge remote-tracking branch 'upstream/master' into feature/build-system

parents 22887da0 eaa3c9be
*.o
build
obj
/build
/out
*.html
......@@ -13,5 +13,8 @@ linter:
test:
stage: test
script:
- make -sj SANITIZER=all
- make -sk test SANITIZER=all
- cmake -B ./build/ -G "Ninja Multi-Config" -DCMAKE_C_COMPILER=clang
- cmake --build ./build/ --config ASan --target check
- cmake --build ./build/ --config LSan --target check
- cmake --build ./build/ --config MSan --target check
- cmake --build ./build/ --config UBSan --target check
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" GENERATION_DIR="out/build/debug" CONFIG_NAME="Debug" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=Debug" />
<configuration PROFILE_NAME="Release" ENABLED="true" GENERATION_DIR="out/build/release" CONFIG_NAME="Release" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=Release" />
<configuration PROFILE_NAME="ASan" ENABLED="true" GENERATION_DIR="out/build/asan" CONFIG_NAME="ASan" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=ASan" />
<configuration PROFILE_NAME="LSan" ENABLED="true" GENERATION_DIR="out/build/lsan" CONFIG_NAME="LSan" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=LSan" />
<configuration PROFILE_NAME="MSan" ENABLED="true" GENERATION_DIR="out/build/msan" CONFIG_NAME="MSan" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=MSan" />
<configuration PROFILE_NAME="UBSan" ENABLED="true" GENERATION_DIR="out/build/ubsan" CONFIG_NAME="UBSan" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=UBSan" />
</configurations>
</component>
</project>
\ No newline at end of file
cmake_minimum_required(VERSION 3.12)
project(image-transformer LANGUAGES C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_C_COMPILER_ID STREQUAL GNU)
set(CMAKE_CONFIGURATION_TYPES Debug Release ASan LSan UBSan)
elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
set(CMAKE_CONFIGURATION_TYPES Debug Release ASan LSan MSan UBSan)
elseif(MSVC)
set(CMAKE_CONFIGURATION_TYPES Debug Release ASan)
endif()
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE IN_LIST CMAKE_CONFIGURATION_TYPES)
message(FATAL_ERROR "Unexpected build type ${CMAKE_BUILD_TYPE}, possible values: ${CMAKE_CONFIGURATION_TYPES}")
endif()
if(CMAKE_C_COMPILER_ID STREQUAL GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "-std=c17 -pedantic -Wall -Werror -ggdb")
set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-optimize-sibling-calls -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS_LSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=leak")
set(CMAKE_C_FLAGS_MSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=memory -fno-optimize-sibling-calls -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS_UBSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined")
elseif(MSVC)
set(CMAKE_C_FLAGS "/std:c17 /W4 /WX")
set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_DEBUG} /fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS_ASAN "/debug /INCREMENTAL:NO")
endif()
if(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
find_program(CLANG_TIDY clang-tidy)
message(STATUS "Clang-tidy: ${CLANG_TIDY}")
if(CLANG_TIDY)
file(STRINGS clang-tidy-checks.txt clang_tidy_checks)
list(JOIN clang_tidy_checks "," clang_tidy_checks_str)
set(CMAKE_C_CLANG_TIDY
${CLANG_TIDY}
-header-filter=${CMAKE_SOURCE_DIR}
-checks=${clang_tidy_checks_str}
-warnings-as-errors=*
)
endif()
add_subdirectory(solution)
option(BUILD_TESTING "Enable tests" ON)
if(BUILD_TESTING)
enable_testing()
add_subdirectory(tester)
endif()
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "Release",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
},
{
"name": "x64-Asan",
"generator": "Ninja",
"configurationType": "ASan",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
}
]
}
\ No newline at end of file
......@@ -229,46 +229,55 @@ bmp-заголовка.
## Система сборки и тестирования
- Используйте команду `make` для того, чтобы собрать ваш код в исполняемый файл
`build/image-transformer`. Проверьте, что в вашей системе установлены программа
`make` версии как минимум 4.0 и компилятор `clang`. Флаги для компиляции берутся
из `compile_flags.txt` &mdash; вы можете добавить свои флаги в конец
этого файла или в саму команду `make`. Например, чтобы собрать код с оптимизациями
и протестировать скорость выполнения, вы можете использовать `make CFLAGS=-O3`.
С помощью `LDFLAGS` можно передать дополнительные параметры линковщику.
- Используйте `make check`, чтобы проверить вашу программу через статический анализатор
`clang-tidy`. Список проверок описан в файле `clang-tidy-checks.txt`. Вы можете добавить
свои проверки в конец этого файла или в параметр `CLANG_TIDY_CHECKS` для `make`.
- Вы можете собрать код с поддержкой определенных динамических анализаторов (санитайзеров).
Санитайзеры могут дать подробную информацию о возможных и реальных ошибках в программе вместо
классического сообщения о segmentation fault. Исполняемые файлы будут также размещены в директории `build`, но для санитайзеров выделены отдельные
поддиректории с их названием.
Поддерживаются следующие санитайзеры:
- `make SANITIZER=asan` &mdash; [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
Для сборки кода вам предоставлена система сборки на языке CMake, самим писать систему сборки не требуется.
- В зависимости от платформы и компилятора, система сборки поддерживает несколько конфигураций с динамическими
анализаторами (санитайзерами). Санитайзеры могут дать подробную информацию о возможных и реальных ошибках в
программе вместо классического сообщения о segmentation fault. Выбрать подходящую конфигурацию вы можете с
помощью переменной `CMAKE_BUILD_TYPE`:
- `ASan` &mdash; [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
набор проверок на некорректное использование адресов памяти. Примеры:
use-after-free, double-free, выход за пределы стека, кучи или статического блока.
- `make SANITIZER=lsan` &mdash; [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html),
- `LSan` &mdash; [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html),
проверки на утечки памяти.
- `make SANITIZER=msan` &mdash; [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
- `MSan` &mdash; [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
проверяет, что любая используемая ячейка памяти проинициализирована на момент чтения из нее.
- `make SANITIZER=usan` &mdash; [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
- `UBSan` &mdash; [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
набор базовых проверок на неопределенное поведение. Примеры: переполнение численного типа,
null-pointer dereference.
- `make SANITIZER=none` &mdash; собрать код без санитайзеров (по умолчанию).
- `make SANITIZER=all` &mdash; собрать 5 версий кода, каждая с одной из предыдущих опций.
- Используйте `make clean` для очистки временных файлов и директории `build`.
- Директория `tester` содержит код и изображения для тестирования вашей программы. Используйте
`make -k test`, чтобы запустить тесты и вывести отчет по их выполнению. Параметры `CFLAGS`,
`LDFLAGS` и `SANITIZER` также могут быть переданы программам, используемым в тестах.
- Чтобы запустить конкретный тест, посмотрите его название в отчете всех тестов (оно же название
директории с изображениями в `testers/tests`) и запустите `make -k test-<name>`. Например,
чтобы запустить тест №1 ([изначальная картинка](testers/tests/1/input.bmp) ->
[ожидаемый результат](testers/tests/1/output_expected.bmp)), используйте `make -k test-1`.
- Ваша программа будет тестироваться в
[Docker-контейнере](https://gitlab.se.ifmo.ru/low-level-programming/docker-c-test-machine/),
вы можете использовать его для тестирования вашего кода локально. В контейнере будут запущены:
- Статический анализатор - аналогичен команде `make check`
- Тесты с санитайзерами - аналогичен команде `make -k test SANITIZER=all`
- Если в вашей системе имеется статический анализатор `clang-tidy`, он будет запущен во время компиляции программы.
Список проверок описан в файле `clang-tidy-checks.txt`. Вы можете добавить свои проверки в конец этого файла.
- Директория `tester` содержит код и изображения для тестирования вашей программы. Для запуска тестов используется CTest.
- Поддержана интеграция системы сборки со средами разработки CLion, Visual Studio и Visual Studio Code.
Чтобы система сборки работала на вашей системе, вам необходимо:
### Linux и MacOS
- Компилятор (`gcc`/`clang`) и `cmake` (проверьте, что `cmake` версии 3.12 или выше)
- Если вы хотите использовать санитайзеры с GCC, установите `libasan`, `liblsan` и `libubsan` с помощью пакетного менеджера (названия могут отличаться).
- Если вы хотите использовать санитайзеры с Clang, на некоторых системах вам может понадобиться пакет `compiler-rt`.
- Если вы хотите пользоваться `clang-tidy`, установите `clang-tools-extra`.
### Windows
- Какая-либо среда разработки (CLion, Visual Studio, Visual Studio Code)
- Если вы хотите пользоваться `clang-tidy`, скачайте LLVM: https://github.com/llvm/llvm-project/releases (найдите установщик win64 под одной из версий)
- Для VS Code требуется отдельно поставить Visual Studio (с сайта Microsoft) и CMake: https://cmake.org/download/
### Инструкции по сборке и тестированию
- [Работа с терминалом](docs/Terminal.md)
- [CLion](docs/CLion.md)
- [Visual Studio](docs/Visual%20Studio.md)
- [Visual Studio Code](docs/VSCode.md)
# Для самопроверки
......
buildType:
default: debug
description: Build Type
choices:
debug:
short: Debug
long: Build with debugging information
buildType: Debug
release:
short: Release
long: Optimize the resulting binaries
buildType: Release
asan:
short: ASan
long: Instrument with AddressSanitizer
buildType: ASan
lsan:
short: LSan
long: Instrument with LeakSanitizer
buildType: LSan
msan:
short: MSan
long: Instrument with MemorySanitizer
buildType: MSan
ubsan:
short: UBSan
long: Instrument with UndefinedBehaviourSanitizer
buildType: UBSan
# Разработка с CLion
## 1. Выберите и склонируйте ваш форк с GitLab
![Select project from VCS](CLion/01-get-from-vcs.png)
## 2. В окне проекта, выберите `CMakeLists.txt` на панели слева
![Load CMake project](CLion/02-load-cmake-project.png)
Сверху окна с редактором появится подсказка, предлагающая загрузить CMake в проект. Нажмите **`Load CMake project`**.
В окне сборки может появиться ошибка, например: `Unexpected build type MSan, possible values: Debug;Release;ASan;LSan;UBSan`.
Она означает, что данной конфигурации на вашей ОС или с вашим компилятором не предусмотрено,
но разработке с другими конфигурациями она не помешает.
## 3. Выберите необходимую конфигурацию в раскрывающемся списке
![Choose Config](CLion/03-choose-configuration.png)
- **`Debug`** быстро компилируется и подходит для разработки.
- **`ASan, LSan, MSan, UBSan`** подходят для отладки ошибок сегментации и других проблем с памятью. Рекомендуется
запустить ваш код с санитайзерами перед отправкой на проверку!
- **`Release`** нужен для сборки кода с оптимизациями и проверки скорости выполнения.
В качестве цели для сборки выберите **`All CTest`**. Теперь вы можете собирать проект и
запускать его через кнопки сверху справа как обычно.
Если при сборке вы получили ошибку вроде `C:\CLion 2022.2.4\bin\mingw\bin/ld.exe: cannot find -lasan`, значит, у вас
нет нужной библиотеки для запуска данного профиля. Можете просто выбрать другую конфигурацию.
docs/CLion/01-get-from-vcs.png

23.6 KB

docs/CLion/02-load-cmake-project.png

152 KB

docs/CLion/03-choose-configuration.png

161 KB

# Работа с терминалом
## 1. Конфигурация
```bash
$ mkdir ./build/
$ cd ./build/
$ cmake .. -DCMAKE_BUILD_TYPE=<config>
```
Вместо `<config>` можно использовать одну из существующих конфигураций:
- **`Debug`** быстро компилируется и подходит для разработки.
- **`ASan, LSan, MSan, UBSan`** подходят для отладки ошибок сегментации и других проблем с памятью. Рекомендуется
запустить ваш код с санитайзерами перед отправкой на проверку!
- **`Release`** нужен для сборки кода с оптимизациями и проверки скорости выполнения.
## 2. Сборка
```bash
$ cmake --build ./build/
```
Исполняемые файлы `./build/solution/image-transformer` и `./build/tester/image-matcher`
будут собраны, их можно использовать для ручного тестирования.
## 3. Тестирование
```bash
$ cmake --build ./build/ --target check
# ИЛИ
$ cd ./build/
$ ctest --output-on-failure
```
## Бонус: `ssh` + `git`
### Как настроить SSH ключи
```bash
$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub
```
В настройках профиля GitLab нужно открыть категорию `SSH Keys`, добавить новый
ключ и скопировать содержимое `id_rsa.pub` туда.
### Как склонировать форк
```bash
$ git clone ssh://git@gitlab.se.ifmo.ru:4815/<my username>/assignment-image-rotation.git
$ cd ./assignment-image-rotation/
```
### Как отправить свои изменения обратно в форк
```bash
$ git add ./solution/
$ git status
$ git commit -m "Lab complete"
$ git push origin master
```
После того, как вы откроете merge request, каждое новое изменение, добавленное таким образом,
будет появляться там автомагически.
### Как обновить свою лабораторную, если преподаватель попросил "подтянуть к себе свежие изменения" из основного репозитория
```bash
$ git remote add upstream ssh://git@gitlab.se.ifmo.ru:4815/programming-languages/assignment-image-rotation.git
$ git fetch upstream
$ git checkout master
$ git merge upstream/master
$ git remote remove upstream
```
docs/VS/01-vcs.png

20.7 KB

docs/VS/02-folder-view.png

40.5 KB

docs/VS/03-choose-config.png

55.4 KB

docs/VS/04-tests.png

63.7 KB

# Разработка с Visual Studio Code
Для разработки требуются расширения:
- **`CMake`** от `twxs`
- **`CMakeTools`** от `Microsoft`
- **`C/C++`** от `Microsoft`
Перезагрузите VSCode после установки расширений.
## 1. Выберите и склонируйте ваш форк с GitLab
![Clone repository](VSCode/01-clone.png)
## 2. В окне проекта, выберите компилятор
![Choose Kit](VSCode/02-choose-kit.png)
VSCode предложит выбрать компилятор при открытии проекта. Если он этого не сделал,
кликните по кнопке с гаечным ключом на нижней панели.
На Windows, вероятнее всего, вам нужен компилятор `Visual Studio` с версией `amd64`.
## 3. Выберите конфигурацию на нижней панели
![Choose Config](VSCode/03-choose-config.png)
- **`Debug`** быстро компилируется и подходит для разработки.
- **`ASan, LSan, MSan, UBSan`** подходят для отладки ошибок сегментации и других проблем с памятью. Рекомендуется
запустить ваш код с санитайзерами перед отправкой на проверку!
- **`Release`** нужен для сборки кода с оптимизациями и проверки скорости выполнения.
На той же нижней панели, используйте кнопку **`Build`** для сборки кода и **`Run CTests tests`** для запуска тестов.
Если во время сборки вы видите ошибку вроде `...\Microsoft.CppBuild.targets(457,5): error MSB8013: This project doesn't contain the Configuration and Platform combination of MSan|x64`, это означает что выбранная конфигурация на вашей системе не поддержана - выберите другую.
docs/VSCode/01-clone.png

66.6 KB

docs/VSCode/02-choose-kit.png

114 KB

docs/VSCode/03-choose-config.png

85.9 KB

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment