diff --git a/.gitignore b/.gitignore index 87e93c3aa6db1c5ccac4ce33203d05067441716e..1a7d54eac0d19c1b43d57bb7296c95b1e8aefadb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -*.o -build -obj +/build +/out *.html diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08a8c0e2903f8a12be4714a1732a588cb0f3f376..01520f4d071a2217871ad199fe411247f42e699c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/.idea/cmake.xml b/.idea/cmake.xml new file mode 100644 index 0000000000000000000000000000000000000000..2330220dc7bc2351338c8296709f3853f61fdb37 --- /dev/null +++ b/.idea/cmake.xml @@ -0,0 +1,13 @@ +<?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 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e5c26d2f0239822ba05884f4ba45d4fa19752549 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,54 @@ +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() diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000000000000000000000000000000000000..f7aa3175439b9950fc37fb9dc8f79847249ed23a --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,37 @@ +п»ї{ + "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 diff --git a/README.md b/README.md index d3b00991a09b744ce075398e4b46c37cee21a0bf..c5b3000febf8cfd8cb2bf213e19828ad9b3f2c2b 100644 --- a/README.md +++ b/README.md @@ -229,46 +229,55 @@ bmp-заголовка. ## Система СЃР±РѕСЂРєРё Рё тестирования -- Рспользуйте команду `make` для того, чтобы собрать ваш РєРѕРґ РІ исполняемый файл - `build/image-transformer`. Проверьте, что РІ вашей системе установлены программа - `make` версии как РјРёРЅРёРјСѓРј 4.0 Рё компилятор `clang`. Флаги для компиляции берутся - РёР· `compile_flags.txt` — РІС‹ можете добавить СЃРІРѕРё флаги РІ конец - этого файла или РІ саму команду `make`. Например, чтобы собрать РєРѕРґ СЃ оптимизациями - Рё протестировать скорость выполнения, РІС‹ можете использовать `make CFLAGS=-O3`. - РЎ помощью `LDFLAGS` можно передать дополнительные параметры линковщику. -- Рспользуйте `make check`, чтобы проверить вашу программу через статический анализатор - `clang-tidy`. РЎРїРёСЃРѕРє проверок описан РІ файле `clang-tidy-checks.txt`. Р’С‹ можете добавить - СЃРІРѕРё проверки РІ конец этого файла или РІ параметр `CLANG_TIDY_CHECKS` для `make`. -- Р’С‹ можете собрать РєРѕРґ СЃ поддержкой определенных динамических анализаторов (санитайзеров). - Санитайзеры РјРѕРіСѓС‚ дать РїРѕРґСЂРѕР±РЅСѓСЋ информацию Рѕ возможных Рё реальных ошибках РІ программе вместо - классического сообщения Рѕ segmentation fault. Рсполняемые файлы Р±СѓРґСѓС‚ также размещены РІ директории `build`, РЅРѕ для санитайзеров выделены отдельные - поддиректории СЃ РёС… названием. - Поддерживаются следующие санитайзеры: - - `make SANITIZER=asan` — [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html), +Для СЃР±РѕСЂРєРё РєРѕРґР° вам предоставлена система СЃР±РѕСЂРєРё РЅР° языке CMake, самим писать систему СЃР±РѕСЂРєРё РЅРµ требуется. + +- Р’ зависимости РѕС‚ платформы Рё компилятора, система СЃР±РѕСЂРєРё поддерживает несколько конфигураций СЃ динамическими + анализаторами (санитайзерами). Санитайзеры РјРѕРіСѓС‚ дать РїРѕРґСЂРѕР±РЅСѓСЋ информацию Рѕ возможных Рё реальных ошибках РІ + программе вместо классического сообщения Рѕ segmentation fault. Выбрать подходящую конфигурацию РІС‹ можете СЃ + помощью переменной `CMAKE_BUILD_TYPE`: + + - `ASan` — [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html), набор проверок РЅР° некорректное использование адресов памяти. Примеры: use-after-free, double-free, выход Р·Р° пределы стека, кучи или статического блока. - - `make SANITIZER=lsan` — [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html), + + - `LSan` — [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html), проверки РЅР° утечки памяти. - - `make SANITIZER=msan` — [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), + + - `MSan` — [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), проверяет, что любая используемая ячейка памяти проинициализирована РЅР° момент чтения РёР· нее. - - `make SANITIZER=usan` — [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), + + - `UBSan` — [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), набор базовых проверок РЅР° неопределенное поведение. Примеры: переполнение численного типа, null-pointer dereference. - - `make SANITIZER=none` — собрать РєРѕРґ без санитайзеров (РїРѕ умолчанию). - - `make SANITIZER=all` — собрать 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) # Для самопроверки diff --git a/cmake-variants.yaml b/cmake-variants.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1986067bea31b509649a1821f36890674328b53b --- /dev/null +++ b/cmake-variants.yaml @@ -0,0 +1,28 @@ +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 diff --git a/docs/CLion.md b/docs/CLion.md new file mode 100644 index 0000000000000000000000000000000000000000..c7be3f0d0edd0087559ed7ffab779c9611fea25c --- /dev/null +++ b/docs/CLion.md @@ -0,0 +1,30 @@ +# Разработка СЃ CLion + +## 1. Выберите Рё склонируйте ваш форк СЃ GitLab + + + +## 2. Р’ РѕРєРЅРµ проекта, выберите `CMakeLists.txt` РЅР° панели слева + + + +Сверху РѕРєРЅР° СЃ редактором появится подсказка, предлагающая загрузить CMake РІ проект. Нажмите **`Load CMake project`**. + +Р’ РѕРєРЅРµ СЃР±РѕСЂРєРё может появиться ошибка, например: `Unexpected build type MSan, possible values: Debug;Release;ASan;LSan;UBSan`. +РћРЅР° означает, что данной конфигурации РЅР° вашей РћРЎ или СЃ вашим компилятором РЅРµ предусмотрено, +РЅРѕ разработке СЃ РґСЂСѓРіРёРјРё конфигурациями РѕРЅР° РЅРµ помешает. + +## 3. Выберите необходимую конфигурацию РІ раскрывающемся СЃРїРёСЃРєРµ + + + +- **`Debug`** быстро компилируется Рё РїРѕРґС…РѕРґРёС‚ для разработки. +- **`ASan, LSan, MSan, UBSan`** РїРѕРґС…РѕРґСЏС‚ для отладки ошибок сегментации Рё РґСЂСѓРіРёС… проблем СЃ памятью. Рекомендуется + запустить ваш РєРѕРґ СЃ санитайзерами перед отправкой РЅР° проверку! +- **`Release`** нужен для СЃР±РѕСЂРєРё РєРѕРґР° СЃ оптимизациями Рё проверки скорости выполнения. + +Р’ качестве цели для СЃР±РѕСЂРєРё выберите **`All CTest`**. Теперь РІС‹ можете собирать проект Рё +запускать его через РєРЅРѕРїРєРё сверху справа как обычно. + +Если РїСЂРё СЃР±РѕСЂРєРµ РІС‹ получили ошибку РІСЂРѕРґРµ `C:\CLion 2022.2.4\bin\mingw\bin/ld.exe: cannot find -lasan`, значит, Сѓ вас +нет нужной библиотеки для запуска данного профиля. Можете просто выбрать РґСЂСѓРіСѓСЋ конфигурацию. diff --git a/docs/CLion/01-get-from-vcs.png b/docs/CLion/01-get-from-vcs.png new file mode 100644 index 0000000000000000000000000000000000000000..1cc5866b4c60fbcc13f1d10f26fb054312231898 Binary files /dev/null and b/docs/CLion/01-get-from-vcs.png differ diff --git a/docs/CLion/02-load-cmake-project.png b/docs/CLion/02-load-cmake-project.png new file mode 100644 index 0000000000000000000000000000000000000000..e548687bdf02b1873d0deeb1bc524fa3d3632035 Binary files /dev/null and b/docs/CLion/02-load-cmake-project.png differ diff --git a/docs/CLion/03-choose-configuration.png b/docs/CLion/03-choose-configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..3dc34a7cb8aa1c1dabc8f8f01ae3c4fe22c2e8d6 Binary files /dev/null and b/docs/CLion/03-choose-configuration.png differ diff --git a/docs/Terminal.md b/docs/Terminal.md new file mode 100644 index 0000000000000000000000000000000000000000..8992affd8dc2c98f3c010c550e33c2d2ef2e2879 --- /dev/null +++ b/docs/Terminal.md @@ -0,0 +1,75 @@ +# Работа СЃ терминалом + +## 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 +``` diff --git a/docs/VS/01-vcs.png b/docs/VS/01-vcs.png new file mode 100644 index 0000000000000000000000000000000000000000..19344a17ee044ba33000f900201f023dd1e47b87 Binary files /dev/null and b/docs/VS/01-vcs.png differ diff --git a/docs/VS/02-folder-view.png b/docs/VS/02-folder-view.png new file mode 100644 index 0000000000000000000000000000000000000000..4c57e63995ac6e1570eb4c49222a6c9e43c4d435 Binary files /dev/null and b/docs/VS/02-folder-view.png differ diff --git a/docs/VS/03-choose-config.png b/docs/VS/03-choose-config.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3f0a76aedfb7eb1e5444324234ff5cce7f8477 Binary files /dev/null and b/docs/VS/03-choose-config.png differ diff --git a/docs/VS/04-tests.png b/docs/VS/04-tests.png new file mode 100644 index 0000000000000000000000000000000000000000..5d43ef3e1bf9652e79c47d4289ddb74d6b83c40b Binary files /dev/null and b/docs/VS/04-tests.png differ diff --git a/docs/VSCode.md b/docs/VSCode.md new file mode 100644 index 0000000000000000000000000000000000000000..d2f67a318dbd716457a5774f8ab03b7b0d16610a --- /dev/null +++ b/docs/VSCode.md @@ -0,0 +1,35 @@ +# Разработка СЃ Visual Studio Code + +Для разработки требуются расширения: + +- **`CMake`** РѕС‚ `twxs` +- **`CMakeTools`** РѕС‚ `Microsoft` +- **`C/C++`** РѕС‚ `Microsoft` + +Перезагрузите VSCode после установки расширений. + +## 1. Выберите Рё склонируйте ваш форк СЃ GitLab + + + +## 2. Р’ РѕРєРЅРµ проекта, выберите компилятор + + + +VSCode предложит выбрать компилятор РїСЂРё открытии проекта. Если РѕРЅ этого РЅРµ сделал, +кликните РїРѕ РєРЅРѕРїРєРµ СЃ гаечным ключом РЅР° нижней панели. + +РќР° Windows, вероятнее всего, вам нужен компилятор `Visual Studio` СЃ версией `amd64`. + +## 3. Выберите конфигурацию РЅР° нижней панели + + + +- **`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`, это означает что выбранная конфигурация РЅР° вашей системе РЅРµ поддержана - выберите РґСЂСѓРіСѓСЋ. diff --git a/docs/VSCode/01-clone.png b/docs/VSCode/01-clone.png new file mode 100644 index 0000000000000000000000000000000000000000..b14f8a2e016f28abc07beb4ce4eb34eca2850383 Binary files /dev/null and b/docs/VSCode/01-clone.png differ diff --git a/docs/VSCode/02-choose-kit.png b/docs/VSCode/02-choose-kit.png new file mode 100644 index 0000000000000000000000000000000000000000..cdc325ba3a7c1e108b3f5d7011cc7f2a5498312a Binary files /dev/null and b/docs/VSCode/02-choose-kit.png differ diff --git a/docs/VSCode/03-choose-config.png b/docs/VSCode/03-choose-config.png new file mode 100644 index 0000000000000000000000000000000000000000..d5a15983515a46da9813c70da7a210be06d73a85 Binary files /dev/null and b/docs/VSCode/03-choose-config.png differ diff --git a/docs/Visual Studio.md b/docs/Visual Studio.md new file mode 100644 index 0000000000000000000000000000000000000000..59c0e152abafd5b3245ee1d93d74838b2b75763d --- /dev/null +++ b/docs/Visual Studio.md @@ -0,0 +1,27 @@ +# Разработка СЃ Visual Studio + +## 1. Выберите Рё склонируйте ваш форк СЃ GitLab + + + +## 2. Р’ РѕРєРЅРµ решения, выберите `Folder View` РЅР° панели слева + + + +Visual Studio запустит конфигурацию проекта СЃ помощью CMake РІ профиле РїРѕ умолчанию (**`x64-Debug`**). + +## 3. Выберите необходимую конфигурацию РІ раскрывающемся СЃРїРёСЃРєРµ + + + +- **`x64-Debug`** быстро компилируется Рё РїРѕРґС…РѕРґРёС‚ для разработки. +- **`x64-Asan`** РїРѕРґС…РѕРґРёС‚ для отладки ошибок сегментации Рё РґСЂСѓРіРёС… проблем СЃ памятью. Рекомендуется + запустить ваш РєРѕРґ РІ Asan перед отправкой РЅР° проверку! +- **`x64-Release`** нужен для СЃР±РѕСЂРєРё РєРѕРґР° СЃ оптимизациями Рё проверки скорости выполнения. + +## 4. Рспользуйте панели сверху для запуска СЃР±РѕСЂРєРё Рё тестирования + + + +- Варианты для СЃР±РѕСЂРєРё находятся РІ меню **`Build`**. Для СЃР±РѕСЂРєРё всего решения нажмите **`F7`**. +- Для запуска тестов выберите **`Run CTests for ...`** РІ меню **`Test`**. diff --git a/solution/CMakeLists.txt b/solution/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b8ff60995419877a10093ed0377e4951e1fa0981 --- /dev/null +++ b/solution/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB_RECURSE sources CONFIGURE_DEPENDS + src/*.c + src/*.h + include/*.h +) + +add_executable(image-transformer ${sources}) +target_include_directories(image-transformer PRIVATE src include) diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b702752aca2a943078cf41efe08c297a33543bf2 --- /dev/null +++ b/tester/CMakeLists.txt @@ -0,0 +1,28 @@ +file(GLOB_RECURSE sources CONFIGURE_DEPENDS + src/*.c + src/*.h + include/*.h +) + +add_executable(image-matcher ${sources}) +target_include_directories(image-matcher PRIVATE src include) + +file(GLOB test_directories CONFIGURE_DEPENDS tests/*) +list(FILTER test_directories EXCLUDE REGEX ".*/\.gitignore") + +foreach(test_dir IN LISTS test_directories) + string(REPLACE "/" ";" name_components ${test_dir}) + list(GET name_components -1 name) + add_test(NAME test-${name} + COMMAND ${CMAKE_COMMAND} + -DTEST_DIR=${test_dir} + -DIMAGE_TRANSFORMER=$<TARGET_FILE:image-transformer> + -DIMAGE_MATCHER=$<TARGET_FILE:image-matcher> + -P ${CMAKE_CURRENT_SOURCE_DIR}/tester.cmake + ) +endforeach() + +set(CMAKE_CTEST_ARGUMENTS --output-on-failure -C $<CONFIG>) +add_custom_target(check + COMMAND ${CMAKE_CTEST_COMMAND} ${CMAKE_CTEST_ARGUMENTS} + DEPENDS image-transformer image-matcher) diff --git a/tester/include/image.h b/tester/include/image.h index efced9fecf3d04b99bd4fa54c2b0648071bfd33f..da8021d53ac06686be3193a2ba631530ea21e07b 100644 --- a/tester/include/image.h +++ b/tester/include/image.h @@ -1,8 +1,8 @@ #pragma once -#include <stddef.h> -#include <malloc.h> #include <inttypes.h> +#include <malloc.h> +#include <stddef.h> #include "dimensions.h" diff --git a/tester/src/bmp.c b/tester/src/bmp.c index 4554ac22829ffd9cf3a75e8e246bafb825eee723..4f5926e548b32e70de41ef669ef8e3a331a9ab75 100644 --- a/tester/src/bmp.c +++ b/tester/src/bmp.c @@ -27,9 +27,11 @@ #define DECLARE_FIELD(t, n) t n; -struct __attribute__((packed)) header { +#pragma pack(push, 1) +struct header { FOR_HEADER(DECLARE_FIELD) }; +#pragma pack(pop) #undef FOR_HEADER #undef DECLARE_FIELD @@ -66,8 +68,8 @@ enum bmp_compare_status bmp_cmp(FILE *f1, FILE *f2) { case CMP_DIFF: return BMP_CMP_DIFF; case CMP_ERROR: return BMP_CMP_FILE_ERROR; case CMP_EQ: - if (fseek(f1, padding, SEEK_CUR) != 0 || - fseek(f2, padding, SEEK_CUR) != 0) + if (fseek(f1, (long) padding, SEEK_CUR) != 0 || + fseek(f2, (long) padding, SEEK_CUR) != 0) return BMP_CMP_FILE_ERROR; break; default: err("Implementation error"); break; diff --git a/tester/tester.cmake b/tester/tester.cmake new file mode 100644 index 0000000000000000000000000000000000000000..0dcc9196f12228d99571bd0b4a7dd801b7f00414 --- /dev/null +++ b/tester/tester.cmake @@ -0,0 +1,25 @@ +# CMP0007: list command no longer ignores empty elements. +if(POLICY CMP0007) + cmake_policy(SET CMP0007 NEW) +endif() + +function(exec_check) + execute_process(COMMAND ${ARGV} + OUTPUT_VARIABLE out + ERROR_VARIABLE err + RESULT_VARIABLE result) + if(result) + string(REPLACE "/" ";" name_components ${ARGV0}) + list(GET name_components -1 name) + if(NOT out) + set(out "<empty>") + endif() + if(NOT err) + set(err "<empty>") + endif() + message(FATAL_ERROR "\nError running \"${name}\"\n*** Output: ***\n${out}\n*** Error: ***\n${err}\n") + endif() +endfunction() + +exec_check(${IMAGE_TRANSFORMER} ${TEST_DIR}/input.bmp ${TEST_DIR}/output.bmp) +exec_check(${IMAGE_MATCHER} ${TEST_DIR}/output.bmp ${TEST_DIR}/output_expected.bmp) diff --git a/tester/tester.sh b/tester/tester.sh index 06e166a29054b1476011feb2099d50c816751d30..bafd9910b681cdc7c96c5508d92c72165253c09c 100755 --- a/tester/tester.sh +++ b/tester/tester.sh @@ -62,8 +62,8 @@ if [ "$rc" -ne "0" ]; then echo echo "Failed at creating output. Command: $main_cmd" if [ ! -z "$log_dir" ]; then - [ ! -e "$log_out" ] && echo "*** stdout log: $log_out ***" && cat $log_out - [ ! -e "$log_err" ] && echo "*** stderr log: $log_err ***" && cat $log_err + [ -s "$log_out" ] && echo "*** stdout log: $log_out ***" && cat "$log_out" + [ -s "$log_err" ] && echo "*** stderr log: $log_err ***" && cat "$log_err" fi echo echo "$test_name: Failed with exit code $rc"