как скомпилировать си файл windows

Пошаговое руководство. Компиляция программы на языке C из командной строки

В состав Visual C++ включен компилятор языка C, позволяющий создавать как простые консольные программы, так и классические приложения Windows, мобильные приложения и многое другое.

В этом пошаговом руководстве показано, как создать простейшую программу на языке C в стиле «Hello, World» в текстовом редакторе с последующей компиляцией из командной строки. Если вы предпочитаете работать с C++ в командной строке, см. статью Пошаговое руководство. Компиляция собственной программы на языке C++ из командной строки. Если вы хотите попробовать интегрированную среду разработки Visual Studio вместо командной строки, см. статью Пошаговое руководство. Работа с проектами и решениями (C++) или Использование интегрированной среды разработки Visual Studio для разработки приложений для настольных систем на языке C++.

Предварительные требования

Для выполнения этого пошагового руководства необходимо установить Visual Studio и дополнительные компоненты Visual C++ или Build Tools для Visual Studio.

Visual Studio — это эффективная интегрированная среда разработки, которая поддерживает полнофункциональный редактор, диспетчеры ресурсов, отладчики и компиляторы для многих языков и платформ. Сведения об этих компонентах, а также о скачивании и установке Visual Studio, включая бесплатный выпуск Visual Studio Community, см. в этой статье.

При использовании версии Build Tools для Visual Studio устанавливаются только программы командной строки, библиотеки и компиляторы, необходимые для сборки программ на C и C++. Это идеальный вариант для создания заданий и упражнений, а установка выполняется относительно быстро. Чтобы установить только набор программ командной строки, скачайте Build Tools для Visual Studio на странице скачивания Visual Studio, а затем запустите установщик. В установщике Visual Studio выберите рабочую нагрузку Средства сборки C++ и щелкните Установить.

Прежде чем можно будет выполнить сборку программы C или C++ в командной строке, необходимо убедиться в том, что эти средства установлены и к ним можно получить доступ из командной строки. Visual C++ имеет сложные требования к среде командной строки для поиска используемых средств, заголовков и библиотек. Visual C++ нельзя использовать в простом окне командной строки без предварительной подготовки. Вам понадобится окно командной строки разработчика, являющееся обычным окном командной строки, в котором заданы все необходимые переменные среды. К счастью, Visual C++ устанавливает ярлыки для запуска командной строки разработчика, для которой настроена среда для сборок из командной строки. К сожалению, имена ярлыков командной строки разработчика и места их расположения отличаются практически во всех версиях Visual C++ и в различных версиях Windows. Первая задача пошагового руководства — найти нужный ярлык.

Ярлык командной строки разработчика автоматически задает правильные пути для компилятора и средств, а также для всех необходимых заголовков и библиотек. Некоторые из этих значений различаются для каждой конфигурации сборки. Если вы не используете ни один из ярлыков, эти значения среды необходимо задать самостоятельно. Дополнительные сведения см. в статье Использование набора инструментов MSVC из командной строки. Так как настраивать среду разработки сложно, настоятельно рекомендуется использовать ярлык командной строки разработчика вместо создания собственного.

Инструкции отличаются в зависимости от используемой версии Visual Studio. Чтобы ознакомиться с документацией по предпочтительной версии Visual Studio, используйте селектор Версия. Он находится в верхней части оглавления на этой странице.

Открытие командной строки разработчика в Visual Studio 2022

Если вы установили Visual Studio 2022 в Windows 10 или более поздней версии, откройте меню «Пуск» и выберите Все приложения. Прокрутите вниз и откройте папку Visual Studio 2022 (не приложение Visual Studio 2022). Выберите элемент Командная строка разработчика для VS 2022, чтобы открыть окно командной строки.

Открытие командной строки разработчика в Visual Studio 2019

Если вы установили Visual Studio 2019 в Windows 10 или более поздней версии, откройте меню «Пуск» и выберите Все приложения. Прокрутите вниз и откройте папку Visual Studio 2019 (не приложение Visual Studio 2019). Выберите элемент Командная строка разработчика для VS 2019, чтобы открыть окно командной строки.

Открытие командной строки разработчика в Visual Studio 2017

Если вы установили Visual Studio 2017 в Windows 10 или более поздней версии, откройте меню «Пуск» и выберите Все приложения. Прокрутите вниз и откройте папку Visual Studio 2017 (не приложение Visual Studio 2017). Выберите элемент Командная строка разработчика для VS 2017, чтобы открыть окно командной строки.

Открытие командной строки разработчика в Visual Studio 2015

Если вы установили Microsoft Visual C++ Build Tools 2015 в Windows 10 или более поздней версии, откройте меню «Пуск» и выберите Все приложения. Прокрутите вниз и откройте папку Microsoft Visual C++ Build Tools. Выберите элемент Командная строка Native Tools x86 Visual C++ 2015, чтобы открыть окно командной строки.

Если вы используете другую версию Windows, найдите в меню «Пуск» или на начальной странице папку средств Visual Studio, содержащую ярлык командной строки разработчика. Можно также ввести «командная строка разработчика» в строке поиска в Windows и выбрать командную строку, которая соответствует установленной версии Visual Studio. Откройте окно командной строки с помощью ярлыка.

Затем убедитесь в том, что командная строка разработчика Visual C++ настроена правильно. В окне командной строки введите cl и убедитесь в том, что выходные данные выглядят примерно так:

В зависимости от установленной версии Visual C++ и обновлений текущий каталог или номера версий могут отличаться. Если приведенный выше результат похож на отображаемый, можно приступать к сборке программ C или C++ в командной строке.

Если при выполнении команды cl появляется сообщение о том, что «cl не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл», или возникают ошибки C1034 или LNK1104, дело в том, что вы не используете командную строку разработчика или что-то не так с установкой Visual C++. Для продолжения нужно будет исправить ошибку.

Если вы не можете найти ярлык командной строки разработчика или при вводе cl появляется сообщение об ошибке, возможно, возникла проблема с установкой Visual C++. При использовании Visual Studio 2017 или более поздней версии попробуйте переустановить рабочую нагрузку Разработка классических приложений на C++ с помощью установщика Visual Studio. Подробные сведения см. в статье Справка по установке средства С++ в Visual Studio. Можно также переустановить Build Tools со страницы Загрузки Visual Studio. Не переходите к следующему разделу, пока команда cl не сработает. Дополнительные сведения об установке Visual Studio и устранении неполадок см. в статье Установка Visual Studio.

В зависимости от версии Windows, установленной на компьютере, и конфигурации системы безопасности может потребоваться правой кнопкой мыши открыть контекстное меню для ярлыка командной строки разработчика и выбрать пункт Запуск от имени администратора, чтобы успешно выполнить сборку и запуск программы, созданной в этом пошаговом руководстве.

Создание файла исходного кода на языке C и его компиляция из командной строки

В окне блокнота введите следующие строки кода:

В строке меню блокнота выберите Файл > Сохранить, чтобы сохранить файл hello.c в рабочей папке.

Имя исполняемой программы (hello.exe) отображается в информации, выводимой компилятором.

Если вы получаете сообщение об ошибке, например «cl не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл», ошибке C1034 или LNK1104, командная строка разработчика настроена неправильно. Чтобы получить сведения о том, как устранить эту проблему, вернитесь к разделу Открыть командную строку разработчика.

Если вы получаете другое сообщение об ошибке или предупреждение компилятора или компоновщика, проверьте исходный код, исправьте ошибки, сохраните его и снова запустите компилятор. Для получения сведений о конкретных ошибках введите номер ошибки в поле поиска вверху этой страницы.

Программа выводит следующий текст и затем закрывается:

Поздравляем! Вы скомпилировали и запустили программу на C с помощью командной строки.

Следующие шаги

Этот пример Hello, World является самой простой программой C. Реальные программы выполняют полезные действия и имеют файлы заголовков, дополнительные исходные файлы и ссылки на библиотеки.

Вы можете использовать шаги, описанные в этом пошаговом руководстве для C, для создания собственного кода, чтобы не вводить приведенный пример. Вы также можете выполнить сборку различных примеров кода на C, которые можно найти в других местах. Чтобы скомпилировать программу с дополнительными файлами исходного кода, введите их все в командной строке, например:

cl file1.c file2.c file3.c

Компилятор выдает программу с именем file1.exe. Чтобы изменить имя на program1.exe, добавьте параметр компоновщика /out:

cl file1.c file2.c file3.c /link /out:program1.exe

Чтобы автоматически перехватывать другие ошибки программирования, рекомендуется выполнить компиляцию с помощью порога предупреждений /W3 или /W4:

cl /W4 file1.c file2.c file3.c /link /out:program1.exe

Компилятор cl.exe имеет множество других параметров, которые можно применять для создания, оптимизации, отладки и анализа кода. Чтобы просмотреть краткий список, введите cl /? в командной строке разработчика. Можно также выполнять компиляцию и компоновку отдельно и применять параметры компоновщика в более сложных сценариях сборки. Дополнительные сведения о параметрах и использовании компилятора и компоновщика см. в справочнике по сборке для C/C++.

Для настройки и создания более сложных проектов в командной строке можно использовать NMAKE и файлы makefile либо MSBuild и файлы проекта. Дополнительные сведения об использовании этих средств см. в разделах Справочник по NMAKE и MSBuild.

Языки C и C++ похожи, но имеют различия. Компилятор Microsoft C/C++ (MSVC) использует простое правило для определения языка, используемого при компиляции кода. По умолчанию компилятор MSVC рассматривает все файлы с расширением .c как исходные коды на языке С, а файлы с расширением .cpp как исходные коды на языке С++. Если указан параметр компилятора /TC, компилятор будет рассматривать все файлы как исходные коды на языке С вне зависимости от расширения.

Некоторые функции библиотеки и имена функций POSIX являются нерекомендуемыми в компиляторе MSVC. Функции поддерживаются, но предпочтительные имена изменились. Дополнительные сведения см. в статьях Функции безопасности в CRT и Предупреждение компилятора (уровень 3) C4996.

Источник

Пошаговое руководство. Компиляция собственной программы на языке C++ из командной строки

В этом пошаговом руководстве приводятся инструкции по созданию программы на языке C++ в стиле «Hello, Wolrd» в текстовом редакторе с последующей компиляцией из командной строки. Если вы хотите попробовать интегрированную среду разработки Visual Studio вместо командной строки, см. статью Пошаговое руководство. Работа с проектами и решениями (C++) или Использование интегрированной среды разработки Visual Studio для разработки приложений для настольных систем на языке C++.

В этом пошаговом руководстве вместо ввода показанного кода можно использовать собственную программу на языке C++. Также можно использовать пример кода C++ из другой статьи справки.

Предварительные требования

Для выполнения этого пошагового руководства необходимо установить Visual Studio и дополнительную рабочую нагрузку Разработка настольных приложений на C++ или Build Tools командной строки для Visual Studio.

Visual Studio — интегрированная среда разработки (IDE). Она поддерживает полнофункциональный редактор, диспетчеры ресурсов, отладчики и компиляторы для многих языков и платформ. Доступные версии включают бесплатный выпуск Visual Studio Community Edition, и все они могут поддерживать разработку на C и C++. Сведения о скачивании и установке Visual Studio см. в статье Установка поддержки C++ в Visual Studio.

Build Tools для Visual Studio устанавливают только средства, библиотеки и компиляторы командной строки, необходимые для сборки программ C и C++. Это идеальный вариант для создания заданий и упражнений, а установка выполняется относительно быстро. Чтобы установить только средства командной строки, найдите Build Tools для Visual Studio на странице загрузки Visual Studio.

Прежде чем можно будет выполнить сборку программ C или C++ в командной строке, убедитесь, что эти средства установлены и к ним можно получить доступ из командной строки. Visual C++ имеет сложные требования к среде командной строки для поиска используемых средств, заголовков и библиотек. Visual C++ нельзя использовать в простом окне командной строки без предварительной подготовки. К счастью, Visual C++ устанавливает ярлыки для запуска командной строки разработчика, для которой настроена среда для сборок из командной строки. К сожалению, имена ярлыков командной строки разработчика и места их расположения отличаются практически во всех версиях Visual C++ и в различных версиях Windows. Первая задача пошагового руководства — найти нужную командную строку.

Ярлык командной строки разработчика автоматически задает правильные пути для компилятора и средств, а также для всех необходимых заголовков и библиотек. Эти значения среды необходимо задавать самостоятельно, если используется обычное окно командной строки. Дополнительные сведения см. в статье Использование набора инструментов MSVC из командной строки. Рекомендуется использовать ярлык командной строки разработчика вместо создания собственного.

Открытие командной строки разработчика

Если вы установили Visual Studio 2017 или более поздней версии в Windows 10 или более поздней версии, откройте меню «Пуск» и выберите Все приложения. Прокрутите вниз и откройте папку Visual Studio (не приложение Visual Studio). Выберите элемент Командная строка разработчика для VS, чтобы открыть окно командной строки.

Если вы установили Microsoft Visual C++ Build Tools 2015 в Windows 10 или более поздней версии, откройте меню Пуск и выберите Все приложения. Прокрутите вниз и откройте папку Microsoft Visual C++ Build Tools. Выберите элемент Командная строка Native Tools x86 Visual C++ 2015, чтобы открыть окно командной строки.

Можно также ввести «командная строка разработчика» в строке поиска в Windows и выбрать командную строку, которая соответствует установленной версии Visual Studio. Откройте окно командной строки с помощью ярлыка.

Затем убедитесь в том, что командная строка разработчика Visual C++ настроена правильно. В окне командной строки введите cl и убедитесь в том, что выходные данные выглядят примерно так:

Возможно, существуют различия в текущем каталоге или номерах версий. Эти значения зависят от версии Visual C++ и установленных обновлений. Если приведенный выше результат похож на отображаемый, можно приступать к сборке программ C или C++ в командной строке.

Если при выполнении команды cl появляется сообщение о том, что «cl не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл», или возникают ошибки C1034 или LNK1104, дело в том, что вы не используете командную строку разработчика или что-то не так с установкой Visual C++. Для продолжения нужно будет исправить ошибку.

Если вы не можете найти ярлык командной строки разработчика или при вводе cl появляется сообщение об ошибке, возможно, возникла проблема с установкой Visual C++. Попробуйте переустановить компонент Visual C++ в Visual Studio или Microsoft Visual C++ Build Tools. Не переходите к следующему разделу, пока команда cl не сработает. Дополнительные сведения об установке Visual C++ и устранении неполадок см. в статье Установка Visual Studio.

В зависимости от версии Windows, установленной на компьютере, и конфигурации системы безопасности может потребоваться правой кнопкой мыши открыть контекстное меню для ярлыка командной строки разработчика и выбрать пункт Запуск от имени администратора, чтобы успешно выполнить сборку и запуск программы, созданной в этом пошаговом руководстве.

Создание файла исходного кода на языке Visual C++ и его компиляция из командной строки

Когда Блокнот предложит создать файл, выберите Да. Откроется пустое окно Блокнота, в котором можно ввести код для файла hello.cpp.

В окне блокнота введите следующие строки кода:

Это простая программа, которая выведет одну строку текста на экран, а затем завершит работу. Для сведения числа ошибок к минимуму скопируйте этот код и вставьте его в Блокнот.

Сохраните файл. В Блокноте, в меню Файл выберите Сохранить.

Поздравляем, вы создали исходный файл C++ hello.cpp, который готов к компиляции.

Вернитесь к окну командной строки разработчика. Введите dir в командной строке, чтобы получить список содержимого каталога c:\hello. Вы увидите исходный файл hello.cpp в списке каталогов, который выглядит примерно так:

Даты и некоторые другие данные будут отличаться на вашем компьютере.

Компилятор cl.exe создаст OBJ-файл, содержащий скомпилированный код, а затем запустит компоновщик для создания исполняемой программы с именем hello.exe. Это имя отображается в строках информации, выводимой компилятором. Выходные данные компилятора должны выглядеть следующим образом:

Если вы получаете сообщение об ошибке, например «cl не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл», ошибке C1034 или LNK1104, командная строка разработчика настроена неправильно. Чтобы получить сведения о том, как устранить эту проблему, вернитесь к разделу Открыть командную строку разработчика.

Если вы получаете другое сообщение об ошибке или предупреждение компилятора или компоновщика, проверьте исходный код, исправьте ошибки, сохраните его и снова запустите компилятор. Для получения сведений о конкретных ошибках введите номер ошибки в поле поиска.

Программа выводит следующий текст и закрывается:

Поздравляем, вы скомпилировали и запустили программу C++ с помощью средств командной строки.

Следующие шаги

Этот пример «Hello, World» является самой простой программой C++. Реальные программы обычно имеют файлы заголовков, дополнительные исходные файлы и ссылки на библиотеки.

Вы можете использовать шаги, описанные в этом пошаговом руководстве по C++, для создания собственного кода, чтобы не вводить приведенный пример. Эти шаги также позволяют собрать множество примеров кода C++, которые можно найти в других местах. Вы можете разместить исходный код и собрать приложения в любом доступном для записи каталоге. По умолчанию интегрированная среда разработки Visual Studio создает проекты в папке пользователя во вложенной папке source\repos. Более старые версии могут помещать проекты в папку Документы\Visual Studio \ Проекты*.

Чтобы скомпилировать программу с дополнительными файлами исходного кода, введите их все в командной строке, например:

cl /EHsc file1.cpp file2.cpp file3.cpp

Параметр командной строки /EHsc указывает компилятору на необходимость стандартной обработки исключений C++. В противном случае созданные исключения могут привести к неуничтоженным объектам и утечкам ресурсов. Дополнительные сведения см. в статье /EH (модель обработки исключений).

При указании дополнительных исходных файлов компилятор использует первый входной файл для создания имени программы. В этом случае выводится программа с именем file1.exe. Чтобы изменить имя на program1.exe, добавьте параметр компоновщика /out:

cl /EHsc file1.cpp file2.cpp file3.cpp /link /out:program1.exe

Чтобы автоматически перехватывать другие ошибки программирования, рекомендуется выполнить компиляцию с помощью порога предупреждений /W3 или /W4:

cl /W4 /EHsc file1.cpp file2.cpp file3.cpp /link /out:program1.exe

В компиляторе cl.exe есть множество дополнительных параметров. Их можно применять для создания, оптимизации, отладки и анализа кода. Чтобы просмотреть краткий список, введите cl /? в командной строке разработчика. Можно также выполнять компиляцию и компоновку отдельно и применять параметры компоновщика в более сложных сценариях сборки. Дополнительные сведения о параметрах и использовании компилятора и компоновщика см. в справочнике по сборке для C/C++.

Для настройки и создания более сложных проектов в командной строке можно использовать NMAKE и файлы makefile, MSBuild и файл проекта или CMake. Дополнительные сведения об использовании этих средств см. в разделах Справочник по NMAKE, MSBuild и Проекты CMake в Visual Studio.

Языки C и C++ похожи, но имеют различия. Компилятор MSVC использует простое правило для определения языка, используемого при компиляции кода. По умолчанию компилятор MSVC рассматривает файлы с расширением .c как исходные файлы на языке С, а файлы с расширением .cpp — как исходные файлы на языке С++. Если указан параметр компилятора /TP, компилятор будет рассматривать все файлы как исходные файлы на языке С++ вне зависимости от расширения.

Компилятор MSVC содержит библиотеку времени выполнения C (CRT), которая соответствует стандарту ISO C99 с небольшими исключениями. Переносимый код обычно компилируется и выполняется, как ожидалось. Некоторые устаревшие функции библиотеки и несколько имен функций POSIX не рекомендуется использовать в компиляторе MSVC. Функции поддерживаются, но предпочтительные имена изменились. Дополнительные сведения см. в статьях Функции безопасности в CRT и Предупреждение компилятора (уровень 3) C4996.

Источник

Процесс компиляции программ на C++

Цель данной статьи:

В данной статье я хочу рассказать о том, как происходит компиляция программ, написанных на языке C++, и описать каждый этап компиляции. Я не преследую цель рассказать обо всем подробно в деталях, а только дать общее видение. Также данная статья — это необходимое введение перед следующей статьей про статические и динамические библиотеки, так как процесс компиляции крайне важен для понимания перед дальнейшим повествованием о библиотеках.

Все действия будут производиться на Ubuntu версии 16.04.
Используя компилятор g++ версии:

Состав компилятора g++

Мы не будем вызывать данные компоненты напрямую, так как для того, чтобы работать с C++ кодом, требуются дополнительные библиотеки, позволив все необходимые подгрузки делать основному компоненту компилятора — g++.

Зачем нужно компилировать исходные файлы?

Исходный C++ файл — это всего лишь код, но его невозможно запустить как программу или использовать как библиотеку. Поэтому каждый исходный файл требуется скомпилировать в исполняемый файл, динамическую или статическую библиотеки (данные библиотеки будут рассмотрены в следующей статье).

Этапы компиляции:

driver.cpp:

1) Препроцессинг

Самая первая стадия компиляции программы.

Препроцессор — это макро процессор, который преобразовывает вашу программу для дальнейшего компилирования. На данной стадии происходит происходит работа с препроцессорными директивами. Например, препроцессор добавляет хэдеры в код (#include), убирает комментирования, заменяет макросы (#define) их значениями, выбирает нужные куски кода в соответствии с условиями #if, #ifdef и #ifndef.

Хэдеры, включенные в программу с помощью директивы #include, рекурсивно проходят стадию препроцессинга и включаются в выпускаемый файл. Однако, каждый хэдер может быть открыт во время препроцессинга несколько раз, поэтому, обычно, используются специальные препроцессорные директивы, предохраняющие от циклической зависимости.

Получим препроцессированный код в выходной файл driver.ii (прошедшие через стадию препроцессинга C++ файлы имеют расширение .ii), используя флаг -E, который сообщает компилятору, что компилировать (об этом далее) файл не нужно, а только провести его препроцессинг:

Взглянув на тело функции main в новом сгенерированном файле, можно заметить, что макрос RETURN был заменен:

В новом сгенерированном файле также можно увидеть огромное количество новых строк, это различные библиотеки и хэдер iostream.

2) Компиляция

На данном шаге g++ выполняет свою главную задачу — компилирует, то есть преобразует полученный на прошлом шаге код без директив в ассемблерный код. Это промежуточный шаг между высокоуровневым языком и машинным (бинарным) кодом.

Ассемблерный код — это доступное для понимания человеком представление машинного кода.

Используя флаг -S, который сообщает компилятору остановиться после стадии компиляции, получим ассемблерный код в выходном файле driver.s:

Мы можем все также посмотреть и прочесть полученный результат. Но для того, чтобы машина поняла наш код, требуется преобразовать его в машинный код, который мы и получим на следующем шаге.

3) Ассемблирование

Так как x86 процессоры исполняют команды на бинарном коде, необходимо перевести ассемблерный код в машинный с помощью ассемблера.

Ассемблер преобразовывает ассемблерный код в машинный код, сохраняя его в объектном файле.

Объектный файл — это созданный ассемблером промежуточный файл, хранящий кусок машинного кода. Этот кусок машинного кода, который еще не был связан вместе с другими кусками машинного кода в конечную выполняемую программу, называется объектным кодом.

Далее возможно сохранение данного объектного кода в статические библиотеки для того, чтобы не компилировать данный код снова.

Получим машинный код с помощью ассемблера (as) в выходной объектный файл driver.o:

Но на данном шаге еще ничего не закончено, ведь объектных файлов может быть много и нужно их всех соединить в единый исполняемый файл с помощью компоновщика (линкера). Поэтому мы переходим к следующей стадии.

4) Компоновка

Компоновщик (линкер) связывает все объектные файлы и статические библиотеки в единый исполняемый файл, который мы и сможем запустить в дальнейшем. Для того, чтобы понять как происходит связка, следует рассказать о таблице символов.

Таблица символов — это структура данных, создаваемая самим компилятором и хранящаяся в самих объектных файлах. Таблица символов хранит имена переменных, функций, классов, объектов и т.д., где каждому идентификатору (символу) соотносится его тип, область видимости. Также таблица символов хранит адреса ссылок на данные и процедуры в других объектных файлах.
Именно с помощью таблицы символов и хранящихся в них ссылок линкер будет способен в дальнейшем построить связи между данными среди множества других объектных файлов и создать единый исполняемый файл из них.

Получим исполняемый файл driver:

5) Загрузка

Последний этап, который предстоит пройти нашей программе — вызвать загрузчик для загрузки нашей программы в память. На данной стадии также возможна подгрузка динамических библиотек.

Запустим нашу программу:

Заключение

В данной статье были рассмотрены основы процесса компиляции, понимание которых будет довольно полезно каждому начинающему программисту. В скором времени будет опубликована вторая статья про статические и динамические библиотеки.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *