Merge branch 'asciidoc'

This commit is contained in:
Andrei Astafev 2019-06-03 10:04:55 +03:00
commit 3b34f960b5
90 changed files with 3258 additions and 3034 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
cache/* cache/*
cache-ascii/*
cache-full/* cache-full/*
cache-html/* cache-html/*
output/* output/*
@ -6,4 +7,6 @@ __pycache__
wiki/trash wiki/trash
wiki/notes.sqlite wiki/notes.sqlite
upload.sh upload.sh
wiki/**/*.png
wiki/**/*.png.cache

3
.gitmodules vendored
View File

@ -23,3 +23,6 @@
[submodule "plugins/thirdparty/replacer"] [submodule "plugins/thirdparty/replacer"]
path = plugins/thirdparty/replacer path = plugins/thirdparty/replacer
url = git@github.com:/narusemotoki/replacer url = git@github.com:/narusemotoki/replacer
[submodule "plugins/thirdparty/asciidoctor"]
path = plugins/thirdparty/asciidoctor
url = git@git.246060.ru:f1x1t/pelican-asciidoctor

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals from __future__ import unicode_literals
import os
class i18n(object): class i18n(object):
# looks for translations in # looks for translations in
@ -54,23 +55,12 @@ AUTHOR_FEED_RSS = None
USE_FOLDER_AS_CATEGORY = True USE_FOLDER_AS_CATEGORY = True
DEFAULT_DATE = 'fs' DEFAULT_DATE = 'fs'
STATIC_PATHS = [ 'images', 'files', 'extras' ] STATIC_PATHS = [ 'images', 'files', 'extras' ]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
EXTRA_PATH_METADATA = { EXTRA_PATH_METADATA = {
'extras/favicon.ico': {'path': 'favicon.ico'}, 'extras/favicon.ico': {'path': 'favicon.ico'},
} }
MARKDOWN = {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {
'title': 'Содержание'
},
} ,
'output_format': 'html5',
}
DISPLAY_CATEGORIES_ON_MENU = False DISPLAY_CATEGORIES_ON_MENU = False
DISPLAY_CATEGORIES_ON_SIDEBAR = True DISPLAY_CATEGORIES_ON_SIDEBAR = True
DISPLAY_TAGS_ON_SIDEBAR = True DISPLAY_TAGS_ON_SIDEBAR = True
@ -85,50 +75,31 @@ I18N_GETTEXT_DOMAIN = 'messages'
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']} JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"] PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"]
PLUGINS = [i18n(), "pandoc_reader", "pelican-css", "pelidoc", "series", "subcategory", "tag_cloud", "tipue_search", "plantuml", "replacer"] PLUGINS = [i18n(), "pelican-css", "series", "subcategory", "tag_cloud", "tipue_search", "replacer", "asciidoctor"]
#PLUGINS = ["better_tables", "just_table"]
PDF_PROCESSOR = True
PANDOC_OUTPUTS = { ASCIIDOCTOR_CMD = "asciidoctor"
'pdf': 'pdf', ASCIIDOCTOR_EXTRA_OPTIONS = [
} '--require', 'asciidoctor-diagram',
'--attribute=imagesdir={}/wiki/images'.format(os.getcwd()),
PANDOC_ARGS = [ '--attribute=source-highlighter=pygments',
"--variable=documentclass:extarticle", '--attribute=pygments-style=manni',
"--variable=toc-title:Содержание", '--attribute=pygments-css=class',
"--filter=skip-toc-tag", '--attribute=lang=ru',
"--filter=pandoc_plantuml_filter.py", '--attribute=figure-caption=Рис.',
"--highlight-style=tango", '--attribute=toc-title=Содержание',
"--template=wiki", '--attribute=experimental',
"--resource-path=wiki:."
] ]
PANDOC_EXTRA_OPTIONS = PANDOC_ARGS + [ "--pdf-engine=xelatex" ]
PANDOC_MARKDOWN_EXTENSIONS = [
"+smart",
"+backtick_code_blocks",
"+fenced_code_blocks",
"+fenced_code_attributes",
"+fenced_divs",
"+native_divs",
"+bracketed_spans",
"+native_spans"
]
PANDOC_EXTENSIONS = PANDOC_MARKDOWN_EXTENSIONS
REPLACES = ( REPLACES = (
(u'output/images/', u'images/'), ('{}/wiki/'.format(os.getcwd()), u''),
) )
YUICOMPRESSOR_EXECUTABLE = "yui-compressor" YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"] YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"]
PLUGINS += ["yuicompressor-opt"] PLUGINS += ["yuicompressor-opt"]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search') PDF_PROCESSOR = True
# Blogroll # Blogroll
LINKS = () LINKS = ()
@ -142,7 +113,7 @@ SOCIAL = ()
# SOCIAL = (('You can add links in your config file', '#'), # SOCIAL = (('You can add links in your config file', '#'),
# ('Another social link', '#'),) # ('Another social link', '#'),)
PYGMENTS_STYLE='pastie' PYGMENTS_STYLE='asciidoctor-pastie'
DEFAULT_PAGINATION = 20 DEFAULT_PAGINATION = 20

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals from __future__ import unicode_literals
import os
class i18n(object): class i18n(object):
# looks for translations in # looks for translations in
@ -35,7 +36,7 @@ SITENAME = 'ДСП'
SITEURL = 'https://dsp.246060.ru' SITEURL = 'https://dsp.246060.ru'
PATH = 'wiki' PATH = 'wiki'
CACHE_PATH = 'cache-html' CACHE_PATH = 'cache'
TIMEZONE = 'Europe/Moscow' TIMEZONE = 'Europe/Moscow'
@ -54,23 +55,12 @@ AUTHOR_FEED_RSS = None
USE_FOLDER_AS_CATEGORY = True USE_FOLDER_AS_CATEGORY = True
DEFAULT_DATE = 'fs' DEFAULT_DATE = 'fs'
STATIC_PATHS = [ 'images', 'files', 'extras' ] STATIC_PATHS = [ 'images', 'files', 'extras' ]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
EXTRA_PATH_METADATA = { EXTRA_PATH_METADATA = {
'extras/favicon.ico': {'path': 'favicon.ico'}, 'extras/favicon.ico': {'path': 'favicon.ico'},
} }
MARKDOWN = {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {
'title': 'Содержание'
},
} ,
'output_format': 'html5',
}
DISPLAY_CATEGORIES_ON_MENU = False DISPLAY_CATEGORIES_ON_MENU = False
DISPLAY_CATEGORIES_ON_SIDEBAR = True DISPLAY_CATEGORIES_ON_SIDEBAR = True
DISPLAY_TAGS_ON_SIDEBAR = True DISPLAY_TAGS_ON_SIDEBAR = True
@ -85,50 +75,31 @@ I18N_GETTEXT_DOMAIN = 'messages'
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']} JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"] PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"]
PLUGINS = [i18n(), "pandoc_reader", "pelican-css", "pelidoc", "series", "subcategory", "tag_cloud", "tipue_search", "plantuml", "replacer"] PLUGINS = [i18n(), "pelican-css", "series", "subcategory", "tag_cloud", "tipue_search", "replacer", "asciidoctor"]
#PLUGINS = ["better_tables", "just_table"]
#PDF_PROCESSOR = True
PANDOC_OUTPUTS = { ASCIIDOCTOR_CMD = "asciidoctor"
'pdf': 'pdf', ASCIIDOCTOR_EXTRA_OPTIONS = [
} '--require', 'asciidoctor-diagram',
'--attribute=imagesdir={}/wiki/images'.format(os.getcwd()),
PANDOC_ARGS = [ '--attribute=source-highlighter=pygments',
"--variable=documentclass:extarticle", '--attribute=pygments-style=manni',
"--variable=toc-title:Содержание", '--attribute=pygments-css=class',
"--filter=skip-toc-tag", '--attribute=lang=ru',
"--filter=pandoc_plantuml_filter.py", '--attribute=figure-caption=Рис.',
"--highlight-style=tango", '--attribute=toc-title=Содержание',
"--template=wiki", '--attribute=experimental',
"--resource-path=wiki:."
] ]
PANDOC_EXTRA_OPTIONS = PANDOC_ARGS + [ "--pdf-engine=xelatex" ]
PANDOC_MARKDOWN_EXTENSIONS = [
"+smart",
"+backtick_code_blocks",
"+fenced_code_blocks",
"+fenced_code_attributes",
"+fenced_divs",
"+native_divs",
"+bracketed_spans",
"+native_spans"
]
PANDOC_EXTENSIONS = PANDOC_MARKDOWN_EXTENSIONS
REPLACES = ( REPLACES = (
(u'output/images/', u'images/'), ('{}/wiki/'.format(os.getcwd()), u''),
) )
YUICOMPRESSOR_EXECUTABLE = "yui-compressor" YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"] YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"]
#PLUGINS += ["yuicompressor-opt"] #PLUGINS += ["yuicompressor-opt"]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search') #PDF_PROCESSOR = True
# Blogroll # Blogroll
LINKS = () LINKS = ()
@ -142,7 +113,7 @@ SOCIAL = ()
# SOCIAL = (('You can add links in your config file', '#'), # SOCIAL = (('You can add links in your config file', '#'),
# ('Another social link', '#'),) # ('Another social link', '#'),)
PYGMENTS_STYLE='pastie' PYGMENTS_STYLE='asciidoctor-pastie'
DEFAULT_PAGINATION = 20 DEFAULT_PAGINATION = 20

@ -1 +1 @@
Subproject commit cfc7a3f224f1743063b034561f89a6a712d13587 Subproject commit 8cea2c6492f98e11341c48556978da7f6756f8a0

1
plugins/thirdparty/asciidoctor vendored Submodule

@ -0,0 +1 @@
Subproject commit 9e0019a728113f8502d04eeca8bf2682219086b6

@ -1 +1 @@
Subproject commit 4471139a1a419abc4e2aa94c09f0ef7550c65b00 Subproject commit ce6b18660a933855dbe996fc5b5d3d0ac1c25223

View File

@ -0,0 +1,12 @@
= LaTeX: висячие строки
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Пакет https://www.ctan.org/pkg/nowidow[`nowidow`] используется для
изменения алгоритма размещения висячих строк. Пример:
[source,latex]
----
\usepackage[defaultlines=3,all]{nowidow}
----

View File

@ -1,14 +0,0 @@
---
title: "LaTeX: висячие строки"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Пакет [`nowidow`](https://www.ctan.org/pkg/nowidow) используется для
изменения алгоритма размещения висячих строк. Пример:
```latex
\usepackage[defaultlines=3,all]{nowidow}
```

View File

@ -0,0 +1,105 @@
= LyX: редактирование ЕСПД
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, LyX,
Установить пакеты:
[source,sh]
----
sudo apt-get install lyx texlive-xetex
----
Установить стили LaTeX для http://tiny.cc/u8eo7y[ЕСПД]:
[source,sh]
----
git clone https://git.246060.ru/f1x1t/latex-style-esdpx ~/texmf/tex/latex/espdx
----
Установить шаблоны для LyX:
[source,sh]
----
git clone https://git.246060.ru:/f1x1t/lyx-layout-espdx.git ~/.lyx/layouts
----
Запустить LyX и в меню выбрать menu:Инструменты[Обновить конфигурацию] и
перезапустить программу.
Скачать link:files/espdx-template.lyx[шаблон] для LyX, открыть файл
*espdx-template.lyx* и в меню выбрать menu:Документ[Настройки…].
В появившемся окне нажать кнопку btn:[Сохранить как параметры
документа по умолчанию].
Пример настройки:
[.text-center]
.Класс документа
image::lyx-espdx/01.png[Класс документа]
[.text-center]
.Модули
image::lyx-espdx/02.png[Модули]
[.text-center]
.Шрифты
image::lyx-espdx/03.png[Шрифты]
[.text-center]
.Макет текста
image::lyx-espdx/04.png[Макет текста]
[.text-center]
.Макет страницы
image::lyx-espdx/05.png[Макет страницы]
[.text-center]
.Поля страницы
image::lyx-espdx/06.png[Поля страницы]
[.text-center]
.Язык
image::lyx-espdx/07.png[Язык]
[.text-center]
.Нумерация и содержание
image::lyx-espdx/08.png[Нумерация и содержание]
[.text-center]
.Библиография
image::lyx-espdx/09.png[Библиография]
[.text-center]
.Предметный указатель
image::lyx-espdx/10.png[Предметный указатель]
[.text-center]
.Свойства PDF / Общие
image::lyx-espdx/11.png[Свойства PDF / Общие]
[.text-center]
.Свойства PDF / Гиперссылки
image::lyx-espdx/12.png[Свойства PDF / Гиперссылки]
[.text-center]
.Свойства PDF / Закладки
image::lyx-espdx/13.png[Свойства PDF / Закладки]
[.text-center]
.Параметры математики
image::lyx-espdx/14.png[Параметры математики]
[.text-center]
.Размещение плавающих объектов
image::lyx-espdx/15.png[Размещение плавающих объектов]
[.text-center]
.Форматы
image::lyx-espdx/16.png[Форматы]
[.text-center]
.Преамбула LaTeX
image::lyx-espdx/17.png[Преамбула LaTeX]

View File

@ -1,69 +0,0 @@
---
title: "LyX: редактирование ЕСПД"
category: LaTeX
tags: LaTeX, текст, LyX,
summary:
...
Установить пакеты:
```sh
sudo apt-get install lyx texlive-xetex
```
Установить стили LaTeX для ЕСПД:
```
git clone https://git.246060.ru/f1x1t/latex-style-esdpx ~/texmf/tex/latex/espdx
```
Установить шаблоны для LyX:
```
git clone https://git.246060.ru:/f1x1t/lyx-layout-espdx.git ~/.lyx/layouts
```
Запустить LyX и в меню __Инструменты__ выбрать __Обновить конфигурацию__
и перезапустить программу.
Скачать [шаблон](files/espdx-template.lyx) для LyX, открыть файл
**espdx-template.lyx** и в меню выбрать __Документ / Настройки...__.
В появившемся окне нажать кнопку __Сохранить как параметры документа по умолчанию__.
Пример настройки:
![Класс документа](images/lyx-espdx/01.png)
![Модули](images/lyx-espdx/02.png)
![Шрифты](images/lyx-espdx/03.png)
![Макет текста](images/lyx-espdx/04.png)
![Макет страницы](images/lyx-espdx/05.png)
![Поля страницы](images/lyx-espdx/06.png)
![Язык](images/lyx-espdx/07.png)
![Нумерация и содержание](images/lyx-espdx/08.png)
![Библиография](images/lyx-espdx/09.png)
![Предметный указатель](images/lyx-espdx/10.png)
![Свойства PDF / Общие](images/lyx-espdx/11.png)
![Свойства PDF / Гиперссылки](images/lyx-espdx/12.png)
![Свойства PDF / Закладки](images/lyx-espdx/13.png)
![Параметры математики](images/lyx-espdx/14.png)
![Размещение плавающих объектов](images/lyx-espdx/15.png)
![Форматы](images/lyx-espdx/16.png)
![Преамбула LaTeX](images/lyx-espdx/17.png)

View File

@ -0,0 +1,13 @@
= LaTeX: защита команд
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Команда `\protect` используется для защиты инструкций внутри хрупких
команд. Например, для защиты команды переноса строки внутри команды
`section` нужно написать:
[source,latex]
----
\section{Первая строка\protect\\Вторая строка}
----

View File

@ -1,15 +0,0 @@
---
title: "LaTeX: защита команд"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Команда `\protect` используется для защиты инструкций внутри
хрупких команд. Например, для защиты команды переноса строки
внутри команды `section` нужно написать:
```latex
\section{Первая строка\protect\\Вторая строка}
```

View File

@ -1,14 +1,12 @@
--- = LaTeX: лигатуры
title: "LaTeX: лигатуры" :title-separator: {sp}|
category: LaTeX :category: LaTeX
tags: LaTeX, шрифты, :tags: LaTeX, шрифты,
summary:
...
Команды для запрета использования лигатур: Команды для запрета использования лигатур:
```latex [source,latex]
----
\usepackage{microtype} \usepackage{microtype}
\DisableLigatures[f]{encoding = *, family = *} \DisableLigatures[f]{encoding = *, family = *}
``` ----

View File

@ -0,0 +1,29 @@
= LyX: многостраничные таблицы
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, LyX, таблицы,
* Создать таблицу как минимум с четырьмя строками.
* Щёлкнуть правой кнопкой мыши на таблице, выбрать во всплывающем меню
*Длинная таблица*.
* Щёлкнуть правой кнопкой мыши на таблице, выбрать во всплывающем меню
*Настройки*.
* Установить курсор на первой строке таблицы, в окне настроек перейти на
вкладку *Длинная таблица*.
* Выбрать *Подпись* и *Первый заголовок*.
* Нажать *Применить*.
* Установить курсор на второй строке таблицы, в окне настроек перейти на
вкладку *Длинная таблица*.
* Выбрать *Подпись* и *Заголовок*.
* Нажать *Применить*.
* Установить курсор на третьей строке таблицы, в окне настроек перейти
на вкладку *Длинная таблица*.
* Выбрать *Заголовок* и *Первый заголовок*.
* Нажать *Применить*.
* Щёлкнуть правой кнопкой мыши на второй строке таблицы, выбрать в меню
*Подпись (Ненумерованный)*.
* На первой строке таблицы установить метку и ввести текст подписи к
таблице на начальной странице.
* На второй строке таблицы сформировать текст подписи к таблице, который
будет использоваться на последующих страницах.
* На третьей строке нужно сформировать заголовок таблицы.

View File

@ -1,32 +0,0 @@
---
title: "LyX: многостраничные таблицы"
category: LaTeX
tags: LaTeX, текст, LyX, таблицы,
summary:
...
- Создать таблицу как минимум с четырьмя строками.
- Щелкнуть правой кнопкой мыши на таблице, выбрать во всплывающем
меню **Длинная таблица**.
- Щелкнуть правой кнопкой мыши на таблице, выбрать во всплывающем
меню **Настройки**.
- Установить курсор на первой строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Подпись** и **Первый заголовок**.
- Нажать **Применить**.
- Установить курсор на второй строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Подпись** и **Заголовок**.
- Нажать **Применить**.
- Установить курсор на третьей строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Заголовок** и **Первый заколовок**.
- Нажать **Применить**.
- Щелкнуть правой кнопкой мыши на второй строке таблицы, выбрать в меню
**Подпись (Ненумерованный)**.
- На первой строке таблицы установить метку и ввести текст подписи к
таблице на начальной странице.
- На второй строке таблицы сформировать текст подписи к таблице,
который будет использоваться на последующих страницах.
- На третьей строке нужно сформировать заголовок таблицы.

View File

@ -0,0 +1,8 @@
= LaTeX: переносы строк
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Текст между командами `\sloppy` и `\fussy` или внутри блока
`\begin{sloppypar} ... \end{sloppypar}` будет переноситься сразу при
достижении края бокса.

View File

@ -1,11 +0,0 @@
---
title: "LaTeX: переносы строк"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Текст между командами `\sloppy` и `\fussy` или внутри блока
`\begin{sloppypar} ... \end{sloppypar}` будет переноситься
сразу при достижении края бокса.

View File

@ -0,0 +1,20 @@
= LaTeX: русский язык в выходном PDF
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, PDF,
Данный метод используется только в LaTeX, в XeTeX (XeLaTeX) генерация
PDF работает изначально.
Для поиска в файле PDF и копирования текста с правильной кодировкой
нужно использовать пакет https://www.ctan.org/pkg/cmap[`cmap`]. Включать
использование пакета нужно как можно раньше, чтобы правильно
формировалась служебная информация и титульные листы.
[source,latex]
----
\usepackage{cmap}
----
Полезная http://s.arboreus.com/2007/07/pdf-latex.html[информация] о
выводе из LaTeX в PDF.

View File

@ -1,22 +0,0 @@
---
title: "LaTeX: русский язык в выходном PDF"
category: LaTeX
tags: LaTeX, текст, PDF,
summary:
...
Данный метод используется только в LaTeX, в XeTeX (XeLaTeX) генерация PDF
работает изначально.
Для поиска в файле PDF и копирования текста с правильной кодировкой
нужно использовать пакет [`cmap`](https://www.ctan.org/pkg/cmap).
Включать использование пакета нужно как можно раньше, чтобы правильно
формировалась служебная информация и титульные листы.
```latex
\usepackage{cmap}
```
Полезная [информация](http://s.arboreus.com/2007/07/pdf-latex.html)
о выводе из LaTeX в PDF.

View File

@ -1,26 +1,26 @@
--- = Astra: авторизация в PostgreSQL через PAM
title: "Astra: авторизация в PostgreSQL через PAM" :title-separator: {sp}|
category: Linux :category: Linux
tags: Linux, Astra, postgresql, базы данных, :tags: Linux, Astra, postgresql, базы данных,
summary:
...
Для обеспечения авторизации пользователей через PAM системному Для обеспечения авторизации пользователей через PAM системному
пользователю `postgres`, с правами которого выполняется сервер пользователю `postgres`, с правами которого выполняется сервер базы
базы данных, необходимо выдать права на чтение информации из базы данных, необходимо выдать права на чтение информации из базы данных
данных пользователей и сведений о мандатных метках и привилегиях: пользователей и сведений о мандатных метках и привилегиях:
```sh [source,sh]
----
usermod -a -G shadow postgres usermod -a -G shadow postgres
setfacl -d -m u:postgres:r /etc/parsec/macdb setfacl -d -m u:postgres:r /etc/parsec/macdb
setfacl -R -m u:postgres:r /etc/parsec/macdb setfacl -R -m u:postgres:r /etc/parsec/macdb
setfacl -m u:postgres:rx /etc/parsec/macdb setfacl -m u:postgres:rx /etc/parsec/macdb
``` ----
Для обеспечения возможности авторизации пользователя `user`, Для обеспечения возможности авторизации пользователя `user`,
зарегистрированного в системе PAM, нужно выполнить команду зарегистрированного в системе PAM, нужно выполнить команду
```sh [source,sh]
----
usermac -c 0:0 -l 0:0 user usermac -c 0:0 -l 0:0 user
``` ----

View File

@ -1,42 +1,46 @@
--- = CUPS: команды
title: "CUPS: команды" :title-separator: {sp}|
category: Linux :category: Linux
tags: Linux, печать, CUPS :tags: Linux, печать, CUPS,
...
Текущее состояние принтера (см. также [lpstat](http://cheat.sh/lpstat)): Текущее состояние принтера (см. также http://cheat.sh/lpstat[lpstat]):
```sh [source,sh]
----
lpstat -h hostname -p printer_name lpstat -h hostname -p printer_name
``` ----
Возобновить работу принтера: Возобновить работу принтера:
```sh [source,sh]
----
lpadmin -h hostname -p printer_name -E lpadmin -h hostname -p printer_name -E
``` ----
Печать (см. также [lp](http://cheat.sh/lp)): Печать (см. также http://cheat.sh/lp[lp]):
```sh [source,sh]
----
lp -h hostname -d printer_name file.pdf lp -h hostname -d printer_name file.pdf
``` ----
Просмотр очереди: Просмотр очереди:
```sh [source,sh]
----
lpq -h hostname -p printer_name lpq -h hostname -p printer_name
``` ----
Удаление задания job-id из очереди: Удаление задания job-id из очереди:
```sh [source,sh]
----
lprm -h hostname -p printer_name job-id lprm -h hostname -p printer_name job-id
``` ----
Удаление всех заданий из очереди: Удаление всех заданий из очереди:
```sh [source,sh]
----
lprm -h hostname -p printer_name - lprm -h hostname -p printer_name -
``` ----

View File

@ -1,12 +1,10 @@
--- = APT
title: "APT" :category: Linux
category: Linux :tags: linux, ubuntu, debian, apt,
tags: linux, ubuntu, debian, apt,
summary:
...
Запрет загрузки переводов описаний пакетов: Запрет загрузки переводов описаний пакетов:
```sh [source,sh]
----
echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/99translations echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/99translations
``` ----

View File

@ -1,32 +1,36 @@
--- = GnuPG: шифрование файлов
title: "GnuPG: шифрование файлов" :title-separator: {sp}|
category: Linux :category: Linux
tags: Linux, GnuPG, безопасность :tags: Linux, GnuPG, безопасность
...
Для шифрования файлов с использованием публичного ключа адресата можно выполнить команду: Для шифрования файлов с использованием публичного ключа адресата можно
выполнить команду:
```sh [source,sh]
----
tar cp files_list | pv | gpg -e --recipient user@domain.tld > archive.tar.gpg tar cp files_list | pv | gpg -e --recipient user@domain.tld > archive.tar.gpg
``` ----
По умолчанию во время шифрования данные сжимаются компрессорами `zip` или `gzip`, По умолчанию во время шифрования данные сжимаются компрессорами `zip`
поэтому сжимать данные до `gpg` не нужно. Можно отключить стандартный алгоритм сжатия и или `gzip`, поэтому сжимать данные до `gpg` не нужно. Можно отключить
использовать собственный компрессор, например `xz`: стандартный алгоритм сжатия и использовать собственный компрессор,
например `xz`:
```sh [source,sh]
----
tar cp files_list | pv | xz -9 | gpg -e --compress-algo none --recipient user@domain.tld > archive.tar.xz.gpg tar cp files_list | pv | xz -9 | gpg -e --compress-algo none --recipient user@domain.tld > archive.tar.xz.gpg
``` ----
Для шифрования с использованием пароля: Для шифрования с использованием пароля:
```sh [source,sh]
----
tar cf files_list | pv | gpg -c > archive.tar.gpg tar cf files_list | pv | gpg -c > archive.tar.gpg
``` ----
Для расшифровки нужно выполнить команду: Для расшифровки нужно выполнить команду:
```sh [source,sh]
----
gpg -d archive.tar.gpg --output archive.tar gpg -d archive.tar.gpg --output archive.tar
``` ----

View File

@ -0,0 +1,28 @@
= Прерывания GPE
:category: Linux
:tags: Linux, hardware, железо,
Неисправная аппаратура может генерировать большое количество прерываний,
что приводит к заметному ухудшению отзывчивости системы. Проверить
наличие подобной ситуации можно командой
[source,sh]
----
find /sys/firmware/acpi/interrupts | sort | while read i; do echo "$i:"; cat $i; done
----
Если в выводе будет присутствовать очень большое число, то значит
проявляется именно данная проблема. Для временного исправления можно
заблокировать прерывание, выполнив команду
[source,sh]
----
echo 0 > /sys/firmware/acpi/interrupts/gpeXX 2>/dev/null
----
где XX номер прерывания, для которого зафиксировано большое число
срабатываний. Для полного исправления проблемы нужно разбираться с
аппаратурой.
https://unix.stackexchange.com/questions/242013/disable-gpe-acpi-interrupts-on-boot[См.
также]

View File

@ -1,28 +0,0 @@
---
title: "Прерывания GPE"
category: Linux
tags: Linux, hardware, железо,
summary:
...
Неисправная аппаратура может генерировать большое количество прерываний,
что приводит к заметному ухудшению отзывчивости системы. Проверить
наличие подобной ситуации можно командой
```sh
find /sys/firmware/acpi/interrupts | sort | while read i; do echo "$i:"; cat $i; done
```
Если в выводе будет присутствовать очень большое число, то значит проявляется
именно данная проблема. Для временного исправления можно заблокировать прерывание,
выполнив команду
```sh
echo 0 > /sys/firmware/acpi/interrupts/gpeXX 2>/dev/null
```
где XX номер прерывания, для которого зафиксировано большое число срабатываний.
Для полного исправления проблемы нужно разбираться с аппаратурой.
[См. также](https://unix.stackexchange.com/questions/242013/disable-gpe-acpi-interrupts-on-boot)

View File

@ -0,0 +1,15 @@
= DNS в контейнере LXC
:category: Linux
:tags: lxc, контейнеры, ubuntu, linux, dns,
В системе Ubuntu 18.04 работающей внутри контейнера LXC по умолчанию не
работает разрешение имён. Чтобы использовать DNS-сервер `8.8.8.8`, нужно
внутри контейнера выполнить команды:
[source,sh]
----
sed -i 's/#DNS=/DNS=8.8.8.8/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
----

View File

@ -1,17 +0,0 @@
---
title: "DNS в контейнере LXC"
category: Linux
tags: lxc, контейнеры, ubuntu, linux, dns,
summary:
...
В системе Ubuntu 18.04 работающей внутри контейнера LXC по умолчанию
не работает разрешение имён. Чтобы использовать DNS-сервер `8.8.8.8`,
нужно внутри контейнера выполнить команды:
```sh
sed -i 's/#DNS=/DNS=8.8.8.8/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
```

View File

@ -1,28 +1,28 @@
--- = runit: система инициализации
title: "runit: система инициализации" :title-separator: {sp}|
category: Linux :category: Linux
tags: Debian, Ubuntu, Linux, инициализация, runit, :tags: Debian, Ubuntu, Linux, инициализация, runit,
summary:
...
### Установка == Установка
[runit](http://smarden.org/runit/) — это система инициализации со http://smarden.org/runit/[runit] — это система инициализации со
встроенными средствами контроля за процессами. встроенными средствами контроля за процессами.
Установка в Ubuntu: Установка в Ubuntu:
```sh [source,sh]
----
sudo apt-get install runit runit-systemd sudo apt-get install runit runit-systemd
``` ----
### Запуск сервисов от непривилегированного пользователя == Запуск сервисов от непривилегированного пользователя
Чтобы разрешить непривилегированному пользователю `user` управлять Чтобы разрешить непривилегированному пользователю `user` управлять
собственной конфигурацией для runit, нужно с правами суперпользователя собственной конфигурацией для runit, нужно с правами суперпользователя
выполнить: выполнить:
```sh [source,sh]
----
mkdir -p /etc/service/run-user/supervise mkdir -p /etc/service/run-user/supervise
cat > /etc/service/run-user/run << EOF cat > /etc/service/run-user/run << EOF
#!/bin/sh #!/bin/sh
@ -31,17 +31,18 @@ exec 2>&1
exec chpst -u user runsvdir /home/user/sv exec chpst -u user runsvdir /home/user/sv
EOF EOF
chmod +x /etc/service/run-user/run chmod +x /etc/service/run-user/run
``` ----
В результате в каталоге `/home/user/sv` пользователь `user` сможет В результате в каталоге `/home/user/sv` пользователь `user` сможет
создавать собственные правила управления сервисами. создавать собственные правила управления сервисами.
### Пример сервиса == Пример сервиса
Для запуска сервера Redis пользователем `user` нужно создать файл Для запуска сервера Redis пользователем `user` нужно создать файл
конфигурации `/home/user/redis/etc/redis.conf`: конфигурации `/home/user/redis/etc/redis.conf`:
``` [source,text]
----
daemonize no daemonize no
port 5079 port 5079
tcp-backlog 128 tcp-backlog 128
@ -56,33 +57,36 @@ client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 4mb 1mb 60 client-output-buffer-limit slave 4mb 1mb 60
client-output-buffer-limit pubsub 4mb 1mb 60 client-output-buffer-limit pubsub 4mb 1mb 60
maxclients 50 maxclients 50
``` ----
Запускаемый сервер должен запускаться не в фоновом режиме, чтобы Запускаемый сервер должен запускаться не в фоновом режиме, чтобы `runit`
runit мог контролировать его состояние. мог контролировать его состояние.
Скрипт `/home/user/sv/redis/run`, который `runit` использует для Скрипт `/home/user/sv/redis/run`, который `runit` использует для запуска
запуска процесса: процесса:
```sh [source,sh]
#!/bin/sh ----
#!/bin/sh -e
WORKDIR=/home/user/redis WORKDIR=/home/user/redis
cd "${WORKDIR}" || exit 1 cd "${WORKDIR}" || exit 1
exec 2>&1 exec 2>&1
exec redis-server etc/redis.conf exec redis-server etc/redis.conf
``` ----
Журналирование выполняется с помощью входящей в состав пакета Журналирование выполняется с помощью входящей в состав пакета runit
runit программы `svlogd`. Скрипт для его запуска должен находиться программы `svlogd`. Скрипт для его запуска должен находиться в
в подкаталоге `log` (`/home/user/sv/redis/log/run`): подкаталоге `log` (`/home/user/sv/redis/log/run`):
```sh [source,sh]
----
#!/bin/sh -e #!/bin/sh -e
LOGDIR=/home/user/redis/log LOGDIR=/home/user/redis/log
mkdir -p "${LOGDIR}" mkdir -p "${LOGDIR}"
exec svlogd -tt "${LOGDIR}"" exec svlogd -tt "${LOGDIR}""
``` ----

View File

@ -1,16 +1,14 @@
--- = Сервер времени NTP в локальной сети
title: "Сервер времени NTP в локальной сети" :category: Linux
category: Linux :tags: Linux, NTP, время,
tags: Linux, NTP, время,
summary:
...
Если в локальной сети необходимо синхронизировать время, не имея Если в локальной сети необходимо синхронизировать время, не имея
авторитетного источника времени, то можно использовать локальные авторитетного источника времени, то можно использовать локальные часы
часы сервера в качестве базовых. В этом случае файл настройки сервера в качестве базовых. В этом случае файл настройки `/etc/ntp.conf`
`/etc/ntp.conf` на сервере `192.168.0.1` будет выглядеть так: на сервере `192.168.0.1` будет выглядеть так:
``` [source,text]
----
driftfile /var/lib/ntp/ntp.drift driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log logfile /var/log/ntp.log
tinker panic 0 tinker panic 0
@ -19,11 +17,12 @@ server 127.127.1.0 minpoll 4 maxpoll 7
fudge 127.127.1.0 stratum 8 fudge 127.127.1.0 stratum 8
restrict 192.168.0.0 mask 255.255.255.0 restrict 192.168.0.0 mask 255.255.255.0
restrict default nomodify notrap restrict default nomodify notrap
``` ----
Файл `/etc/ntp.conf` на клиенте из подсети `192.168.0.0/24` имеет вид: Файл `/etc/ntp.conf` на клиенте из подсети `192.168.0.0/24` имеет вид:
``` [source,text]
----
driftfile /var/lib/ntp/ntp.drift driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log logfile /var/log/ntp.log
tinker panic 0 tinker panic 0
@ -32,5 +31,4 @@ server 127.127.1.0 minpoll 4 maxpoll 7
fudge 127.127.1.0 stratum 12 fudge 127.127.1.0 stratum 12
server 192.168.0.1 minpoll 4 maxpoll 7 iburst server 192.168.0.1 minpoll 4 maxpoll 7 iburst
restrict default nomodify nopeer restrict default nomodify nopeer
``` ----

View File

@ -1,20 +1,19 @@
--- = Терминал rxvt-unicode
title: "Терминал rxvt-unicode" :category: Linux
category: Linux :tags: Linux, Xorg, rxvt, терминал,
tags: Linux, Xorg, rxvt, терминал,
summary:
...
Скачать скрипт для динамического изменения размера шрифта Скачать скрипт для динамического изменения размера шрифта
```sh [source,sh]
----
curl -fLo $HOME/.urxvt/ext/font-size --create-dirs \ curl -fLo $HOME/.urxvt/ext/font-size --create-dirs \
https://raw.githubusercontent.com/majutsushi/urxvt-font-size/master/font-size https://raw.githubusercontent.com/majutsushi/urxvt-font-size/master/font-size
``` ----
Добавить в файл `$HOME/.Xresources`: Добавить в файл `$HOME/.Xresources`:
``` [source,text]
----
URxvt.background: White URxvt.background: White
URxvt.foreground: Black URxvt.foreground: Black
URxvt.saveLines: 8192 URxvt.saveLines: 8192
@ -40,5 +39,5 @@ URxvt.keysym.C-S-KP_Subtract: perl:font-size:decglobal
! Запрет печати ! Запрет печати
URxvt.print-pipe: "cat > /dev/null" URxvt.print-pipe: "cat > /dev/null"
``` ----

View File

@ -0,0 +1,9 @@
= Linux: полезные ссылки
:title-separator: {sp}|
:category: Linux
:tags: Linux, ссылки,
* https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html[Параметры
загрузки ядра]
* http://cheat.sh/[Примеры команд]
* https://m.opennet.ru/[Новости]

View File

@ -1,10 +0,0 @@
---
title: "Linux: полезные ссылки"
category: Linux
tags: Linux, ссылки,
...
* [Параметры загрузки ядра](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html)
* [Примеры команд](http://cheat.sh/)
* [Новости](https://m.opennet.ru/)

31
wiki/Misc/Libgen.adoc Normal file
View File

@ -0,0 +1,31 @@
= Libgen: локальная база данных для Windows
:title-separator: {sp}|
:category: Windows
:tags: windows, libgen, библиотеки, книги,
Программа http://libruslib.ucoz.com/index/libgen_bibliotekar/0-5[LibGen
- Библиотекарь] позволяет просматривать локальную копию базы данных
сервера http://libgen.io/[Libgen]. Архив базы данных можно скачать
http://gen.lib.rus.ec/dbdumps/[здесь]. В архиве базы с именем вида
`libgen_YYYY-MM-DD.rar` содержится полная информация для полнотекстового
поиска по описаниям книг, а в архиве с именем вида
`libgen-compact_YYYY-MM-DD.rar` описания удалены.
Для обработки полного архива потребуется около 30 ГБ свободного
пространства. Последовательность действий:
* https://yadi.sk/d/j_ToPE7D3SHGN6[Скачать] и распаковать программу
Libgen.
* Скачать архив базы данных, распаковать его в каталог `upload` и
переименовать SQL-скрипт в `backup_ba.sql`.
* https://yadi.sk/d/psnuXFJM3SHGR8[Скачать] архив со скриптами для
преобразования базы данных и распаковать его в каталог `upload`.
* Запустить программу `libgen.exe`.
* Выбрать в меню menu:Databases[Update book database].
* Перечень настроек должен быть таким:
** [ ] Download from the Internet
** [ ] Unpack
** [x] Prepare for import to the database
* Нажать кнопку btn:[Start].
* После завершения работы нажать кнопку btn:[Done].
* Удалить из каталога `upload` файл `backup_ba1.sql`.

View File

@ -1,30 +0,0 @@
---
title: "Libgen: локальная база данных для Windows"
category: Windows
tags: windows, libgen, библиотеки, книги,
summary:
...
Программа [LibGen - Библиотекарь](http://libruslib.ucoz.com/index/libgen_bibliotekar/0-5)
позволяет просматривать локальную копию базы данных сервера [Libgen](http://libgen.io/).
Архив базы данных можно скачать [здесь](http://gen.lib.rus.ec/dbdumps/).
В архиве базы с именем вида `libgen_YYYY-MM-DD.rar` содержится полная информация
для полнотекстового поиска по описаниям книг, а в архиве с именем вида
`libgen-compact_YYYY-MM-DD.rar` описания удалены.
Для обработки полного архива потребуется около 25 Гб свободного пространства.
Последовательность действий:
1. [Скачать](https://yadi.sk/d/j_ToPE7D3SHGN6) и распаковать программу Libgen.
2. Скачать архив базы данных, распаковать его в каталог `upload`
и переименовать SQL-скрипт в `backup_ba.sql`.
3. [Скачать](https://yadi.sk/d/psnuXFJM3SHGR8) архив со скриптами для преобразования
базы данных и распаковать его в каталог `upload`.
4. Запустить программу `libgen.exe`.
5. Выбрать в меню **Databases | Update book database**.
6. Убрать галочки **Download from the Internet** и **Unpack** и поставить
**Prepare for import to the database**.
7. Нажать кнопку **Start**.
8. После завершения работы нажать кнопку **Done**.
9. Удалить из каталога `upload` файл `backup_ba1.sql`.

View File

@ -0,0 +1,22 @@
= Настройка Windows в O&O ShutUp10
:category: Misc
:tags: Windows, настройка, программы,
Программа https://www.oo-software.com/en/shutup10[O&O ShutUp10]
используется для быстрой настроки большого количества параметров
Windows{nbsp}10. Пример приведён ниже:
.Экран 1
image::oo-shutup/1.jpg[1]
.Экран 2
image::oo-shutup/2.jpg[2]
.Экран 3
image::oo-shutup/3.jpg[3]
.Экран 4
image::oo-shutup/4.jpg[4]
.Экран 5
image::oo-shutup/5.jpg[5]

View File

@ -1,22 +0,0 @@
---
title: "Настройка Windows в O&O ShutUp10"
category: Misc
tags: Windows, настройка, программы,
summary:
...
Программа [O&O ShutUp10](https://www.oo-software.com/en/shutup10)
используется для быстрой настроки большого количества параметров Windows 10.
Пример приведён ниже:
![1](images/oo-shutup/1.jpg)
![2](images/oo-shutup/2.jpg)
![3](images/oo-shutup/3.jpg)
![4](images/oo-shutup/4.jpg)
![5](images/oo-shutup/5.jpg)

View File

@ -1,38 +1,20 @@
--- = CMake: управление проектом
title: "CMake: управление проектом" :title-separator: {sp}|
category: Программирование :category: Программирование
tags: программирование, cmake, :tags: программирование, cmake,
summary: :toc:
toc: yes
monofontoptions:
- Scale=0.6
...
<style type="text/css" rel="stylesheet"> == Полезные ссылки
table {
table-layout: fixed;
}
thead th:nth-child(1) {
width: 30%;
}
thead th:nth-child(2) {
width: 70%;
}</style>
[TOC] * https://github.com/onqtam/awesome-cmake[Каталог ссылок]
* https://cgold.readthedocs.io/en/latest/index.html[CGold: The
Hitchhikers Guide to the CMake]
== Структура каталогов проекта
### Полезные ссылки
* [Каталог ссылок](https://github.com/onqtam/awesome-cmake)
* [CGold: The Hitchhikers Guide to the CMake](https://cgold.readthedocs.io/en/latest/index.html)
### Структура каталогов проекта
Файлы проекта и результаты компиляции размещаются в каталогах: Файлы проекта и результаты компиляции размещаются в каталогах:
``` ....
└── cmex └── cmex
├── _build ├── _build
│ ├── Debug │ ├── Debug
@ -54,68 +36,85 @@ thead th:nth-child(2) {
│ └── lib │ └── lib
├── thirdparty ├── thirdparty
└── tools └── tools
``` ....
Назначение каталогов приведено в таблице. Назначение каталогов приведено в таблице.
Каталог | Назначение [cols="1,3",options="header",]
-------------------------|---------------------------------------------- |===
`cmex/_build` | Результаты компиляции |Каталог |Назначение
`cmex/_build/Debug` | Результаты компиляции в режиме отладки |`cmex/_build` |Результаты компиляции
`cmex/_build/Release` | Результаты компиляции в режиме выпуска |`cmex/_build/Debug` |Результаты компиляции в режиме отладки
`cmex/.git` | Репозиторий git |`cmex/_build/Release` |Результаты компиляции в режиме выпуска
`cmex/cmake` | Файлы с дополнительными функциями для CMake |`cmex/.git` |Репозиторий git
`cmex/cmake/cmlib` | Библиотека функций для CMake |`cmex/cmake` |Файлы с дополнительными функциями для CMake
`cmex/cmake/find` | Модули CMake для поиска внешних программ и библиотек |`cmex/cmake/cmlib` |Библиотека функций для CMake
`cmex/cmake/etc` | Файлы настроек, используемые в CMake |`cmex/cmake/find` |Модули CMake для поиска внешних программ и библиотек
`cmex/cmake/generators` | Генераторы проектов |`cmex/cmake/etc` |Файлы настроек, используемые в CMake
`cmex/doc` | Документация для проекта |`cmex/cmake/generators` |Генераторы проектов
`cmake/files` | Каталог для дополнительных файлов |`cmex/doc` |Документация для проекта
`cmake/files/etc` | Каталог для файлов настроек проекта |`cmake/files` |Каталог для дополнительных файлов
`cmake/files/share` | Каталог для неизменяемых файлов |`cmake/files/etc` |Каталог для файлов настроек проекта
`cmake/files/var` | Каталог для изменяемых файлов |`cmake/files/share` |Каталог для неизменяемых файлов
`cmex/l10n` | Файлы переводов |`cmake/files/var` |Каталог для изменяемых файлов
`cmex/src` | Исходные тексты |`cmex/l10n` |Файлы переводов
`cmex/src/app` | Исходные тексты программ |`cmex/src` |Исходные тексты
`cmex/src/lib` | Исходные тексты библиотек |`cmex/src/app` |Исходные тексты программ
`cmex/thirdparty` | Исходные тексты сторонних проектов |`cmex/src/lib` |Исходные тексты библиотек
`cmex/tools` | Дополнительные утилиты |`cmex/thirdparty` |Исходные тексты сторонних проектов
|`cmex/tools` |Дополнительные утилиты
|===
Каталог `_build` создаётся, чтобы избежать попадания получаемых во время Каталог `_build` создаётся, чтобы избежать попадания получаемых во время
сборки файлов в иерархию основного проекта. сборки файлов в иерархию основного проекта. Запись результатов сборки
Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами проекта внутрь иерархии каталогов с исходными текстами приводит к
приводит к засорению формируемыми на этапе сборки файлами, которые затрудняют засорению формируемыми на этапе сборки файлами, которые затрудняют
разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте. разработку, поиск в оригинальных файлах и мешают ориентироваться в
При работе с несколькими типами сборки, например, отладка и выпуск, появляется проекте. При работе с несколькими типами сборки, например, отладка и
необходимость корректного полного удаления результатов предыдущего тип сборки. выпуск, появляется необходимость корректного полного удаления
результатов предыдущего тип сборки.
== Начало проекта
### Начало проекта Проект, в котором выполнены приведённые ниже действия, можно посмотреть
https://git.246060.ru/f1x1t/cmex[здесь] или сделать его копию командой:
[source,sh]
----
git clone --recursive https://git.246060.ru/f1x1t/cmex
----
В каталоге `cmex` нужно создать файл `CMakeLists.txt`: В каталоге `cmex` нужно создать файл `CMakeLists.txt`:
```cmake [source,cmake]
----
# Минимальная версия Cmake # Минимальная версия Cmake
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.3)
cmake_policy(VERSION 3.0.2..3.7) cmake_policy(VERSION 3.0.2..3.7)
# Название и версия проекта и используемые языки программирования # Название и версия проекта и используемые языки программирования
project(cmex VERSION 0.2.0 LANGUAGES C CXX) project(cmex VERSION 0.2.0 LANGUAGES C CXX)
``` ----
Значение версии следует формировать согласно правилам Значение версии следует формировать согласно правилам
[семантического версионирования](https://semver.org/lang/ru/). https://semver.org/lang/ru/[семантического версионирования].
В каталог `cmake/cmlib` установить субмодуль CMLib, содержащий функции для CMake: В каталоге `cmex` нужно инициализировать репозиторий и установить
подмодули, содержащие функции для CMake:
``` [source,sh]
git submodule add ssh://git@gitlab-server/root/cmlib cmake/cmlib ----
``` git init .
git submodule add https://git.246060.ru/f1x1t/cmlib cmake/cmlib
git submodule add https://git.246060.ru/f1x1t/cmake-find cmake/find
git submodule add https://git.246060.ru/f1x1t/cmake-generators cmake/generators
git submodule update --remote --init
----
и подключить в файле `CMakeLists.txt`: и подключить в файле `CMakeLists.txt`:
```cmake [source,cmake]
----
# В каталоге cmake/cmlib находятся файлы с библиотечными функциями # В каталоге cmake/cmlib находятся файлы с библиотечными функциями
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib) if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/cmlib) list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/cmlib)
@ -125,19 +124,19 @@ endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
include(CMLibCommon) include(CMLibCommon)
``` ----
В файле `cmake/etc/organization.txt` записать название В файле `cmake/etc/organization.txt` записать название организации,
организации, которой принадлежит проект: которой принадлежит проект:
``` ....
ORG, Inc. ORG, Inc.
``` ....
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны для исключения
для исключения из архива, создаваемого целью `dist`. Например: из архива, создаваемого целью `dist`. Например:
``` ....
cmake/lib/.git$ cmake/lib/.git$
.git$ .git$
files/var files/var
@ -146,82 +145,86 @@ CMakeLists.txt.user
\\\\..*\\\\.bak$ \\\\..*\\\\.bak$
\\\\..*\\\\.tmp$ \\\\..*\\\\.tmp$
\\\\..*\\\\.swp$ \\\\..*\\\\.swp$
``` ....
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать
каталог `_build` в каталоге `cmex`, перейти в него и выполнить команды:
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать каталог [source,sh]
`_build` в каталоге `cmex`, перейти в него и выполнить команды: ----
```sh
cmake .. cmake ..
make make
``` ----
== Поиск системных библиотек
### Поиск системных библиотек
Системные библиотеки можно искать с помощью программы `pkgconfig`, Системные библиотеки можно искать с помощью программы `pkgconfig`,
которая хранит базу данных параметров, включающую пути к заголовочным которая хранит базу данных параметров, включающую пути к заголовочным
файлами и перечни библиотек, необходимых для компоновки. файлами и перечни библиотек, необходимых для компоновки. Сначала
Сначала производится наличие модуля `PkgConfig`, в котором определена производится наличие модуля `PkgConfig`, в котором определена функция
функция `pkg_check_modules`, которая и осуществляет поиск. Например, `pkg_check_modules`, которая и осуществляет поиск. Например, для поиска
для поиска библиотек `gsl`, `fftw3` и `udev` можно написать: библиотек `gsl`, `fftw3` и `udev` можно написать:
```cmake [source,cmake]
----
# Поиск библиотек с помощью pkgconfig # Поиск библиотек с помощью pkgconfig
find_package(PkgConfig) find_package(PkgConfig)
pkg_check_modules(GSL REQUIRED gsl) pkg_check_modules(GSL REQUIRED gsl)
pkg_check_modules(FFTW3 REQUIRED fftw3) pkg_check_modules(FFTW3 REQUIRED fftw3)
pkg_check_modules(UDEV udev) pkg_check_modules(UDEV udev)
``` ----
Если системная библиотека поставляется без файла описания для `pkgconfig`, Если системная библиотека поставляется без файла описания для
то для её поиска может быть написан специальный модуль для `CMake`, `pkgconfig`, то для её поиска может быть написан специальный модуль для
который вызывается функцией `find_package`. Кроме того функция `find_package` `CMake`, который вызывается функцией `find_package`. Кроме того функция
может возвращать дополнительные значения, например, пути к исполняемым файлам. `find_package` может возвращать дополнительные значения, например, пути
к исполняемым файлам.
```cmake [source,cmake]
----
# Поиск с помощью функции find_package # Поиск с помощью функции find_package
find_package(LibXml2) find_package(LibXml2)
find_package(CURL) find_package(CURL)
``` ----
Если для библиотеки нет модуля, выполняющего её поиск, то можно Если для библиотеки нет модуля, выполняющего её поиск, то можно
произвести поиск с помощью функции `find_library`. Например, произвести поиск с помощью функции `find_library`. Например,
```cmake [source,cmake]
----
# Поиск библиотеки с помощью функции find_library # Поиск библиотеки с помощью функции find_library
find_library(MATHGL mgl PATHS /usr/lib /usr/lib/x86_64-linux-gnu) find_library(MATHGL mgl PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu) find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
``` ----
== Автоматически генерируемый заголовочный файл
### Автоматически генерируемый заголовочный файл
На этапе конфигурирования проекта можно создать файл, в который будут На этапе конфигурирования проекта можно создать файл, в который будут
записаны параметры, полученные на данной стадии. В библиотеке CMLib записаны параметры, полученные на данной стадии. В библиотеке CMLib
присутствует функция `cmlib_config_hpp_generate()`, создающая файл присутствует функция `cmlib_config_hpp_generate()`, создающая файл
`${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается `${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается
информация о имени и версии проекта, дате и типе сборки. информация о имени и версии проекта, дате и типе сборки.
```cmake [source,cmake]
----
# Автоматически генерируемый заголовочный файл # Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate() cmlib_config_hpp_generate()
``` ----
== Базовая библиотека
### Базовая библиотека В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
`CMakeLists.txt` в подкаталоге `src/lib`:
В файле `cmex/CMakeLists.txt` должна быть строка, включающая [source,cmake]
поиск файла `CMakeLists.txt` в подкаталоге `src/lib`: ----
```cmake
add_subdirectory(src/libcmex) add_subdirectory(src/libcmex)
``` ----
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`: В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
```cpp [source,cpp]
----
#ifndef LIBCMEX_CMEX_HPP_ #ifndef LIBCMEX_CMEX_HPP_
#define LIBCMEX_CMEX_HPP_ #define LIBCMEX_CMEX_HPP_
@ -230,21 +233,23 @@ add_subdirectory(src/libcmex)
int32_t cmex_init(int32_t i); int32_t cmex_init(int32_t i);
#endif // LIBCMEX_CMEX_HPP_ #endif // LIBCMEX_CMEX_HPP_
``` ----
файл `cmex.cpp`: файл `cmex.cpp`:
```cpp [source,cpp]
----
#include "cmex.hpp" #include "cmex.hpp"
int32_t cmex_init(int32_t i = 0) { int32_t cmex_init(int32_t i = 0) {
return i; return i;
} }
``` ----
и файл `CMakeLists.txt`: и файл `CMakeLists.txt`:
```cmake [source,cmake]
----
# Название основной цели и имя библиотеки в текущем каталоге # Название основной цели и имя библиотеки в текущем каталоге
set(current_target cmex) set(current_target cmex)
@ -274,21 +279,22 @@ if(BUILD_SHARED_LIBS)
endif() endif()
install(FILES ${CMAKE_BINARY_DIR}/include/config.hpp ${current_target_headers} install(FILES ${CMAKE_BINARY_DIR}/include/config.hpp ${current_target_headers}
COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target}) COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target})
``` ----
== Базовое приложение
### Базовое приложение В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
`CMakeLists.txt` в подкаталоге `src/cmex`:
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла `CMakeLists.txt` [source,cmake]
в подкаталоге `src/cmex`: ----
```cmake
add_subdirectory(src/cmex) add_subdirectory(src/cmex)
``` ----
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`: В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`:
```cpp [source,cpp]
----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "config.hpp"
@ -297,18 +303,18 @@ add_subdirectory(src/cmex)
#include "cmex.hpp" #include "cmex.hpp"
int main(int argc, char **argv) { int main(int argc, char **argv) {
std::cout << CMEX_COMPILER_VERSION_MAJOR << std::endl; // Значение из compiler_features.hpp std::cout << CMEX_COMPILER_VERSION_MAJOR << std::endl; // Значение из compiler_features.hpp
std::cout << BUILD_TYPE << std::endl; // Значение из config.hpp std::cout << BUILD_TYPE << std::endl; // Значение из config.hpp
std::cout << CMEX_VERSION_STR << std::endl; // Значение из config.hpp std::cout << CMEX_VERSION_STR << std::endl; // Значение из config.hpp
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки
return 0; return 0;
} }
----
```
и файл `CMakeLists.txt`: и файл `CMakeLists.txt`:
```cmake [source,cmake]
----
# Название основной цели в текущем каталоге # Название основной цели в текущем каталоге
set(current_target cmex_app) set(current_target cmex_app)
@ -343,15 +349,15 @@ target_link_libraries(${current_target} cmex_static)
# Правила для установки # Правила для установки
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
``` ----
== Подключение внешнего проекта
### Подключение внешнего проекта
В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом, В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом,
состоящим из файлов `cmext.hpp`: состоящим из файлов `cmext.hpp`:
```c [source,c]
----
#ifndef CMEXT_CMEXT_HPP_ #ifndef CMEXT_CMEXT_HPP_
#define CMEXT_CMEXT_HPP_ #define CMEXT_CMEXT_HPP_
@ -360,21 +366,23 @@ install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
int32_t cmext_init(int32_t i); int32_t cmext_init(int32_t i);
#endif #endif
``` ----
`cmext.cpp`: `cmext.cpp`:
```c [source,c]
----
#include "cmext.hpp" #include "cmext.hpp"
int32_t cmext_init(int32_t i = 0) { int32_t cmext_init(int32_t i = 0) {
return i; return i;
} }
``` ----
и `CMakeLists.txt`: и `CMakeLists.txt`:
```cmake [source,cmake]
----
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.3)
project(cmext) project(cmext)
@ -382,54 +390,60 @@ include(GNUInstallDirs)
add_library(cmext cmext.cpp) add_library(cmext cmext.cpp)
install(TARGETS cmext ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS cmext ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES cmext.hpp COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}) install(FILES cmext.hpp COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME})
``` ----
В файле `cmex/CMakeLists.txt` нужно подключить стандартный модуль В файле `cmex/CMakeLists.txt` нужно подключить стандартный модуль
`ExternalProject` и описать правила для его загрузки, настройки, `ExternalProject` и описать правила для его загрузки, настройки,
компиляции и установки для сопряжения с текущим проектом: компиляции и установки для сопряжения с текущим проектом:
```cmake [source,cmake]
----
# Подключение внешних проектов # Подключение внешних проектов
include(ExternalProject) include(ExternalProject)
ExternalProject_Add(cmext ExternalProject_Add(cmext
EXCLUDE_FROM_ALL TRUE EXCLUDE_FROM_ALL TRUE
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/libcmext SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/cmext
INSTALL_DIR ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_BINARY_DIR}
DOWNLOAD_COMMAND "" DOWNLOAD_COMMAND ""
BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libcmext.a BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libcmext.a
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=Release CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=Release
) )
``` ----
Вызовы этих функций нужно сделать до функций `add_subdirectories`, Вызовы этих функций нужно сделать до функций `add_subdirectories`, чтобы
чтобы в подключенных подкаталогах можно было использовать цель `cmext` в подключенных подкаталогах можно было использовать цель `cmext` для
для определения зависимостей. определения зависимостей.
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект `cmext`: В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект
`cmext`:
```cmake [source,cmake]
----
# Зависимость от библиотеки из внешнего проекта проекта # Зависимость от библиотеки из внешнего проекта проекта
add_dependencies(${current_target} cmext) add_dependencies(${current_target} cmext)
``` ----
```cmake [source,cmake]
----
# Добавление каталога, в который устанавливаются заголовочные файлы от внешнего # Добавление каталога, в который устанавливаются заголовочные файлы от внешнего
# проекта cmext, к списку путей для поиска заголовочных файлов # проекта cmext, к списку путей для поиска заголовочных файлов
target_include_directories(${current_target} PUBLIC target_include_directories(${current_target} PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>) $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>)
``` ----
```cmake [source,cmake]
----
# Библиотека из внешнего проекта cmext # Библиотека из внешнего проекта cmext
target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a) target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
``` ----
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно вызвать Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно
функцию `cmext_init` из библиотеки, предоставляемой внешним проектом. вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним
Например: проектом. Например:
```cpp [source,cpp]
----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "config.hpp"
@ -456,43 +470,44 @@ int main(int argc, char **argv) {
// Функция из внешней библиотеки // Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl; qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
return 0; return 0;
} }
``` ----
== Qt5
### Qt5 Для поиска необходимых компонентов Qt5 нужно в файл
`cmex/CMakeLists.txt` добавить строки:
Для поиска необходимых компонентов Qt5 нужно в файл `cmex/CMakeLists.txt` [source,cmake]
добавить строки: ----
```cmake
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED) find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)
``` ----
Библиотека CMLib автоматически подключает вызов препроцессора `moc` Библиотека CMLib автоматически подключает вызов препроцессора `moc` и
и компилятора ресурсов `rcc`, если цель использует модуль `Core`, и компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
вызывает компилятор файлов описания интерфейса, если цель использует вызывает компилятор файлов описания интерфейса, если цель использует
модуль `Widgets`. модуль `Widgets`.
== Консольное приложение
### Консольное приложение
В файл `cmex/src/cmex/CMakeLists.txt` добавить строки: В файл `cmex/src/cmex/CMakeLists.txt` добавить строки:
```cmake [source,cmake]
----
# Qt5 # Qt5
qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU) qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU)
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
target_link_libraries(${current_target} Qt5::Core) target_link_libraries(${current_target} Qt5::Core)
``` ----
Для проверки работоспособности подключения Qt5 файл `cmex/src/cmex/main.cpp` Для проверки работоспособности подключения Qt5 файл
нужно заменить на: `cmex/src/cmex/main.cpp` нужно заменить на:
```cpp [source,cpp]
----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "config.hpp"
@ -509,13 +524,13 @@ QTextStream& qStdOut()
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QTranslator translator; QTranslator translator;
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm"))) if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{ {
app.installTranslator(&translator); app.installTranslator(&translator);
} }
// Значение из compiler_features.hpp // Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl; qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp // Значение из config.hpp
@ -527,30 +542,32 @@ int main(int argc, char **argv) {
// Функция из внешней библиотеки // Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl; qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
return 0; return 0;
} }
``` ----
После сборки проекта в каталоге `cmex/l10n` появится файл `cmex_app_ru_RU.ts`, После сборки проекта в каталоге `cmex/l10n` появится файл
в котором нужно отредактировать переводы с помощью программы `linguist`. `cmex_app_ru_RU.ts`, в котором нужно отредактировать переводы с помощью
После сохранения переводов проект нужно пересобрать, файл переводов в программы `linguist`. После сохранения переводов проект нужно
скопилированном виде будет встроен в исполняемый файл `cmex`, а доступ пересобрать, файл переводов в скомпилированном виде будет встроен в
к нему будет осуществляться с помощью кода: исполняемый файл `cmex`, а доступ к нему будет осуществляться с помощью
кода:
```cpp [source,cpp]
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm"))) ----
{ if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
app.installTranslator(&translator); {
} app.installTranslator(&translator);
``` }
----
== Графическое приложение
### Графическое приложение Для создания минимального графического приложения нужно создать файл
описания интерфейса `cmex/src/cmex/my_main_window.ui`:
Для создания минимального графического приложения нужно создать [source,xml]
файл описания интерфейса `cmex/src/cmex/my_main_window.ui`: ----
```xml
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>MyMainWindow</class> <class>MyMainWindow</class>
@ -571,11 +588,12 @@ int main(int argc, char **argv) {
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>
``` ----
заголовочный файл `cmex/src/cmex/my_main_window.hpp`: заголовочный файл `cmex/src/cmex/my_main_window.hpp`:
```cpp [source,cpp]
----
#ifndef CMEX_MY_MAIN_WINDOW_HPP_ #ifndef CMEX_MY_MAIN_WINDOW_HPP_
#define CMEX_MY_MAIN_WINDOW_HPP_ #define CMEX_MY_MAIN_WINDOW_HPP_
@ -583,18 +601,20 @@ int main(int argc, char **argv) {
#include "ui_my_main_window.h" #include "ui_my_main_window.h"
class MyMainWindow : public QWidget, private Ui::MyMainWindow { class MyMainWindow : public QWidget, private Ui::MyMainWindow {
Q_OBJECT Q_OBJECT
public: public:
MyMainWindow(QWidget* parent = 0); MyMainWindow(QWidget* parent = 0);
virtual ~MyMainWindow(); virtual ~MyMainWindow();
}; };
#endif /* CMEX_MY_MAIN_WINDOW_HPP_ */ #endif /* CMEX_MY_MAIN_WINDOW_HPP_ */
``` ----
и файл с реализацией конструктора и деструктора `cmex/src/cmex/my_main_window.cpp`: и файл с реализацией конструктора и деструктора
`cmex/src/cmex/my_main_window.cpp`:
```cpp [source,cpp]
----
#include "my_main_window.hpp" #include "my_main_window.hpp"
MyMainWindow::MyMainWindow(QWidget* parent) { MyMainWindow::MyMainWindow(QWidget* parent) {
@ -604,12 +624,13 @@ MyMainWindow::MyMainWindow(QWidget* parent) {
MyMainWindow::~MyMainWindow() { MyMainWindow::~MyMainWindow() {
} }
``` ----
Для отображения графического окна нужно заменить файл Для отображения графического окна нужно заменить файл
`cmex/src/cmex/main.cpp` на: `cmex/src/cmex/main.cpp` на:
```cpp [source,cpp]
----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "config.hpp"
@ -628,13 +649,13 @@ QTextStream& qStdOut()
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
QApplication app(argc, argv); QApplication app(argc, argv);
QTranslator translator; QTranslator translator;
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm"))) if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{ {
app.installTranslator(&translator); app.installTranslator(&translator);
} }
// Значение из compiler_features.hpp // Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl; qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
@ -647,16 +668,17 @@ int main(int argc, char **argv) {
// Функция из внешней библиотеки // Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl; qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
MyMainWindow* mmw = new MyMainWindow(); MyMainWindow* mmw = new MyMainWindow();
mmw->show(); mmw->show();
return app.exec(); return app.exec();
} }
``` ----
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы к списку
к списку файлов, используемых для компиляции: файлов, используемых для компиляции:
```cmake [source,cmake]
----
set(current_target_sources set(current_target_sources
main.cpp main.cpp
my_main_window.cpp my_main_window.cpp
@ -665,51 +687,51 @@ set(current_target_sources
set(current_target_uis set(current_target_uis
my_main_window.ui my_main_window.ui
) )
``` ----
```cmake [source,cmake]
----
# Цель для создания исполняемого файла # Цель для создания исполняемого файла
add_executable(${current_target} ${current_target_sources} ${current_target_uis}) add_executable(${current_target} ${current_target_sources} ${current_target_uis})
``` ----
и добавить строки для подключения графических библиотек Qt5 и добавить строки для подключения графических библиотек Qt5 и
и соответствующих им заголовочных файлов: соответствующих им заголовочных файлов:
```cmake [source,cmake]
----
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Gui_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Gui_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Widgets_INCLUDE_DIRS}) target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Widgets_INCLUDE_DIRS})
target_link_libraries(${current_target} Qt5::Gui) target_link_libraries(${current_target} Qt5::Gui)
target_link_libraries(${current_target} Qt5::Widgets) target_link_libraries(${current_target} Qt5::Widgets)
``` ----
Во время сборки проекта в файл переводов `cmex/l10n/cmex_app_ru_RU.ts` Во время сборки проекта в файл переводов `cmex/l10n/cmex_app_ru_RU.ts`
будут добавлены повые строки, их нужно перевести с помощью `linguist` будут добавлены новые строки, их нужно перевести с помощью `linguist` и
и снова скомпилировать проект. снова скомпилировать проект.
== Удаление установленных файлов
### Удаление установленных файлов
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить
файлы, перечисленные в файле `${CMAKE_BUILD_DIR}/install_manifest.txt`. файлы, перечисленные в файле `${CMAKE_BUILD_DIR}/install_manifest.txt`.
== Архивирование проекта
### Архивирование проекта Стандартный модуль `CPack` осуществляет архивирование проекта. В файле
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов
для исключения из архива:
Стандарный модуль `CPack` осуществляет архивирование проекта. В файле ....
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов для
исключения из архива:
```
.git$ .git$
files/var files/var
CMakeLists.txt.user CMakeLists.txt.user
~$ ~$
\\\\..*\\\\.bak$
\\\\..*\\\\.tmp$ \\\\..*\\\\.tmp$
\\\\..*\\\\.bak$
\\\\..*\\\\.swp$ \\\\..*\\\\.swp$
``` \\\\..*\\\\.o$
....
По умолчанию цель для упаковки проекта называется `package_source`. По умолчанию цель для упаковки проекта называется `package_source`. В
В библиотеке CMLib определены значения основных параметров, а также библиотеке CMLib определены значения основных параметров, а также
дополнительная цель `dist`. дополнительная цель `dist`.

View File

@ -0,0 +1,39 @@
= Intel Parallel Studio: установка в образ для чтения
:title-separator: {sp}|
:category: Linux/Программы
:tags: Linux, Intel, компилятор, C++,
Для установки и использования Intel Parallel Studio в сжатом образе
доступном только для чтения необходимо:
[arabic]
. Скачать
https://software.intel.com/en-us/parallel-studio-xe[дистрибутив] и
распаковать его.
. Скачать файл link:files/parallel-studio/silent.cfg[`silent.cfg`] и
скопировать его в полученный каталог.
. Если есть файл лицензии `parallel_studio.lic`, скопировать его в
каталог `/opt/intel/licenses`.
. Добавить полномочия для сбора статистики:
[source,sh]
----
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_amplifier/bin64/amplxe-cl
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_amplifier/bin64/amplxe-perf
----
[arabic, start=5]
. От суперпользователя установить в каталог `/opt/intel` командой
`sudo ./install.sh -s silent.cfg`.
. Создать образ
`mksquashfs /opt/intel/* /home/user/intel.sfs -comp xz -Xbcj x86 -all-root -b 512K`
. Удалить содержимое каталога `/opt/intel`.
. Примонтировать образ:
`mount -t squashfs /home/user/intel.sfs /opt/intel`
. Добавить в файл `/home/user/.bashrc` строки:
[source,sh]
----
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/vtune_amplifier/amplxe-vars.sh
----

View File

@ -1,22 +0,0 @@
---
title: "Intel Parallel Studio: установка в образ для чтения"
category: Linux/Программы
tags: Linux, Intel, компилятор, C++
summary:
...
Для установки и использования Intel Parallel Studio
в сжатом образе доступном только для чтения необходимо:
1. Скачать [дистрибутив](https://software.intel.com/en-us/parallel-studio-xe) и распаковать его.
2. Скачать файл [`silent.cfg`](files/parallel-studio/silent.cfg) и скопировать его в полученный каталог.
3. Если есть файл лицензии `parallel_studio.lic`, скопировать его в каталог `/opt/intel/licenses`.
4. От суперпользователя установить в каталог `/opt/intel` командой `sudo ./install.sh -s silent.cfg`.
5. Создать образ `mksquashfs /opt/intel/* /home/user/intel.sfs -comp xz -Xbcj x86 -all-root -b 512K`
6. Удалить содержимое каталога `/opt/intel`.
7. Подмонтировать образ: `mount -t squashfs /home/user/intel.sfs /opt/intel`
8. Добавить в файл `/home/user/.bashrc` строки:
```sh
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/vtune_amplifier/amplxe-vars.sh
```

View File

@ -1,59 +1,62 @@
--- = PVS-Studio
title: "PVS-Studio" :category: Программирование
category: Программирование :tags: программирование, C, C++, отладка,
tags: программирование, C, C++, отладка,
summary:
toc: yes
...
[TOC] :toc:
### Информация и лицензия == Информация и лицензия
[PVS-Studio](https://www.viva64.com/ru/pvs-studio/) — это инструмент для https://www.viva64.com/ru/pvs-studio/[PVS-Studio] — это инструмент для
статического анализа исходного кода программ, написанных на языках С, C++. статического анализа исходного кода программ, написанных на языках С,
C++.
Для использования в Linux нужно чтобы в каталоге `~/.config/PVS-Studio` Для использования в Linux нужно чтобы в каталоге `~/.config/PVS-Studio`
находился лицензионный ключ или в начале исходных файлов с расширениями находился лицензионный ключ или в начале исходных файлов с расширениями
`*.c`, `*.cpp`, `*.cxx` и т.п. [присутствовали строки](https://www.viva64.com/ru/b/0457/) `*.c`, `*.cpp`, `*.cxx` и т.п.
https://www.viva64.com/ru/b/0457/[присутствовали строки]
``` ....
// This is an independent project of an individual developer. Dear PVS-Studio, please check it. // This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
``` ....
### Настройка и компиляция проекта == Настройка и компиляция проекта
Полное руководство для работы в Linux находится Полное руководство для работы в Linux находится
[здесь](https://www.viva64.com/ru/m/0036/), а ниже приведён список типовых команд. https://www.viva64.com/ru/m/0036/[здесь], а ниже приведён список типовых
команд.
Настройка проекта для CMake: Настройка проекта для CMake:
```sh [source,sh]
----
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root> cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root>
``` ----
Сборка проекта с помощью `make`: Сборка проекта с помощью `make`:
```sh [source,sh]
----
pvs-studio-analyzer trace -- make -j$(nproc) pvs-studio-analyzer trace -- make -j$(nproc)
``` ----
Настройка и сборка проекта с использованием Ninja: Настройка и сборка проекта с использованием Ninja:
```sh [source,sh]
----
cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root> cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root>
ninja -t compdb ninja -t compdb
``` ----
### Анализ проекта == Анализ проекта
Для анализа проектов используется утилита `pvs-studio-analyzer`. По умолчанию Для анализа проектов используется утилита `pvs-studio-analyzer`. По
включены только диагностики общего назначения (General Analysis, GA). умолчанию включены только диагностики общего назначения (General
Включить дополнительные правила можно с помощью опции `-a`: Analysis, GA). Включить дополнительные правила можно с помощью опции
`-a`:
``` ....
-a [MODE], --analysis-mode [MODE] -a [MODE], --analysis-mode [MODE]
MODE defines the type of warnings: MODE defines the type of warnings:
1 - 64-bit errors; 1 - 64-bit errors;
@ -64,45 +67,50 @@ ninja -t compdb
32 - MISRA. 32 - MISRA.
Modes can be combined by adding the values Modes can be combined by adding the values
Default: 4 Default: 4
``` ....
Выбор типов предупреждений осуществляется на основе побитовой маски из Выбор типов предупреждений осуществляется на основе побитовой маски из
приведенных выше типов. Чтобы выполнить анализ, исключив проверки MISRA, приведённых выше типов. Чтобы выполнить анализ, исключив проверки MISRA,
нужно выполнить нужно выполнить
```sh [source,sh]
----
pvs-studio-analyzer analyze -a 29 -j$(nproc) -o pvs.log pvs-studio-analyzer analyze -a 29 -j$(nproc) -o pvs.log
``` ----
Составление отчёта для просмотра в Qt Creator: Составление отчёта для просмотра в Qt Creator:
```sh [source,sh]
----
plog-converter -t tasklist -o pvs.tasks pvs.log plog-converter -t tasklist -o pvs.tasks pvs.log
``` ----
При составлении отчёта уровень детализации можно изменять с помощью ключа При составлении отчёта уровень детализации можно изменять с помощью
`-a` (`--analyzer`), который производит фильтрацию предупреждений согласно ключа `-a` (`--analyzer`), который производит фильтрацию предупреждений
маске, которая имеет вид `MessageType:MessageLevels`, где `MessageType` согласно маске, которая имеет вид `MessageType:MessageLevels`, где
может принимать один из следующих типов: `GA`, `OP`, `64`, `CS`, `MISRA`, `MessageType` может принимать один из следующих типов: `GA`, `OP`, `64`,
а `MessageLevels` может принимать значения от `1` до `3`. `CS`, `MISRA`, а `MessageLevels` может принимать значения от `1` до `3`.
Возможна комбинация разных масок через `;`. Например, при составлении Возможна комбинация разных масок через `;`. Например, при составлении
отчёта для просмотра в формате HTML можно повысить уровень детализации: отчёта для просмотра в формате HTML можно повысить уровень детализации:
```sh [source,sh]
----
plog-converter -t fullhtml -a "GA:1,2,3;64:1;OP:1,2;CS:1,2" -o html pvs.log plog-converter -t fullhtml -a "GA:1,2,3;64:1;OP:1,2;CS:1,2" -o html pvs.log
``` ----
Составление отчёта для редактора Vim: Составление отчёта для редактора Vim:
```sh [source,sh]
----
plog-converter -a "GA:1,2" -t errorfile -o pvs.err pvs.log plog-converter -a "GA:1,2" -t errorfile -o pvs.err pvs.log
``` ----
Для просмотра отчёта в редакторе Vim нужно открыть файл `pvs.err` и выполнить команды: Для просмотра отчёта в редакторе Vim нужно открыть файл `pvs.err` и
выполнить команды:
```vim [source,vim]
----
:set makeprg=cat\ % " выбор программы для компиляции в текущей сессии :set makeprg=cat\ % " выбор программы для компиляции в текущей сессии
:silent make " имитация сборки :silent make " имитация сборки
:cw " открытие результатов в нижнем окне :cw " открытие результатов в нижнем окне
``` ----

View File

@ -0,0 +1,36 @@
= Подбор ключей компиляции GCC
:category: Программирование
:tags: программирование, C, C++, отладка, оптимизация,
Подбор ключей компиляции основан на измерениях характеристик во время
выполнения программы. На первом этапе создаётся исполняемый файл
`program`, в который включается информация для профилировки. Ключ
`-fprofile-generate=data/pgo` указывает, что нужно собирать информацию и
сохранять в каталог `data/pgo`. Компиляцию следует выполнять в
последовательном режиме.
[source,sh]
----
env CXXFLAGS='-fprofile-generate=data/pgo' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
----
После компиляцию программу следует выполнить, придерживаясь типичного
сценария использования.
[source,sh]
----
./program
----
Скомпилировать программу с использованием полученной статистики. Для
многопоточной программы следует указать флаг `-fprofile-correction`,
чтобы скорректировать данные, которые могут неустойчивыми из-за
пропусков обновлений счётчиков. Компиляцию следует выполнять в
последовательном режиме.
[source,sh]
----
env CXXFLAGS='-fprofile-use=data/pgo -fprofile-correction' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
----

View File

@ -1,35 +0,0 @@
---
title: "Подбор ключей компиляции GCC"
category: Программирование
tags: программирование, C, C++, отладка, оптимизация,
summary:
...
Подбор ключей компиляции основан на измерениях характеристик во
время выполнения программы. На первом этапе создаётся исполняемый
файл `program`, в который включается информация для профилировки.
Ключ `-fprofile-generate=data/pgo` указывает, что нужно собирать
информацию и сохранять в каталог `data/pgo`. Компиляцию следует
выполнять в последовательном режиме.
```sh
env CXXFLAGS='-fprofile-generate=data/pgo' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
```
После компиляцию программу следует выполнить, придерживаясь
типичного сценария использования.
```sh
./program
```
Скомпилировать программу с использованием полученной статистики.
Для многопоточной программы следует указать флаг `-fprofile-correction`,
чтобы скорректировать данные, которые могут неустойчивыми из-за пропусков
обновлений счётчиков. Компиляцию следует выполнять в последовательном режиме.
```sh
env CXXFLAGS='-fprofile-use=data/pgo -fprofile-correction' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
```

View File

@ -0,0 +1,77 @@
= Профилирование кода
:category: Программирование
:tags: программирование, отладка, производительность, профилирование, gprof,
== Общее описание
Чтобы профилировать приложения, компилируемые http://gcc.gnu.org[GCC],
необходимо добавлять флаг `-fno-omit-frame-pointer` и, желательно, `-g`.
== quickstack
Утилита для отслеживания стеков вызовов функций
https://github.com/yoshinorim/quickstack[quicktrack]. Пример
использования:
[source,sh]
----
quickstack -f -p $(pidof application)
----
== perf
Утилита профилирования для ядра Linux (находится в дереве его исходных
текстов в каталоге `tools/perf`).
[source,sh]
----
perf record --call-graph dwarf -- ./application
perf report -g graph --no-children
----
Полезные ссылки:
* https://perf.wiki.kernel.org/index.php/Main_Page[Официальная страница]
* https://stackoverflow.com/questions/1777556/alternatives-to-gprof/10958510#10958510[Примеры]
* http://www.brendangregg.com/perf.html[Примеры]
== oprofile
[source,sh]
----
opcontrol --setup --vmlinux=/boot/vmlinux-`uname -r`
----
== Systemtap
https://eax.me/systemtap/[Установка и простые примеры использования
SystemTap]
== Valgrind
https://eax.me/valgrind/[Хорошая статья] об использовании Valgrind для
поиска утечек, а также о взаимодействии с GDB.
В версии 3.15 добавление инструмент профилирования кучи DHAT (Dynamic
Heap Analysis Tool), позволяющий отследить все запросы на распределения
памяти в куче и выявить утечки ресурсов, места излишне большой
активности при работе с кучей, неиспользованные выделения памяти,
краткосрочные выделения и неэффективное размещение данных в куче.
[source,sh]
----
valgrind --tool=dhat ./application
----
== gperftools
== Разное
* https://eax.me/c-cpp-profiling/[Профилирование кода на C/C++ в Linux и
FreeBSD]
* http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-profiling-linux/[Примеры]
== Графическое отображение
* http://www.brendangregg.com/flamegraphs.html[Flame Graphs]
* https://github.com/jrfonseca/gprof2dot[gprof2dot]

View File

@ -1,79 +0,0 @@
---
title: "Профилирование кода"
category: Программирование
tags: программирование, отладка, производительность, профилирование, gprof,
summary:
...
## Общее описание
Чтобы профилировать приложения, компилируемые [GCC](http://gcc.gnu.org),
необходимо добавлять флаг `-fno-omit-frame-pointer` и, желательно, `-g`.
## quickstack
Утилита для отслеживания стеков вызовов функций [quicktrack](https://github.com/yoshinorim/quickstack).
Пример использования:
```sh
quickstack -f -p $(pidof application)
```
## perf
Утилита профилирования для ядра Linux (находится в дереве его исходных текстов
в каталоге `tools/perf`).
```sh
perf record --call-graph dwarf -- ./application
perf report -g graph --no-children
```
Полезные ссылки:
* [Официальная страница](https://perf.wiki.kernel.org/index.php/Main_Page)
* [Примеры](https://stackoverflow.com/questions/1777556/alternatives-to-gprof/10958510#10958510)
* [Примеры](http://www.brendangregg.com/perf.html)
## oprofile
```sh
opcontrol --setup --vmlinux=/boot/vmlinux-`uname -r`
```
## Systemtap
[Установка и простые примеры использования SystemTap](https://eax.me/systemtap/)
## Valgrind
[Хорошая статья](https://eax.me/valgrind/) об использовании Valgrind для поиска
утечек, а также о взаимодействии с GDB.
В версии 3.15 добавление инструмент профилирования кучи DHAT (Dynamic
Heap Analysis Tool), позволяющий отследить все запросы на распределения
памяти в куче и выявить утечки ресурсов, места излишне большой активности
при работе с кучей, неиспользованные выделения памяти, краткосрочные
выделения и неэффективное размещение данных в куче.
```sh
valgrind --tool=dhat ./application
```
## gperftools
## Разное
* [Профилирование кода на C/C++ в Linux и FreeBSD](https://eax.me/c-cpp-profiling/)
* [Примеры](http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-profiling-linux/)
## Графическое отображение
* [Flame Graphs](http://www.brendangregg.com/flamegraphs.html)
* [gprof2dot](https://github.com/jrfonseca/gprof2dot)

View File

@ -1,33 +1,33 @@
--- = Статический анализ кода
title: "Статический анализ кода" :category: Программирование
category: Программирование :tags: программирование, отладка, cppcheck, iwyu, clang-tidy, cpplint, clazy,
tags: программирование, отладка, cppcheck, iwyu, clang-tidy, cpplint, clazy,
summary:
...
## Общее описание == Общее описание
Ниже приведены утилиты для проверки кода на C++ и примеры их настройки и использования Ниже приведены утилиты для проверки кода на C++ и примеры их настройки и
совместно с [CMake](https://cmake.org/). использования совместно с https://cmake.org/[CMake].
### [clang-tidy](http://clang.llvm.org/extra/clang-tidy/) === http://clang.llvm.org/extra/clang-tidy/[clang-tidy]
Установка: Установка:
```sh [source,sh]
----
sudo apt-get install clang-tidy-6.0 sudo apt-get install clang-tidy-6.0
``` ----
Использование: Использование:
```sh [source,sh]
----
cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source
``` ----
В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со списком В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со
выполняемых проверок. Например: списком выполняемых проверок. Например:
```yaml [source,yaml]
----
--- ---
Checks: '-*, Checks: '-*,
clang-diagnostic-*, clang-diagnostic-*,
@ -42,91 +42,97 @@ CheckOptions:
- key: readability-identifier-naming.ClassMemberCase - key: readability-identifier-naming.ClassMemberCase
value: camelBack value: camelBack
... ...
``` ----
Пример файла `.clang-tidy`, в котором перечислены все правила для проверки Пример файла `.clang-tidy`, в котором перечислены все правила для
именования идентификаторов приведён [здесь](https://git.246060.ru/f1x1t/clang-tidy-readability-identifier-naming). проверки именования идентификаторов приведён
https://git.246060.ru/f1x1t/clang-tidy-readability-identifier-naming[здесь].
=== CppCheck
### CppCheck
Установка: Установка:
```sh [source,sh]
----
sudo apt-get install cppcheck sudo apt-get install cppcheck
``` ----
Использование: Использование:
```sh [source,sh]
----
cmake "-DCMAKE_CXX_CPPCHECK=/usr/bin/cppcheck;--std=c++11" path/to/source cmake "-DCMAKE_CXX_CPPCHECK=/usr/bin/cppcheck;--std=c++11" path/to/source
``` ----
This will run /usr/bin/cppcheck;std=c++11″ source=/path/to/source/file.cxx on each c++ file in the project being built. This will run /usr/bin/cppcheck;std=c++11″
source=/path/to/source/file.cxx on each c++ file in the project being
built.
=== CppLint
### CppLint
Установка: Установка:
```sh [source,sh]
----
sudo apt-get install python3-cpplint sudo apt-get install python3-cpplint
``` ----
Использование: Использование:
```sh [source,sh]
----
cmake "-DCMAKE_CXX_CPPLINT=/usr/bin/cpplint;--linelength=79" path/to/source cmake "-DCMAKE_CXX_CPPLINT=/usr/bin/cpplint;--linelength=79" path/to/source
``` ----
```sh [source,sh]
----
make -j24 2>&1 1>/dev/null | ../cpplint2tasks.pl > 222.tasks make -j24 2>&1 1>/dev/null | ../cpplint2tasks.pl > 222.tasks
``` ----
This will run /usr/local/bin/cpplint linelength=79 on each c++ file in the project being built. This will run /usr/local/bin/cpplint linelength=79 on each c++ file in
the project being built.
=== IWYU
### IWYU
Установка: Установка:
```sh [source,sh]
----
sudo apt-get install iwyu sudo apt-get install iwyu
``` ----
Использование: Использование:
[source,sh]
```sh ----
cmake "-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=/usr/bin/iwyu;--transitive_includes_only" .. cmake "-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=/usr/bin/iwyu;--transitive_includes_only" ..
``` ----
This will run /usr/bin/iwyu transitive_includes_only on each c++ file
in the project being built.
This will run /usr/bin/iwyu transitive_includes_only on each c++ file in the project being built. === LWYU
[source,sh]
### LWYU ----
```sh
cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE .. cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..
``` ----
### Clazy
=== Clazy
Установка: Установка:
```sh [source,sh]
----
sudo apt-get install clazy clang-6.0 sudo apt-get install clazy clang-6.0
``` ----
Использование: Использование:
```sh [source,sh]
----
CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy .. CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy ..
CLANGXX=clang++-6.0 make CLANGXX=clang++-6.0 make
``` ----
### PVS-Studio
=== PVS-Studio

View File

@ -0,0 +1,49 @@
= Построение профиля местности в Gis
:category: Картография
:tags: картография, qgis, sxf, shp, gdal,
[arabic]
. В главном меню QGis *Слой* — *Добавить слой* — *Добавить векторный
слой* выбрать и открыть файл с векторным слоем, например, `map.sxf`.
. Среди слоёв выбрать слой с рельефом местности и типом геометрии
`LineString`.
image:qgis-heights/1.png[Слои карты]
[arabic, start=3]
. На панели *Панель слоёв* правой кнопкой мыши щёлкнуть на слое,
содержащем данные о высотах, и выбрать *Фильтр…*.
. Построить выражение выбирающие только данные с высотами, например,
`"CLNAME" ILIKE '%ГОРИЗОНТАЛИ ОСНОВ%'` и нажить *OK*.
. На панели *Панель слоёв* правой кнопкой мыши щёлкнуть на слое,
содержащем данные о высотах, и выбрать *Сохранить как…*. Появившийся
новый слой *heights* следует удалить.
. В появившемся диалоговом окне выбрать имя выходного файла, например,
`heights`.
image:qgis-heights/2.png[Имя выходного файла]
[arabic, start=7]
. В каталоге `/home/a/work/map` выполнить команду, которая в файле
`heights.shp` из слоя `heights` берёт данные о высотах из поля `SC_4` и
генерирует матрицу высот размером 2000 на 2000 в формате BMP. Настойки
алгоритма построения матрицы можно изменять с помощью параметра `-a`:
[source,sh]
----
gdal_grid -a invdist:power=3.0:smoothing=1.0 -outsize 2000 2000 -of BMP -ot Byte -zfield SC_4 -l heights heights.shp heights.bmp
----
[arabic, start=8]
. После построения матрицы её можно импортировать в QGis как растровый
слой, для этого в главном меню QGis *Слой* — *Добавить слой* — *Добавить
растровый слой* нужно выбрать и открыть файл `heights.bmp`. В результате
на панели *Панель слоёв* появится растровый слой *heights*.
. С помощью модуля Profile Tool можно построить профиль местности. В
главном меню нужно выбрать *Модуль* — *Profile Tool* — *Terrain
profile*.
. На панели *Панель слоёв* нужно перенести растровый слой *heights* в
конец списка, выделить его и на панели *Profile Tool* нажать *Add
Layer*. После этого на карте можно строить профили местности.
image:qgis-heights/3.png[Матрица высот]

View File

@ -1,51 +0,0 @@
---
title: "Построение профиля местности в QGis"
category: Картография
tags: картография, qgis, sxf, shp, gdal,
summary:
...
1) В главном меню QGis **Слой****Добавить слой** — **Добавить векторный слой**
выбрать и открыть файл с векторным слоем, например, `map.sxf`.
2) Среди слоёв выбрать слой с рельефом местности и типом геометрии `LineString`.
![Слои карты](images/qgis-heights/1.png)
3) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Фильтр...**.
4) Построить выражение выбирающие только данные с высотами, например,
`"CLNAME" ILIKE '%ГОРИЗОНТАЛИ ОСНОВ%'` и нажить **OK**.
5) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Сохранить как...**. Появившийся
новый слой **heights** следует удалить.
6) В появившемся диалоговом окне выбрать имя выходного файла, например, `heights`.
![Имя выходного файла](images/qgis-heights/2.png)
7) В каталоге `/home/a/work/map` выполнить команду, которая в файле
`heights.shp` из слоя `heights` берёт данные о высотах из поля `SC_4`
и генерирует матрицу высот размером 2000 на 2000 в формате BMP.
Настойки алгоритма посторения матрицы можно изменять с помощью параметра `-a`:
```sh
gdal_grid -a invdist:power=3.0:smoothing=1.0 -outsize 2000 2000 -of BMP -ot Byte -zfield SC_4 -l heights heights.shp heights.bmp
```
8) После построения матрицы её можно импортировать в QGis как растровый
слой, для этого в главном меню QGis **Слой****Добавить слой**
**Добавить растровый слой** нужно выбрать и открыть файл `heights.bmp`.
В результате на панели **Панель слоёв** появится растровый слой **heights**.
9) С помощью модуля Profile Tool можно построить профиль местности. В главном
меню нужно выбрать **Модуль****Profile Tool****Terrain profile**.
10) На панели **Панель слоёв** нужно перенести растровый слой **heights**
в конец списка, выделить его и на панели **Profile Tool** нажать **Add Layer**.
После этого на карте можно строить профили местности.
![Матрица высот](images/qgis-heights/3.png)

View File

@ -0,0 +1 @@
{"checksum":"81886ef1b8d31cdb2b865473bbeb2cf9","width":671,"height":550}

View File

@ -0,0 +1 @@
{"checksum":"e76d88ee3db613b3f806d8c773281fdc","width":685,"height":363}

View File

@ -0,0 +1,30 @@
= Git: автоматическое сохранение в репозиторий
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Скрипт https://github.com/elnull/gitwatch[gitwatch] позволяет
отслеживать изменения в каталоге с помощью программы `inotifywait` и
фиксировать их в репозиторий. Для работы скрипта необходимо установить
пакет `inotify-tools`. Если нужно следить за каталогом `/home/user/dir`
и записывать историю изменений в `/home/user/repo/dir`, то нужно
инициализировать репозиторий:
[source,sh]
----
git init --bare /home/user/repo/dir
----
добавить шаблоны исключаемых файлов:
[source,sh]
----
printf '*.[oa]\n*.swp\n*~\n/.git' >> /home/user/repo/dir/info/exclude
----
и запустить скрипт:
[source,sh]
----
./gitwatch.sh -g /home/user/repo/dir /home/user/dir
----

View File

@ -1,27 +0,0 @@
---
title: "Git: автоматическое сохранение в репозиторий"
category: Программирование
tags: программирование, git,
...
Скрипт [gitwatch](https://github.com/elnull/gitwatch) позволяет отслеживать
изменения в каталоге с помощью программы `inotifywait` и фиксировать их в
репозиторий. Для работы скрипта необходимо установить пакет `inotify-tools`.
Если нужно следить за каталогом `/home/user/dir` и записывать историю
изменений в `/home/user/repo/dir`, то нужно инициализировать репозиторий:
```sh
git init --bare /home/user/repo/dir
```
добавить шаблоны исключаемых файлов:
```sh
printf '*.[oa]\n*.swp\n*~\n/.git' >> /home/user/repo/dir/info/exclude
```
и запустить скрипт:
```sh
./gitwatch.sh -g /home/user/repo/dir /home/user/dir
```

View File

@ -1,20 +1,17 @@
--- = Git: замена адреса подмодуля
title: "Git: замена адреса подмодуля" :title-separator: {sp}|
category: Программирование :category: Программирование
tags: программирование, git, :tags: программирование, git,
monofontoptions:
- Scale=0.7
...
Если у подмодуля, находящегося в каталоге `thirdparty/example` нужно Если у подмодуля, находящегося в каталоге `thirdparty/example` нужно
заменить адрес синхронизации и имя используемой ветки, то в каталоге заменить адрес синхронизации и имя используемой ветки, то в каталоге с
с файлом `.gitmodules`, в котором содержится информация об этом подмодуле, файлом `.gitmodules`, в котором содержится информация об этом подмодуле,
нужно выполнить команды: нужно выполнить команды:
```sh [source,sh]
----
git config --file=.gitmodules submodule.thirdparty/example.url https://github.com/username/ABC.git git config --file=.gitmodules submodule.thirdparty/example.url https://github.com/username/ABC.git
git config --file=.gitmodules submodule.thirdparty/example.branch new-branch-name git config --file=.gitmodules submodule.thirdparty/example.branch new-branch-name
git submodule sync --recursive git submodule sync --recursive
git submodule update --init --recursive --remote git submodule update --init --recursive --remote
``` ----

View File

@ -0,0 +1,301 @@
= Git: основные команды
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git
:toc:
== Ссылки
* https://githowto.com/ru/changes_not_files[GitHowTo]
* https://git-scm.com/book/ru/v2[ProGit]
* https://github.com/maxliscia/git-pocket[Git Pocket Guide]
== Установка
В Debian/Ubuntu:
[source,sh]
----
sudo apt-get install git
----
== Термины
[width="100%",cols="18%,20%,62%",options="header",]
|===
|Термин |Англ |Определение
|Рабочий каталог |working tree, working directory |Набор файлов в
текущем каталоге
|Репозиторий |repository, repo |Контейнер, хранящий историю изменений
файлов проекта
|Индекс |index, staging area |Область между рабочим каталогом и
репозиторием, в котором осуществляется подготовка к фиксации
|SHA-1 |SHA-1 |Уникальный идентификатор, отражающий информацию об
истории
|Ветка |branch |Именованная последовательность в истории изменений
|Фиксация (коммит) |commit |Набор файлов, записанных в историю
одновременно
|`HEAD` |`HEAD` |Имя ссылки на последнюю фиксацию в текущей ветке
|Метка |tag |Именованная ссылка на некоторую фиксацию в истории
|===
== Состояния
Файлы в рабочем каталоге могут отслеживаться системой контроля версий
(tracked) или нет (untracked). Отслеживаемые файлы, которые на диаграмме
обозначены зелёным фоном, могут быть неизменёнными (unmodified),
изменёнными (modified) или подготовленными к фиксации (indexed).
[.text-center]
.Состояния
[plantuml]
----
@startuml
participant untracked as "Неотслеживамые\n(untracked)"
box "Отслеживаемые"
participant staged as "Подготовленные к фиксации\n(indexed)" #55FF55
participant unmodified as "Неизменённые\n(unmodified)" #99FF99
participant modified as "Изменённые\n(modified)" #77FF77
end box
untracked -> staged : git add
staged -> unmodified : git commit
unmodified -> modified : редактирование
modified -> staged : git add
modified -> untracked: git rm --cached
unmodified -> untracked: git rm --cached
staged -> untracked: git rm --cached
@enduml
----
Основные команды, осуществляющие взаимодействие между рабочим каталогом,
индексом, локальным и удалённым репозиторием, приведены на диаграмме
ниже.
[.text-center]
.Команды
[plantuml]
----
@startuml
participant workspace as "Рабочий каталог\n(working dir)"
participant index as "Индекс\n(index)" #77FF77
participant local as "Локальный репозиторий\n(local repository)" #FF7777
participant remote as "Удалённый репозиторий\n(remote repository)" #7777FF
workspace -> local : git commit -a
workspace -> index : git add (-u)
index -> local : git commit
local -> remote : git push
== Обновление с сервера ==
remote -> workspace : git pull (rebase)
remote -> local : fetch
== Откат изменений ==
local -[#red]> workspace : git checkout HEAD
index -[#red]> workspace : git checkout
== Сравнение ==
local -[#blue]> workspace : git diff HEAD
index -[#blue]> workspace : git diff
@enduml
----
== Настройка
[width="100%",cols="15%,35%,50%",options="header",]
|===
|Команда |Ключи |Описание
|`git config` |`--global user.name "John Doe"` |Имя текущего
пользователя
|`git config` |`--global user.email "mail@example.com"` |Почта текущего
пользователя
|`git config` |`--list` |Вывод текущей конфигурации
|`git config` |`--global --list` |Вывод глобальной конфигурации
|===
== Инициализация
[width="100%",cols="15%,35%,50%",options="header",]
|===
|Команда |Ключи |Описание
|`git init` |`<dir>` |Создать пустой репозиторий в каталоге `<dir>`
|`git clone` |`<giturl>` `<dir>` |Создать в каталоге `<dir>` копию
репозитория, находящегося по адресу `<giturl>`
|`git clone` |`--recursive <giturl>` `<dir>` |Создать в каталоге `<dir>`
копию репозитория, находящегося по адресу `<giturl>`, с учётом
подмодулей
|===
== Подмодули
[width="100%",cols="15%,25%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git submodule` |`add <giturl> <dir>` |Добавить в каталог `<dir>`
текущего репозитория подмодуль, находящийся по адресу `<giturl>`
|`git submodule` |`update --recursive --remote` |Обновить подмодули
|`git submodule` |`sync --recursive` |Заменить адреса подмодулей на
указанные в файле `.gitmodules`
|===
Удаление подмодуля:
[source,sh]
----
git submodule deinit <path/to/submodule>
git rm <path/to/submodule>
----
== Фиксация
[width="100%",cols="15%,25%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git add` |`<filename>` |Подготовить файл `<filename>` к фиксации
|`git commit` | |Зафиксировать подготовленные файлы
|`git commit` |`-a` |Зафиксировать все отслеживаемые файлы, которые были
изменены
|===
== Удаление
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git rm` |`<filename>` |Удалить файл из индекса и рабочего каталога
|`git rm` |`-f <filename>` |Принудительное удаление файла
|`git rm` |`--cached <filename>` |Удаление файла из проекта, но не из
рабочего каталога
|===
== Информация
[cols=",,",options="header",]
|===
|Команда |Ключи |Описание
|`git status` |`-s` |Вывод информации о рабочем каталоге в краткой форме
|`git log` |`--oneline` |Вывод журнала изменений в краткой форме
|`git ls-files` | |Вывод списка отслеживаемых и подготовленных файлов
|===
== Удалённый репозиторий
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git remote` |`-v` |Список адресов удалённых репозиториев
|`git branch` |`-r` |Список веток в удалённых репозиториях
|`git remote` |`add <name> <url>` |Создать ссылку `<name>` на удалённый
репозиторий, находящийся по адресу `<url>`
|`git remote` |`rename <old> <new>` |Переименовать ссылку `<old>` на
`<new>`
|`git remote` |`rm <name>` |Удалить ссылку `<name>`
|===
* Обращение к удалённому репозиторию осуществляется по ссылке,
создаваемой командой `git remote`
* Команда `git clone` автоматически создаёт ссылку `origin`
== Отправка изменений
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git push` |`<remote> <branch>` |Отправить ветку `<branch>` в удалённый
репозиторий `<remote>`
|`git push` |`<remote> --all` |Отправить все ветки в удалённый
репозиторий `<remote>`
|`git push` |`--d <remote> <branch>` |Удалить ветку `<branch>` из
удалённого репозитория `<remote>`
|===
== Получение изменений
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git fetch` |`<remote>` |Получить изменения из всех веток репозитория
`<remote>`, но не выполнять слияние
|`git fetch` |`<remote> <branch>` |Получить изменения из ветки
`<branch>` репозитория `<remote>`, но не выполнять слияние
|`git merge` |`<remote>/<branch>` |Выполнить слияние с веткой `<branch>`
репозитория `<remote>`
|`git pull` |`<remote>` |Получение и слияние
|===
== Ветки
[cols=",,",options="header",]
|===
|Команда |Ключи |Описание
|`git branch` |`-a` |Список локальных и удалённых веток
|`git branch` | |Список локальных веток
|`git branch` |`<branch>` |Создать ветку `<branch>`
|`git checkout` |`<sha-1>` |Перейти к фиксации с идентификатором
`<sha-1>`
|`git branch` |`-m <old> <new>` |Переименовать ветку `<old>` в `<new>`
|`git merge` |`<branch>` |Слить изменения из ветки `<branch>` в текущую
ветку
|`git branch` |`-d <branch>` |Удалить ветку `<branch>`
|===
== Сравнение
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git diff` | |Сравнить рабочий каталог и индекс
|`git diff` |`-cached` |Сравнить индекс и последнюю фиксацию
|`git diff` |`HEAD` |Сравнить последнюю фиксацию и рабочий каталог
|`git diff` |`--stat` |Краткий вывод результатов
|`git diff` |`<sha-1> <sha-1>` |Сравнить две точки с указанными
идентификаторами
|`git diff` |`<dir>` `<file>` |Сравнивать только указанный каталог
`<dir>` или файл `<file>`
|`git difftool` | |Отобразить результаты сравнения в программе,
определяемой переменной `diff.tool`
|===

View File

@ -1,221 +0,0 @@
---
title: "Git: основные команды"
category: Программирование
tags: программирование, git
monofontoptions:
- Scale=0.8
...
<style type="text/css" rel="stylesheet">
table { table-layout: fixed;}
</style>
## Ссылки
* [GitHowTo](https://githowto.com/ru/changes_not_files)
* [ProGit](https://git-scm.com/book/ru/v2)
* [Git Pocket Guide](https://github.com/maxliscia/git-pocket)
## Установка
В Debian/Ubuntu:
```sh
sudo apt-get install git
```
## Термины
| Термин | Англ | Определение |
| ------ | ------ | ----------------------- |
| Рабочий каталог | working tree, working directory | Набор файлов в текущем каталоге |
| Репозиторий | repository, repo | Контейнер, хранящий историю изменений файлов проекта |
| Индекс | index, staging area | Область между рабочим каталогом и репозиторием, в которой осуществляется подготовка к фиксации |
| SHA-1 | SHA-1 | Уникальный идентификатор, отражающий информацию об истории |
| Ветка | branch | Именованная последовательность в истории изменений |
| Фиксация (коммит) | commit | Набор файлов, записанных в историю одновременно |
| `HEAD` | `HEAD` | Имя ссылки на последнюю фиксацию в текущей ветке |
| Метка | tag | Именованная ссылка на некоторую фиксацию в истории |
## Состояния
Файлы в рабочем каталоге могут отслеживаться системой контроля версий
(tracked) или нет (untracked). Отслеживаемые файлы, которые на диаграмме
обозначены зелёным фоном, могут быть неизменёнными (unmodified),
изменёнными (modified) или подготовленными к фиксации (indexed).
```plantuml
@startuml
participant untracked as "Неотслеживамые\n(untracked)"
box "Отслеживаемые"
participant staged as "Подготовленные к фиксации\n(indexed)" #55FF55
participant unmodified as "Неизменённые\n(unmodified)" #99FF99
participant modified as "Изменённые\n(modified)" #77FF77
end box
untracked -> staged : git add
staged -> unmodified : git commit
unmodified -> modified : редактирование
modified -> staged : git add
modified -> untracked: git rm --cached
unmodified -> untracked: git rm --cached
staged -> untracked: git rm --cached
@enduml
```
Основные команды, осуществляющие взаимодействие между рабочим каталогом,
индексом, локальным и удалённым репозиторием, приведены на диаграмме ниже.
```plantuml
@startuml
participant workspace as "Рабочий каталог\n(working dir)"
participant index as "Индекс\n(index)" #77FF77
participant local as "Локальный репозиторий\n(local repository)" #FF7777
participant remote as "Удалённый репозиторий\n(remote repository)" #7777FF
workspace -> local : git commit -a
workspace -> index : git add (-u)
index -> local : git commit
local -> remote : git push
== Обновление с сервера ==
remote -> workspace : git pull (rebase)
remote -> local : fetch
== Откат изменений ==
local -[#red]> workspace : git checkout HEAD
index -[#red]> workspace : git checkout
== Сравнение ==
local -[#blue]> workspace : git diff HEAD
index -[#blue]> workspace : git diff
@enduml
```
## Настройка
| Команда | Ключи | Описание |
| ---- | ---------- | ------------ |
| `git config` | `--global user.name "John Doe"` | Имя текущего пользователя |
| `git config` | `--global user.email "mail@example.com"` | Почта текущего пользователя |
| `git config` | `--list` | Вывод текущей конфигурации |
| `git config` | `--global --list` | Вывод глобальной конфигурации |
## Инициализация
| Команда | Ключи | Описание |
| ---- | ------ | ------------ |
| `git init` | `<dir>` | Создать пустой репозиторий в каталоге `<dir>` |
| `git clone` | `<giturl>` `<dir>` | Создать в каталоге `<dir>` копию репозитория, находящегося по адресу `<giturl>` |
| `git clone` | `--recursive <giturl>` `<dir>` | Создать в каталоге `<dir>` копию репозитория, находящегося по адресу `<giturl>`, с учётом подмодулей |
## Подмодули
| Команда | Ключи | Описание |
| ---- | ------ | ------------ |
| `git submodule` | `add <giturl> <dir>` | Добавить в каталог `<dir>` текущего рапозитория подмодуль, находящийся по адресу `<giturl>` |
| `git submodule` | `update --recursive --remote` | Обновить подмодули |
| `git submodule` | `sync --recursive` | Заменить адреса подмодулей на указанные в файле `.gitmodules` |
Удаление подмодуля:
```sh
git submodule deinit <path/to/submodule>
git rm <path/to/submodule>
```
## Фиксация
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git add` | `<filename>` | Подготовить файл `<filename>` к фиксации |
| `git commit` | | Зафиксировать подготовленные файлы |
| `git commit` | `-a` | Зафиксировать все отслеживаемые файлы, которые были изменены |
## Удаление
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git rm` | `<filename>` | Удалить файл из индекса и рабочего каталога |
| `git rm` | `-f <filename>` | Принудительное удаление файла |
| `git rm` | `--cached <filename>` | Удаление файла из проекта, но не из рабочего каталога |
## Информация
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git status` | `-s` | Вывод информации о рабочем каталоге в краткой форме |
| `git log` | `--oneline` | Вывод журнала изменений в краткой форме |
| `git ls-files` | | Вывод списка отслеживаемых и подготовленных файлов |
## Удалённый репозиторий
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git remote` | `-v` | Список адресов удалённых репозиториев |
| `git branch` | `-r` | Список веток в удалённых репозиториях |
| `git remote` | `add <name> <url>` | Создать ссылку `<name>` на удалённый репозиторий, находящийся по адресу `<url>` |
| `git remote` | `rename <old> <new>` | Переименовать ссылку `<old>` на `<new>` |
| `git remote` | `rm <name>` | Удалить ссылку `<name>` |
* Обращение к удалённому репозиторию осуществляется по ссылке, создаваемой командой `git remote`
* Команда `git clone` автоматически создаёт ссылку `origin`
## Отправка изменений
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git push` | `<remote> <branch>` | Отправить ветку `<branch>` в удалённый репозиторий `<remote>` |
| `git push` | `<remote> --all` | Отправить все ветки в удалённый репозиторий `<remote>` |
| `git push` | `--d <remote> <branch>` | Удалить ветку `<branch>` из удалённого репозитория `<remote>` |
## Получение изменений
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git fetch` | `<remote>` | Получить изменения из всех веток репозитория `<remote>`, но не выполнять слияние |
| `git fetch` | `<remote> <branch>` | Получить изменения из ветки `<branch>` репозитория `<remote>`, но не выполнять слияние |
| `git merge` | `<remote>/<branch>` | Выполнить слияние с веткой `<branch>` репозитория `<remote>` |
| `git pull` | `<remote>` | Получение и слияние |
## Ветки
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git branch` | `-a` | Список локальных и удалённых веток |
| `git branch` | | Список локальных веток |
| `git branch` | `<branch>` | Создать ветку `<branch>` |
| `git checkout` | `<sha-1>` | Перейти к фиксации с идентификатором `<sha-1>` |
| `git branch` | `-m <old> <new>` | Переименовать ветку `<old>` в `<new>` |
| `git merge` | `<branch>` | Слить изменения из ветки `<branch>` в текущую ветку |
| `git branch` | `-d <branch>` | Удалить ветку `<branch>` |
## Сравнение
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git diff` | | Сравнить рабочий каталог и индекс |
| `git diff` | `-cached` | Сравнить индекс и последнюю фиксацию |
| `git diff` | `HEAD` | Сравнить последнюю фиксацию и рабочий каталог |
| `git diff` | `--stat` | Краткий вывод результатов |
| `git diff` | `<sha-1> <sha-1>` | Сравнить две точки с указанными индетификаторами |
| `git diff` | `<dir> | <file>` | Сравнивать только укзанный каталог `<dir>` или файл `<file>` |
| `git difftool` | | Отобразить результаты сравнения в программе, определяемой переменной `diff.tool` |

View File

@ -0,0 +1,12 @@
= Git: распаковка объекта
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
:toc:
В случае повреждения репозитория можно восстановить отдельные объекты,
которые сохраняются в формате zlib. Пример команды:
....
perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' < 1234567890abcdef1234567890abcdef012345 > file
....

View File

@ -1,14 +0,0 @@
---
title: "Git: распаковка объекта"
category: Программирование
tags: программирование, git,
monofontoptions:
- Scale=0.7
...
В случае повреждения репозитория можно восстановить отдельные
объекты, которые сохраняются в формате zlib. Пример команды:
```
perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' < 1234567890abcdef1234567890abcdef012345 > file
```

View File

@ -1,26 +1,27 @@
--- = Git: репозиторий на переносном устройстве
title: "Git: репозиторий на переносном устройстве" :title-separator: {sp}|
category: Программирование :category: Программирование
tags: программирование, git, :tags: программирование, git,
...
Создание репозитория для нового проекта: Создание репозитория для нового проекта:
```sh [source,sh]
----
ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git
git --bare init /home/user/work/usbdisk/git/project.git git --bare init /home/user/work/usbdisk/git/project.git
cd /home/user/work/projects cd /home/user/work/projects
git clone /home/user/work/usbdisk/git/project.git git clone /home/user/work/usbdisk/git/project.git
cd project cd project
git remote set-url usb file:///home/user/work/usbdisk/git/project.git/ git remote set-url usb file:///home/user/work/usbdisk/git/project.git/
``` ----
Добавление нового удалённого репозитория к существующему проекту: Добавление нового удалённого репозитория к существующему проекту:
```sh [source,sh]
----
ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git
git --bare init /home/user/work/usbdisk/git/project.git git --bare init /home/user/work/usbdisk/git/project.git
cd /home/user/work/projects/project cd /home/user/work/projects/project
git remote add usb file:///home/user/work/usbdisk/git/project.git git remote add usb file:///home/user/work/usbdisk/git/project.git
git push --set-upstream usb master git push --set-upstream usb master
``` ----

View File

@ -0,0 +1,30 @@
= Git: частичная копия репозитория
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Если проект очень большой, а следить нужно только за малой его частью,
можно создать частичную копию репозитория. Допустим, по адресу
`git://localhost/project.git` находится большой проект, в котором
интересует только последнее состояние каталогов `src/driver` и
`include/driver`. Сначала нужно создать пустой репозиторий и подготовить
его для получения только необходимых файлов:
[source,sh]
----
git init project
cd project
git remote add origin git://localhost/project.git
git config core.sparsecheckout true
echo "src/driver/*" >> .git/info/sparse-checkout
echo "include/driver/*" >> .git/info/sparse-checkout
----
После этого можно получать частичную копию проекта, а, добавив ключ
`--depth=1`, указать, что синхронизироваться должно только текущее
состояние файлов без учёта истории.
[source,sh]
----
git pull --depth=1 origin master
----

View File

@ -1,31 +0,0 @@
---
title: "Git: частичная копия репозитория"
category: Программирование
tags: программирование, git,
summary:
...
Если проект очень большой, а следить нужно только за малой
его частью, можно создать частичную копию репозитория.
Допустим, по адресу `git://localhost/project.git` находится
большой проект, в котором интересует только последнее
состояние каталогов `src/driver` и `include/driver`.
Сначала нужно создать пустой репозиторий и подготовить его
для получения только необходимых файлов:
```sh
git init project
cd project
git remote add origin git://localhost/project.git
git config core.sparsecheckout true
echo "src/driver/*" >> .git/info/sparse-checkout
echo "include/driver/*" >> .git/info/sparse-checkout
```
После этого можно получать частичную копию проекта,
а, добавив ключ `--depth=1`, указать, что синхронизироваться
должно только текущее состояние файлов без учёта истории.
```sh
git pull --depth=1 origin master
```

View File

@ -0,0 +1,39 @@
= GitLab: выполнение по расписанию
:title-separator: {sp}|
:category: Программирование
:tags: программирование, gitlab, git,
После помещения изменений (push) на сервер следует выполнять только
задачи, не требующие много ресурсов. Ресурсоёмкие задачи можно отложить
на время минимальной нагрузки сервера. Для этого нужно:
* в секциях файла `.gitlab-ci.yml`, запускающих задачи с высокой
нагрузкой, добавить
[source,yaml]
----
only:
- schedules
----
подробнее это описано
https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified[здесь]
* в веб-интерфейсе в меню *CI/CD* / *Расписания* добавить *Новое
расписание* и назначить исполнение задачи на время, когда нагрузка на
сервер минимальна.
Для пропуска запланированной задачи в исполняемый скрипт нужно добавить
проверку условия запуска. Например, чтобы отменить запуск компиляции,
если за последний день (86400 секунд) не было изменений, можно оформить
`.gitlab-ci.yml` примерно так:
[source,yaml]
----
nightly-job:
only:
- schedules
script:
- "[ $(($(date +%s)-$(git log -1 --date=format:%s --format=%cd))) -gt 86400 ] && exit 0"
- make
----

View File

@ -1,36 +0,0 @@
---
title: "GitLab: выполнение по расписанию"
category: Программирование
tags: программирование, gitlab, git,
...
После помещения изменений (push) на сервер следует выполнять только задачи,
не требующие много ресурсов. Ресурсоёмкие задачи можно отложить на время
минимальной нагрузки сервера. Для этого нужно:
* в секциях файла `.gitlab-ci.yml`, запускающих задачи с высокой нагрузкой,
добавить
```yaml
only:
- schedules
```
подробнее это описано [здесь](https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified)
* в веб-интерфейсе в меню **CI/CD** / **Расписания** добавить **Новое расписание**
и назначить исполнение задачи на время, когда нагрузка на сервер минимальна.
Для пропуска запланированной задачи в исполняемый скрипт нужно добавить
проверку условия запуска. Например, чтобы отменить запуск компиляции,
если за последний день (86400 секунд) не было изменений, можно оформить
`.gitlab-ci.yml` примерно так:
```yaml
nightly-job:
only:
- schedules
script:
- "[ $(($(date +%s)-$(git log -1 --date=format:%s --format=%cd))) -gt 86400 ] && exit 0"
- make
```

View File

@ -1,33 +1,31 @@
--- = Установка и настройка GitLab в LXC
title: "Установка и настройка GitLab в LXC" :category: Программирование
category: Программирование :tags: программирование, gitlab, git, lxc, контейнеры, ubuntu,
tags: программирование, gitlab, git, lxc, контейнеры, ubuntu,
summary:
toc: yes
...
[TOC] :toc:
Установка выполняется в операционной системе Ubuntu Bionic. Установка выполняется в операционной системе Ubuntu Bionic.
### LXC == LXC
Создание базового контейнера: Создание базового контейнера:
```sh [source,sh]
----
lxc-create -t download -n bionic-base -- --dist ubuntu --release bionic --arch amd64 lxc-create -t download -n bionic-base -- --dist ubuntu --release bionic --arch amd64
``` ----
Создание контейнеров для GitLab и GitLab Runner: Создание контейнеров для GitLab и GitLab Runner:
```sh [source,sh]
----
lxc-copy -n bionic-base -N gitlab-bionic -s lxc-copy -n bionic-base -N gitlab-bionic -s
lxc-copy -n bionic-base -N gitlab-runner-bionic -s lxc-copy -n bionic-base -N gitlab-runner-bionic -s
``` ----
Файл `/var/lib/lxc/gitlab-bionic/config`: Файл `/var/lib/lxc/gitlab-bionic/config`:
``` ....
# Distribution configuration # Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf lxc.include = /usr/share/lxc/config/common.conf
@ -50,11 +48,11 @@ lxc.autodev = 1
lxc.pty.max = 16384 lxc.pty.max = 16384
lxc.cgroup.devices.allow = c 10:200 rwm lxc.cgroup.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net dev/net none bind,create=dir lxc.mount.entry = /dev/net dev/net none bind,create=dir
``` ....
Файл `/var/lib/lxc/gitlab-runner-bionic/config`: Файл `/var/lib/lxc/gitlab-runner-bionic/config`:
``` ....
# Distribution configuration # Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf lxc.include = /usr/share/lxc/config/common.conf
@ -82,65 +80,67 @@ lxc.autodev = 1
lxc.pty.max = 16384 lxc.pty.max = 16384
lxc.cgroup.devices.allow = c 10:200 rwm lxc.cgroup.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net dev/net none bind,create=dir lxc.mount.entry = /dev/net dev/net none bind,create=dir
``` ....
### GitLab == GitLab
Установить GitLab: Установить GitLab:
```sh [source,sh]
----
sudo lxc-start -n gitlab-bionic sudo lxc-start -n gitlab-bionic
sudo lxc-attach -n gitlab-bionic sudo lxc-attach -n gitlab-bionic
sudo apt install curl sudo apt install curl
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo apt install gitlab-ce sudo apt install gitlab-ce
``` ----
Отредактировать файл `/etc/locale.gen` и сгенерировать локали для системы: Отредактировать файл `/etc/locale.gen` и сгенерировать локали для
системы:
```sh [source,sh]
----
sudo locale-gen sudo locale-gen
``` ----
Отредактировать файл `/etc/gitlab/gitlab.rb` и выполнить: Отредактировать файл `/etc/gitlab/gitlab.rb` и выполнить:
```sh [source,sh]
----
sudo gitlab-ctl reconfigure sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart sudo gitlab-ctl restart
``` ----
== GitLab Runner и Docker
### GitLab Runner и Docker
Установить GitLab Runner: Установить GitLab Runner:
```sh [source,sh]
----
sudo lxc-start -n runner-bionic sudo lxc-start -n runner-bionic
sudo lxc-attach -n runner-bionic sudo lxc-attach -n runner-bionic
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner docker.io sudo apt install gitlab-runner docker.io
sudo gitlab-runner register sudo gitlab-runner register
``` ----
Во время установки ввести токен приведённый на странице `admin/runners`, Во время установки ввести токен приведённый на странице `admin/runners`,
а в качестве исполнителя задач `docker`. а в качестве исполнителя задач `docker`.
Для работы Docker внутри контейнера нужно удалить AppArmor: Для работы Docker внутри контейнера нужно удалить AppArmor:
```sh [source,sh]
----
sudo apt purge apparmor sudo apt purge apparmor
``` ----
Внутри контейнера для Docker желательно использовать драйвер `btrfs` Внутри контейнера для Docker желательно использовать драйвер `btrfs` cat
cat /etc/docker/daemon.json /etc/docker/daemon.json
{ \{ ``storage-driver'': ``btrfs'' }
"storage-driver": "btrfs"
}
== Ссылки
### Ссылки * https://docs.gitlab.com/runner/register/index.html[GitLab Runner]
* https://docs.gitlab.com/ee/ci/runners/[Runners]
* [GitLab Runner](https://docs.gitlab.com/runner/register/index.html) * https://habr.com/ru/company/southbridge/blog/306596/[Gitlab-CI]
* [Runners](https://docs.gitlab.com/ee/ci/runners/)
* [Gitlab-CI](https://habr.com/ru/company/southbridge/blog/306596/)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
= Библиотеки для C, C++
:category: Программирование
:tags: программирование, C, C++, Qt,
:toc:
== C
* http://nanomsg.org[nanomsg]: сетевое взаимодействие
* https://noping.cc[oping]: работа с ICMP-пакетами
* https://github.com/xianyi/OpenBLAS[openblas]: оптимизированная версия
https://ru.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms[BLAS]
== C++
* https://github.com/nlohmann/json[JSON]
* https://github.com/fmtlib/fmt[fmtlib]: форматирование строк
* https://github.com/gabime/spdlog[spdlog]: журналирование
* https://github.com/skystrife/cpptoml[cpptoml]: чтение
https://github.com/toml-lang/toml[TOML]
* https://github.com/martinmoene/gsl-lite/[gsl-lite]: реализация
рекомендаций https://github.com/isocpp/CppCoreGuidelines[C++ Core
Guidelines]
* http://www.holoborodko.com/pavel/mpfr[mpfrc++]: C++ интерфейс для
https://www.mpfr.org/[MPFR]
== Qt
* https://github.com/sjinks/qt_signalwatcher[Обработка сигналов UNIX]

View File

@ -1,30 +0,0 @@
---
title: "Библиотеки для C, C++"
category: Программирование
tags: программирование, C, C++, Qt,
summary:
toc: yes
...
[TOC]
### C
* [nanomsg](http://nanomsg.org): сетевое взаимодействие
* [oping](https://noping.cc): работа с ICMP-пакетами
* [openblas](https://github.com/xianyi/OpenBLAS): оптимизированная версия
[BLAS](https://ru.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms)
### C++
* [JSON](https://github.com/nlohmann/json)
* [fmtlib](https://github.com/fmtlib/fmt): форматирование строк
* [spdlog](https://github.com/gabime/spdlog): журналирование
* [cpptoml](https://github.com/skystrife/cpptoml): чтение [TOML](https://github.com/toml-lang/toml)
* [gsl-lite](https://github.com/martinmoene/gsl-lite/): реализация рекомедаций [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines)
* [mpfrc++](http://www.holoborodko.com/pavel/mpfr): C++ интерфейс для [MPFR](https://www.mpfr.org/)
### Qt
* [Обработка сигналов UNIX](https://github.com/sjinks/qt_signalwatcher)

View File

@ -0,0 +1,151 @@
= Работа с датами и временем
:category: Программирование
:tags: программирование, время, часы, дата
:toc: auto
== Временные шкалы
В идеале системы учёта времени должны обладать тремя характеристиками:
. _точность_ (время базируется на атомном стандарте, каждая секунда
отсчитывается как секунда в системе СИ, нет високосных секунд, переводов
на зимнее или летнее время и т.п.);
. _простота_ (каждый '`день`' состоит из 86400 "`секунд`");
. _календарные дни_ (дни календаря точно соответствуют вращению Земли).
На практике есть возможность выбрать шкалу только с двумя
характеристиками из трёх.
. точность и календарные дни. Примером такой шкалы является UTC, в
которой отсчёт дней и секунд ведётся разными методами (секунды
исчисляются по атомному стандарту, а дни по суточному вращению Земли), а
соответствие достигается вводом _секунды координации_;
. календарные дни и простота. Примером такой шкалы является POSIX (IEEE
Std 1003.1-1988), в которой день всегда равен 86400 секундам;
. точность и простота. Этими характеристиками обладают технические шкалы
(атомные часы, GPS), в которых не важен учёт дней.
== Классы времени
Время можно условно поделить на два класса: физическое и гражданское.
. _Физическое_ время представляет собой точки на непрерывной шкале,
такую концепцию достаточно точно отражает UTC, если можно пренебречь
_секундой координации_ (дополнительная секунда, добавляемая к UTC 30
июня или 31 декабря для согласования со средним солнечным временем UT1.
В этот момент время условно обозначается как 23:59:60, а на шкале UTC
две секунды отображаются как одна).
. _Гражданское_ время представляется полями (год, месяц, число, час,
минута, секунда, доли секунды, а также временная зона и календарь,
который по умолчанию считается Григорианским).
Почти всегда существует возможность однозначно перевести физическое
время в гражданское и наоборот, но при этом следует различать их
свойства и применение (ближайшая аналогия — массивы байтов и символьные
строки).
Основная проблема состоит в том, что в обычном употреблении не всегда
можно сделать вывод о том, какой класс времени подразумевается, и
гражданское время меняется на основании юридических актов (указов,
постановлений и т.п.), что приводит к неоднозначности при планировании
событий.
== Обработка на компьютере
=== Хранение и отображение
Для ссылки на момент во времени необходимо использовать единую шкалу, на
которой нет разрывов, связанных с летним временем. Примером стандарта
времени с такой шкалой является UTC. Локальное или местное время для
таких целей не подходит, так как на его шкале имеются разрывы и
неоднозначности, связанные с переходами на летнее время и обратно.
Если нужно сохранить значение локального времени, то необходимо
сохранить также смещение относительно UTC, чтобы временную отметку можно
было интерпретировать однозначно. Необходимо помнить, что местное время
может отличаться от UTC на интервал не кратный часу (например, в
Нидерландах с 1909-05-01 по 1937-06-30 смещение времени от UTC
составляло 19 минут и 32.13 секунд).
Правила хранения и отображения времени:
. Время всегда хранится в UTC. При необходимости дополнительно
сохраняется информация о временной зоне (смещение и/или название).
. Для вывода на экран время переводится в местное.
. При выводе на экран отличного от местного времени необходимо указывать
название часового пояса или типа исчисления (например, Юлианский
календарь).
=== Системное время для администратора
Системный администратор должен следить за тем, чтобы файлы базы данных
описания временных зон *tzdata* имели одну версию в рамках комплекса и
обновлялись регулярно, чтобы минимизировать расхождения с внешними
системами. Особенно это важно делать при издании новых правил учёта
зимнего или летнего времени.
На серверах аппаратные часы всегда должны использовать UTC. Операционные
системы тоже должны использовать UTC, чтобы при возникновении проблем в
файлах журналов было указано время в едином формате.
В рамках комплекса следует использовать синхронизацию времени, даже если
нет доверенного источника более высокого уровня.
=== Клиентские приложения
В общем случае нельзя доверять временным отметкам внешних клиентов, так
как невозможно гарантировать их корректность. Программа должна
самостоятельно ставить временные отметки для происходящих событий.
Исключением являются программные комплексы, в которых предусмотрено
наличие доверенных приложений, ответственных за установку временных
отметок.
=== Postgresql
Сервер базы данных должен использовать только временную зону UTC. Для
этого в файле настройки сервера `postgresql.conf` должна быть строка
....
timezone = 'UTC'
....
При создании таблиц необходимо использовать типы данных
`timestamp without time zone` и `time without time zone`. Если данные о
времени должны содержать информацию о временной зоне или смещении
относительно UTC, то нужно создать дополнительные столбцы, информацию из
которых должно обрабатывать клиентское приложение. Например, временные
отметки можно хранить в таком виде
[source,sql]
----
CREATE TABLE time_stamps (
time_stamp time without time zone, -- временная отметка
time_zone character(12), -- текстовое название временной зоны
shift integer -- смещение локального времени относительно UTC в секундах
);
----
Смещение следует записывать в четырёхбайтное знаковое целое, так как оно
может быть как положительным, так и отрицательным, а его максимальное
значение может составлять 14 * 60 * 60 = 50400 секунд. Несмотря на
приведённый выше пример с временной зоной Нидерландов, микросекундами
можно пренебречь, так как современные временные зоны имеют смещения
кратные минутам, а точность до микросекунд в далёком прошлом обычно не
требуется.
Чтобы клиентская программа могла получить выборку, привязанную к
некоторой временной зоне можно использовать оператор `AT TIME ZONE`,
например
[source,sql]
----
SELECT TIMESTAMP '2001-02-16 20:38:40Z' AT TIME ZONE 'MSK';
----
В результате время будет преобразовано из временной зоны UTC в MSK.
Модификатор `Z` в записи времени указывает на принадлежность зоне UTC.
=== Qt
Класс `QTimeZone` предназначен для получения информации о временной зоне
и перевода времени из одной временной зоны в другую.

View File

@ -1,159 +0,0 @@
---
title: "Работа с датами и временем"
category: Программирование
tags: программирование, время, часы, дата,
summary:
toc: yes
toc-depth: 4
...
[TOC]
### Временные шкалы
В идеале системы учёта времени должны обладать тремя характеристиками:
1. очность_ (время базируется на атомном стандарте, каждая секунда
отсчитывается как секунда в системе СИ, нет високосных секунд, переводов
на зимнее или летнее время и т.п.);
2. _простота_ (каждый "день" состоит из 86400 "секунд");
3. алендарные дни_ (дни календаря точно соответствуют вращению Земли).
На практике есть возможность выбрать шкалу только с двумя характеристиками
из трёх.
1. точность и календарные дни. Примером такой шкалы является UTC,
в которой отсчёт дней и секунд ведётся разными методами (секунды
исчисляются по атомному стандарту, а дни по суточному вращению Земли),
а соответствие достигается вводом _секунды координации_;
2. календарные дни и простота. Примером такой шкалы является POSIX
(IEEE Std 1003.1-1988), в которой день всегда равен 86400 секундам;
3. точность и простота. Этими характеристиками обладают технические
шкалы (атомные часы, GPS), в которых не важен учёт дней.
### Классы времени
Время можно условно поделить на два класса: физическое и гражданское.
1. _Физическое_ время представляет собой точки на непрерывной шкале, такую
концепцию достаточно точно отражает UTC, если можно пренебречь _секундой
координации_ (дополнительная секунда, добавляемая к UTC 30 июня или 31 декабря
для согласования со средним солнечным временем UT1. В этот момент время
условно обозначается как 23:59:60, а на шкале UTC две секунды отображаются
как одна).
2. ражданское_ время представляется полями (год, месяц, число, час, минута,
секунда, доли секунды, а также временная зона и календарь, который по умолчанию
считается Григорианским).
Почти всегда существует возможность однозначно перевести физическое время
в гражданское и наоборот, но при этом следует различать их свойства и
применение (ближайшая аналогия — массивы байтов и символьные строки).
Основная проблема состоит в том, что в обычном употреблении не всегда можно
сделать вывод о том, какой класс времени подразумевается, и гражданское
время меняется на основании юридических актов (указов, постановлений и т.п.),
что приводит к неоднозначности при планировании событий.
### Обработка на компьютере
#### Хранение и отображение
Для ссылки на момент во времени необходимо использовать единую шкалу,
на которой нет разрывов, связанных с летним временем. Примером стандарта
времени с такой шкалой является UTC. Локальное или местное время для таких
целей не подходит, так как на его шкале имеются разрывы и неоднозначности,
связанные с переходами на летнее время и обратно.
Если нужно сохранить значение локального времени, то необходимо сохранить
также смещение относительно UTC, чтобы временную отметку можно было
интерпретировать однозначно. Необходимо помнить, что местное время может
отличаться от UTC на интервал не кратный часу (например, в Нидерландах
с 1909-05-01 по 1937-06-30 смещение времени от UTC составляло
19 минут и 32.13 секунд).
Правила хранения и отображения времени:
1. Время всегда хранится в UTC. При необходимости дополнительно сохраняется
информация о временной зоне (смещение и/или название).
2. Для вывода на экран время переводится в местное.
3. При выводе на экран отличного от местного времени необходимо указывать
название часового пояса или типа исчисления (например, Юлианский календарь).
#### Системное время для администратора
Системный администратор должен следить за тем, чтобы файлы базы данных
описания временных зон **tzdata** имели одну версию в рамках комплекса
и обновлялись регулярно, чтобы минимизировать расхождения с внешними
системами. Особенно это важно делать при издании новых правил учёта
зимнего или летнего времени.
На серверах аппаратные часы всегда должны использовать UTC. Операционные
системы тоже должны использовать UTC, чтобы при возникновении проблем
в файлах журналов было указано время в едином формате.
В рамках комплекса следует использовать синхронизацию времени, даже
если нет доверенного источника более высокого уровня.
#### Клиентские приложения
В общем случае нельзя доверять временным отметкам внешних клиентов,
так как невозможно гарантировать их корректность. Программа должна
самостоятельно ставить временные отметки для происходящих событий.
Исключением являются программные комплексы, в которых предусмотрено
наличие доверенных приложений, ответственных за установку временных отметок.
#### Postgresql
Сервер базы данных должен использовать только временную зону UTC. Для этого
в файле настройки сервера `postgresql.conf` должна быть строка
```
timezone = 'UTC'
```
При создании таблиц необходимо использовать типы данных `timestamp without time zone`
и `time without time zone`. Если данные о времени должны содержать информацию
о временной зоне или смещении относительно UTC, то нужно создать дополнительные
столбцы, информацию из которых должно обрабатывать клиентское приложение.
Например, временные отметки можно хранить в таком виде
```sql
CREATE TABLE time_stamps (
time_stamp time without time zone, -- временная отметка
time_zone character(12), -- текстовое название временной зоны
shift integer -- смещение локального времени относительно UTC в секундах
);
```
Смещение следует записывать в четырёхбайтное знаковое целое, так как оно
может быть как положительным, так и отрицательным, а его максимальное
значение может составлять 14 * 60 * 60 = 50400 секунд. Несмотря на приведённый
выше пример с временной зоной Нидерландов, микросекундами можно пренебречь,
так как современные временные зоны имеют смещения кратные минутам, а точность
до микросекунд в далёком прошлом обычно не требуется.
Чтобы клиентская программа могла получить выборку, привязанную к некоторой
временной зоне можно использовать оператор `AT TIME ZONE`, например
```sql
SELECT TIMESTAMP '2001-02-16 20:38:40Z' AT TIME ZONE 'MSK';
```
В результате время будет преобразовано из временной зоны UTC в MSK.
Модификатор `Z` в записи времени указывает на принадлежность зоне UTC.
#### Qt
Класс `QTimeZone` предназначен для получения информации о временной зоне
и перевода времени из одной временной зоны в другую.

19
wiki/Vim/Vimdiff.adoc Normal file
View File

@ -0,0 +1,19 @@
= Vim: сравнение файлов
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Команды режима `diff` для сравнения и слияния файлов:
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`do` |Получить изменения из второго окна в текущее окно
|`dp` |Вставить изменения из текущего окна во второе окно
|`]c` |Перейти к следующему отличию
|`[c` |Перейти к предыдущему отличию
|`C-W` `C-W` |Переход между окнами
|===
http://vimcasts.org/episodes/fugitive-vim-resolving-merge-conflicts-with-vimdiff/[Видеоурок]
по трехпутевому слиянию.

View File

@ -1,19 +0,0 @@
---
title: "Vim: сравнение файлов"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команды режима `diff` для сравнения и слияния файлов:
Команда | Назначение
-------------|------------
`do` | Получить изменения из второго окна в текущее окно
`dp` | Вставить изменения из текущего окна во второе окно
`]c` | Перейти к следующему отличию
`[c` | Перейти к предыдущему отличию
`C-W` `C-W` | Переход между окнами
[Видеоурок](http://vimcasts.org/episodes/fugitive-vim-resolving-merge-conflicts-with-vimdiff/)
по трехпутевому слиянию.

View File

@ -0,0 +1,22 @@
= Vim: замена выделенного блока
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Замену блока, выделенного в режиме VISUAL, можно выполнить
последовательностью команд `y:%s/<ctrl-r>"/заменитель/g`.
[cols="1,3",options="header",]
|===
|Команда |Назначение
|`y` |Копирование в регистр "
|`&#58;` |Перейти в командный режим
|`%` |Применить ко всему буферу
|`s` |Замена
|`Сtrl-r` |Вставка из регистра
|`&quot;` |Имя регистра (будет предложено по умолчанию)
|`/` |Разделитель
|`заменитель` |Новый текст
|`/` |Разделитель
|`g` |Для всех вхождений в строке
|===

View File

@ -1,23 +0,0 @@
---
title: "Vim: замена выделенного блока"
category: Vim
tags: Vim, команды Vim,
summary:
...
Замену блока, выделенного в режиме VISUAL, можно выполнить
последовательностью команд `y:%s/<ctrl-r>"/заменитель/g`.
Команда | Назначение
---------------|-------------
`y` | Копирование в регистр &quot;
`&#58;` | Перейти в командный режим
`%` | Применить ко всему буферу
`s` | Замена
`Сtrl-r` | Вставка из регистра
`&quot;` | Имя регистра (будет предложено по умолчанию)
`/` | Разделитель
`заменитель` | Новый текст
`/` | Разделитель
`g` | Для всех вхождений в строке

View File

@ -1,39 +1,40 @@
--- = Vim: клавиши Leader и LocalLeader
title: "Vim: клавиши Leader и LocalLeader" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, команды Vim, :tags: Vim, команды Vim,
summary:
...
Клавиши `Leader` и `LocalLeader` представляют собой префиксы для команд. Клавиши `Leader` и `LocalLeader` представляют собой префиксы для команд.
Их текущие значения можно посмотреть командами Их текущие значения можно посмотреть командами
```vim [source,vim]
----
:echo mapleader :echo mapleader
:echo maplocalleader :echo maplocalleader
``` ----
Часто их значения переназначают в файле `$HOME/.vimrc`, например так Часто их значения переназначают в файле `$HOME/.vim/vimrc`, например так
```vim [source,vim]
----
let mapleader = "\<Space>" let mapleader = "\<Space>"
let maplocalleader = "," let maplocalleader = ","
``` ----
Новое значение команды генерируется с помощью текущих значений этих Новое значение команды генерируется с помощью текущих значений этих
переменных, таким образом последовательность команд переменных, таким образом последовательность команд
```vim [source,vim]
----
let mapleader = "," let mapleader = ","
nnoremap <Leader>a :echo "Hey there ,"<CR> nnoremap <Leader>a :echo "Hey there ,"<CR>
let mapleader = "\<Space>" let mapleader = "\<Space>"
nnoremap <Leader>a :echo "Hey there space"<CR> nnoremap <Leader>a :echo "Hey there space"<CR>
``` ----
приведёт к тому, что будут созданы две команды `,a` и `<Space>a`, приведёт к тому, что будут созданы две команды `,a` и `<Space>a`,
следовательно для получения единообразных команд следует помещать следовательно для получения единообразных команд следует помещать
переназначения в начало файла `$HOME/.vimrc`. переназначения в начало файла `$HOME/.vim/vimrc`.
`LocalLeader` отличается от `Leader` тем, что действует только для `LocalLeader` отличается от `Leader` тем, что действует только для
текущего буфера, поэтому обычно используется в плагинах, загружаемых текущего буфера, поэтому обычно используется в плагинах, загружаемых
@ -42,7 +43,7 @@ nnoremap <Leader>a :echo "Hey there space"<CR>
Таймауты для ввода команд, использующих клавиши `Leader` и Таймауты для ввода команд, использующих клавиши `Leader` и
`LocalLeader`, настраиваются командой `LocalLeader`, настраиваются командой
```vim [source,vim]
----
set timeout timeoutlen=5000 ttimeoutlen=100 set timeout timeoutlen=5000 ttimeoutlen=100
``` ----

View File

@ -1,14 +1,13 @@
--- = Vim: клавиши PageUp и PageDown
title: "Vim: клавиши PageUp и PageDown" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, команды Vim, :tags: Vim, команды Vim,
summary:
...
Чтобы поведение клавиш `PageUp` и `PageDown` совпадало с более Чтобы поведение клавиш `PageUp` и `PageDown` совпадало с более
привычным, можно добавить в `$HOME/.vimrc` следующий код: привычным, можно добавить в `$HOME/.vim/vimrc` следующий код:
```vim [source,vim]
----
" Более привычные PgUp / PgDown, когда курсор остаётся в той же строке, " " Более привычные PgUp / PgDown, когда курсор остаётся в той же строке, "
" а не переносится вверх / вниз экрана, как при стандартном PgUp / PgDown. " " а не переносится вверх / вниз экрана, как при стандартном PgUp / PgDown. "
" Поскольку по умолчанию прокрутка по C-U / C-D, при которой курсор остаётся " Поскольку по умолчанию прокрутка по C-U / C-D, при которой курсор остаётся
@ -18,5 +17,4 @@ nmap <PageUp> <C-U><C-U>
nmap <PageDown> <C-D><C-D> nmap <PageDown> <C-D><C-D>
imap <PageUp> <C-O><C-U><C-O><C-U> imap <PageUp> <C-O><C-U><C-O><C-U>
imap <PageDown> <C-O><C-D><C-O><C-D> imap <PageDown> <C-O><C-D><C-O><C-D>
``` ----

View File

@ -1,15 +1,14 @@
--- = Vim: кодировка файла
title: "Vim: кодировка файла" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, :tags: Vim,
summary:
...
Для управления кодировкой файлов можно создать дополнительное меню, Для управления кодировкой файлов можно создать дополнительное меню,
позволяющее открыть файл в выбранной кодировке, проверить её позволяющее открыть файл в выбранной кодировке, проверить её
корректность и сохранить в нужном виде. Пример кода: корректность и сохранить в нужном виде. Пример кода:
```vim [source,vim]
----
" кодировка для чтения файла " кодировка для чтения файла
set encoding=utf-8 set encoding=utf-8
" кодировка терминала " кодировка терминала
@ -29,5 +28,4 @@ menu Encoding.Open\ as\ UCS-2LE :e ++enc=ucs-2le<CR>
menu Encoding.Open\ as\ UTF-8 :e ++enc=utf-8<CR> menu Encoding.Open\ as\ UTF-8 :e ++enc=utf-8<CR>
menu Encoding.Convert\ to\ UTF-8 :set fenc=utf-8<CR> menu Encoding.Convert\ to\ UTF-8 :set fenc=utf-8<CR>
map <F12> :emenu Encoding.<Tab> map <F12> :emenu Encoding.<Tab>
``` ----

View File

@ -0,0 +1,26 @@
= Vim: комментирование кода
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Отмена автоматического комментирования кода при вставке из буфера:
[source,vim]
----
autocmd FileType * setlocal formatoptions-=cro
----
Для управления комментированием можно использовать плагин
https://github.com/scrooloose/nerdcommenter[NerdCommenter]. Основные
команды:
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`[n]<leader>cc` |комментировать блок
|`[n]<leader>cn` |комментировать с учётом вложенности
|`[n]<leader>cl` |символ комментария помещать в начало строки
|`[n]<leader>ci` |инвертирование комментариев
|`<leader>cA` |добавить комментарий в конец строки
|`[n]<leader>cu` |раскомментировать блок
|===

View File

@ -1,26 +0,0 @@
---
title: "Vim: комментирование кода"
category: Vim
tags: Vim, команды Vim,
summary:
...
Отмена автоматического комментирования кода при вставке из буфера:
```Vim
autocmd FileType * setlocal formatoptions-=cro
```
Для управления комментированием можно использовать плагин
[NerdCommenter](https://github.com/scrooloose/nerdcommenter).
Основные команды:
Команда | Назначение
----------------------|----------------------------
`[n]<leader\>cc` | комментировать блок
`[n]<leader\>cn` | комментировать с учётом вложенности
`[n]<leader\>cl` | символ комментария помещать в начало строки
`[n]<leader\>ci` | инвертирование комментариев
`<leader\>cA` | добавить комментарий в конец строки
`[n]<leader\>cu` | раскомментировать блок

View File

@ -1,28 +1,28 @@
--- = Vim: менеджер плагинов Plug
title: "Vim: менеджер плагинов Plug" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, плагины Vim, :tags: Vim, плагины Vim,
summary:
...
Автоматическое управление плагинами в Vim можно организовать Автоматическое управление плагинами в Vim можно организовать с помощью
с помощью менеджера [Plug](https://github.com/junegunn/vim-plug), менеджера https://github.com/junegunn/vim-plug[Plug], установить который
установить который можно командой можно командой
```sh [source,sh]
----
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
``` ----
Чтобы использовать Plug, нужно добавить в `$HOME/.vimrc`: Чтобы использовать Plug, нужно добавить в `$HOME/.vim/vimrc`:
1. Строку `call plug#begin('~/.vim/plugged')` * Строку `call plug#begin('~/.vim/plugged')`
2. Список строк, начинающихся с команды `Plug`, для загрузки плагинов * Список строк, начинающихся с команды `Plug`, для загрузки плагинов
3. Закончить список командой `call plug#end()` * Закончить список командой `call plug#end()`
Пример: Пример:
```vim [source,vim]
----
" Обязательно использовать одиночные кавычки " Обязательно использовать одиночные кавычки
call plug#begin('~/.vim/plugged') call plug#begin('~/.vim/plugged')
@ -40,5 +40,4 @@ Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Окончание списка плагинов " Окончание списка плагинов
call plug#end() call plug#end()
``` ----

View File

@ -1,15 +1,14 @@
--- = Vim: навигация по тексту с помощью easymotion
title: "Vim: навигация по тексту с помощью easymotion" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, команды Vim, :tags: Vim, команды Vim,
summary:
...
Плагин [easymotion](https://github.com/easymotion/vim-easymotion) Плагин https://github.com/easymotion/vim-easymotion[easymotion]
предоставляет функции для удобного перемещения по тексту. предоставляет функции для удобного перемещения по тексту. Пример
Пример настройки: настройки:
```vim [source,vim]
----
" Не включать команды по умолчанию " Не включать команды по умолчанию
let g:EasyMotion_do_mapping = 0 let g:EasyMotion_do_mapping = 0
@ -49,5 +48,4 @@ omap / <Plug>(easymotion-tn)
" different highlight method and have some other features ) " different highlight method and have some other features )
map n <Plug>(easymotion-next) map n <Plug>(easymotion-next)
map N <Plug>(easymotion-prev) map N <Plug>(easymotion-prev)
``` ----

View File

@ -0,0 +1,15 @@
= Vim: навигация по буферам
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`:bn` |следующий буфер
|`:bp` |предыдущий буфер
|`:ls` |список открытых буферов
|`:bd` |закрыть текущий буфер
|`:b имя_буфера` |переключиться на буфер
|`:bdа имя_буфера` |удалить буфер по имени
|===

View File

@ -1,16 +0,0 @@
---
title: "Vim: навигация по буферам"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команда | Назначение
------------------|-----------------
`:bn` | следующий буфер
`:bp` | предыдущий буфер
`:ls` | список открытых буферов
`:bd` | закрыть текущий буфер
`:b имя_буфера` | переключиться на буфер
`:bdа имя_буфера` | удалить буфер по имени

View File

@ -1,14 +1,13 @@
--- = Vim: нумерация строк
title: "Vim: нумерация строк" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, команды Vim, :tags: Vim, команды Vim,
summary:
...
Для переключения режимов отображения слева столбца нумерации Для переключения режимов отображения слева столбца нумерации строк можно
строк можно добавить в `$HOME/.vimrc` следующий код: добавить в `$HOME/.vimrc` следующий код:
```vim [source,vim]
----
" Нумерация строк включена " Нумерация строк включена
set number set number
" Нумерация строк абсолютная " Нумерация строк абсолютная
@ -28,7 +27,7 @@ function! ChangeNumbering()
endfunc endfunc
map <LocalLeader># <Esc>:call ChangeNumbering()<CR> map <LocalLeader># <Esc>:call ChangeNumbering()<CR>
``` ----
В результате по команде `<LocalLeader>#` будет осуществляться В результате по команде `<LocalLeader>#` будет осуществляться
циклическое переключение между абсолютной, относительной нумерацией циклическое переключение между абсолютной, относительной нумерацией

View File

@ -1,14 +1,13 @@
--- = Vim: проверка орфографии
title: "Vim: проверка орфографии" :title-separator: {sp}|
category: Vim :category: Vim
tags: Vim, команды Vim, словарь, орфография, :tags: Vim, команды Vim, словарь, орфография,
summary:
...
Код в `$HOME/.vimrc` для циклического переключения режимов проверки Код в `$HOME/.vim/vimrc` для циклического переключения режимов проверки
орфографии: два языка, английский, русский и без проверки: орфографии: два языка, английский, русский и без проверки:
```Vim [source,vim]
----
" По умолчанию проверка орфографии для русского и английского. " По умолчанию проверка орфографии для русского и английского.
setlocal spell spelllang=ru,en setlocal spell spelllang=ru,en
set spellsuggest=9 set spellsuggest=9
@ -35,5 +34,4 @@ map <C-F7> <Esc>:call ChangeSpellLang()<CR>
" выбор альтернатив " выбор альтернатив
imap <F7> <Esc> z=<CR>i imap <F7> <Esc> z=<CR>i
map <F7> z=<CR> map <F7> z=<CR>
``` ----

View File

@ -0,0 +1,11 @@
= Vim: полезные ссылки
:title-separator: {sp}|
:category: Vim
:tags: Vim,
* http://vim.org[Vim]
* http://usevim.com/[Usevim]
* http://nvie.com/posts/how-i-boosted-my-vim/[How I boosted my Vim]
* https://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/[How
to boost your Vim productivity]
* https://vimawesome.com/[Vim Awesome]

View File

@ -1,12 +0,0 @@
---
title: "Vim: полезные ссылки"
category: Vim
tags: Vim,
summary:
...
* [Vim](http://vim.org)
* [Usevim](http://usevim.com/)
* [How I boosted my Vim](http://nvie.com/posts/how-i-boosted-my-vim/)
* [How to boost your Vim productivity](https://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/)
* [Vim Awesome](https://vimawesome.com/)

View File

@ -0,0 +1,20 @@
= Vim: управление окнами
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`:split filename` |открыть в новом окне (горизонтальное разделение)
|`:vsplit filename` |открыть в новом окне (вертикальное разделение)
|`<C-W>` `<C-W>` |перейти к следующему окну
|`<C-W>` `q` |закрыть текущее окно
|`<C-W>` `o` |развернуть окно полностью
|`<C-W>` `pass:c[_]` |развернуть окно по высоте
|`<C-W>` `\|` |развернуть окно по ширине
|`<C-W>` `=` |выровнять размер окон
|`<C-W>` `+` |увеличить окно на 1 строку
|`<C-W>` `-` |уменьшить окно на 1 строку
|`<C-W>` `стрелки` |перемещение между окнами
|===

View File

@ -1,21 +0,0 @@
---
title: "Vim: управление окнами"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команда | Назначение
--------------------|-------------------------
`:split filename` | открыть в новом окне (горизонтальное разделение)
`:vsplit filename` | открыть в новом окне (вертикальное разделение)
`<C-W>` `<C-W>` | перейти к следующему окну
`<C-W>` `q` | закрыть текущее окно
`<C-W>` `o` | развернуть окно полностью
`<C-W>` `_` | развернуть окно по высоте
`<C-W>` `|` | развернуть окно по ширине
`<C-W>` `=` | выровнять размер окон
`<C-W>` `+` | увеличить окно на 1 строку
`<C-W>` `-` | уменьшить окно на 1 строку
`<C-W>` `стрелки` | перемещение между окнами

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB