dsp-site/wiki/Prog/Development/Программные проект и иерархия каталогов.adoc

239 lines
17 KiB
Plaintext
Raw Normal View History

2020-04-11 17:09:43 +00:00
= Программный проект и иерархия каталогов
:title-separator: {sp}|
:category: Программирование
:tags: Linux, программирование, cmake
Для операционных систем типа Linux принят стандарт
https://ru.wikipedia.org/wiki/FHS[FHS] («стандарт иерархии файловой
системы»), унифицирующий местонахождение файлов и каталогов с общим
назначением в файловой системе. Полная текущая версия стандарта
находится http://refspecs.linuxfoundation.org/fhs.shtml[здесь].
2020-04-13 07:00:26 +00:00
== Типы расположения проекта
2020-04-11 17:09:43 +00:00
В соответствии с данным стандартом, а также принятыми в ведущих
дистрибутивах правилами размещения исполняемых файлов в каталогах
пользователей, можно выделить следующие типы расположения:
* системная иерархия в каталоге `/usr` используется для установки
бинарных пакетов для данного дистрибутива;
* системная иерархия в каталоге `/usr/local` используется для установки
программного обеспечения системным администратором без использования
пакетов (не рекомендуется для использования из-за проблем поддержки
в актуальном состоянии);
* системная иерархия в каталоге `/opt` используется для установки
стороннего программного обеспечения. В рамках данной иерархии
предполагается, что каждый программный продукт располагается в
собственном каталоге. При таком типе сборки обычно используются
дополнительные методы (статическая компоновка, включение в состав
пакета своего набора динамических библиотек) для обеспечения работы
2020-04-11 20:09:16 +00:00
пакета в операционных системам с отличающимся составом библиотек
2020-04-11 17:09:43 +00:00
и другим циклом обновления;
* системная иерархия в домашнем каталоге пользователя не имеет
определённого стандарта, обычно производители дистрибутивов
предлагают использовать для исполняемых файлов каталоги
`$HOME/bin` или `$HOME/.local/bin`.
2020-04-11 20:09:16 +00:00
Система автоматизации сборки программного обеспечения `CMake` позволяет
организовать окружение подобное перечисленным выше. На этапе сборки
проекта можно создать структуру каталогов, которая будет отвечать
требованиям по логическому разделению файлов на исполняемые,
заголовочные, библиотеки, файлы настроек и т.д.
2020-04-11 17:09:43 +00:00
2020-04-13 07:00:26 +00:00
== Автоматическая адаптация к текущему окружению
2020-04-11 20:58:43 +00:00
Для обеспечения единообразной работы вне зависимости от варианта
иерархии каталогов, в которой находится исполняемый файл, можно
выполнять автоматическую настройку на работу в текущем окружении.
2020-04-13 06:08:14 +00:00
В библиотеке https://git.246060.ru/f1x1t/myxlib[myxlib] реализован
класс, который анализирует расположение и окружение исполняемого
файла и предоставляет методы для получения имён каталогов,
соответствующих текущему окружению. Названия методов и описания
2020-04-13 07:00:26 +00:00
возвращаемых значений приведены в таблице.
2020-04-13 06:08:14 +00:00
[cols="2m,4",options="header",]
|===
| Метод | Описание
2020-04-13 07:33:11 +00:00
| homeDirectory() | Полный путь к домашнему каталогу текущего пользователя
| tempDirectory() | Полный путь к каталогу с временными файлами
2020-04-13 06:08:14 +00:00
| userConfigDirectory() | Полный путь к пользовательскому каталогу с файлами настройки
2020-04-13 07:33:11 +00:00
| userConstDataDirectory() | Полный путь к пользовательскому каталогу с неизменяемыми файлами
| userVarDataDirectory() | Полный путь к пользовательскому каталогу с изменяемыми файлами
| userLogDirectory() | Полный путь к пользовательскому каталогу с журналами работы
2020-04-13 08:05:48 +00:00
| executableFilePath() | Полный путь к исполняемому файлу
2020-04-13 06:08:14 +00:00
| systemConfigDirectory() | Полный путь к системному каталогу с файлами настройки
| systemConstDataDirectory() | Полный путь к системному каталогу с неизменяемыми файлами
2020-04-13 08:05:48 +00:00
| systemVarDataDirectory() | Полный путь к системному каталогу с изменяемыми файлами
2020-04-13 06:08:14 +00:00
| systemLogDirectory() | Полный путь к системному каталогу с журналами работы
2020-04-13 08:05:48 +00:00
| executableFileDirectory() | Полный путь к каталогу с исполняемым файлом
2020-04-13 06:08:14 +00:00
| executableFileName() | Имя исполняемого файла
2020-04-13 08:05:48 +00:00
| configFilePath() | Полный путь к файлу настройки
| configFileName() | Имя файла настройки
| projectName() | Имя подкаталога для проекта
2020-04-13 06:08:14 +00:00
|===
2020-04-13 06:11:58 +00:00
Пример использования:
[source,cpp]
----
#include <myx/filesystem/paths.hpp>
namespace MF = myx::filesystem;
2020-04-13 07:00:26 +00:00
MF::Paths& paths = MF::Paths::instance();
paths.init( QStringLiteral( "project_name" ), QStringLiteral( "conf" ) );
qDebug() << paths.systemConstDataDirectory().path();
2020-04-13 06:11:58 +00:00
----
2020-04-13 07:00:26 +00:00
2020-04-13 07:33:11 +00:00
=== Правила выбора типа окружения
2020-04-13 07:00:26 +00:00
Класс `myx::filesystem::Paths` реализован в виде синглтона,
чтобы повторно не выполнять проверку окружения в разных частях программы.
Сначала определяются имена пользовательского и временного каталогов с
помощью вызовов функций https://doc.qt.io/qt-5/qdir.html#homePath[`QDir::homePath`]
и https://doc.qt.io/qt-5/qdir.html#tempPath[`QDir::tempPath`], затем
имена пользовательских каталогов для настроек, постоянных и изменяемых
данных и журналов. Эти значения не зависят от расположения исполняемого,
а определяются согласно значениям переменных окружения, либо значениям
принятыми в стандартах. Пример имён каталогов для пользователя `user`
и проекта `project` приведён в таблице.
2020-04-13 07:02:30 +00:00
[cols="3,3m,5m",options="header",]
2020-04-13 07:00:26 +00:00
|===
| Назначение каталога | Метод | Значение
| Домашний каталог | homeDirectory() | /home/user
| Временные файлы | tempDirectory() | /tmp
| Файлы настройки | userConfigDirectory() | /home/user/.config/project
| Неизменяемые файлы | userConstDataDirectory() | /home/user/.local/share/project/data
| Изменяемые файлы | userVarDataDirectory() | /home/user/.local/share/project/lib
| Журналы работы | userLogDirectory() | /home/user/.local/share/project/log
|===
2020-04-13 07:54:15 +00:00
==== Общая проверка
2020-04-13 07:33:11 +00:00
Для определения типа текущего окружения используется полный путь
к исполняемому файлу, если он находится в каталоге `bin`, то выполняются
2020-04-13 07:54:15 +00:00
проверки работы в одной из возможных вариантов иерархий,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
==== Проверка на работу в иерархии `/opt`
Если полный путь к исполняемому файлу начинается c `/opt` и
содержит в себе название текущего проекта, например
`/opt/org/project/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/opt` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
2020-04-13 08:31:26 +00:00
[cols="4,4m,6m",options="header",]
2020-04-13 08:19:37 +00:00
|===
2020-04-13 08:05:48 +00:00
| Назначение файла / каталога | Метод | Значение
2020-04-13 08:06:07 +00:00
| Исполняемый файл | executableFilePath() | /opt/org/project/bin/application
| Файлы настройки | systemConfigDirectory() | /opt/org/project/etc
| Неизменяемые файлы | systemConstDataDirectory() | /opt/org/project/files/data
| Изменяемые файлы | systemVarDataDirectory() | /opt/org/project/files/lib
| Журналы работы | systemLogDirectory() | /opt/org/project/files/log
2020-04-13 08:19:37 +00:00
|===
2020-04-13 07:54:15 +00:00
==== Проверка на работу в иерархии `/usr/local`
Если полный путь к исполняемому файлу начинается c `/usr/local`,
например `/usr/local/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/usr/local` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
2020-04-13 08:31:26 +00:00
[cols="4,4m,5m",options="header",]
2020-04-13 08:19:37 +00:00
|===
2020-04-13 08:05:48 +00:00
| Назначение файла / каталога | Метод | Значение
2020-04-13 08:06:07 +00:00
| Исполняемый файл | executableFilePath() | /usr/local/bin/application
| Файлы настройки | systemConfigDirectory() | /usr/local/etc/project
| Неизменяемые файлы | systemConstDataDirectory() | /usr/local/share/project
| Изменяемые файлы | systemVarDataDirectory() | /var/lib/project
| Журналы работы | systemLogDirectory() | /var/log/project
2020-04-13 08:19:37 +00:00
|===
2020-04-13 07:54:15 +00:00
==== Проверка на работу в иерархии `/usr`
Если полный путь к исполняемому файлу начинается c `/usr`,
например `/usr/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/usr` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
2020-04-13 08:31:26 +00:00
[cols="4,4m,5m",options="header",]
2020-04-13 08:19:37 +00:00
|===
2020-04-13 08:05:48 +00:00
| Назначение файла / каталога | Метод | Значение
2020-04-13 08:06:07 +00:00
| Исполняемый файл | executableFilePath() | /usr/bin/application
| Файлы настройки | systemConfigDirectory() | /etc/project
| Неизменяемые файлы | systemConstDataDirectory() | /usr/share/project
| Изменяемые файлы | systemVarDataDirectory() | /var/lib/project
| Журналы работы | systemLogDirectory() | /var/log/project
2020-04-13 08:19:37 +00:00
|===
==== Проверка на работу в домашнем каталоге
Если полный путь к исполняемому файлу начинается c `/home/user/bin` или
`/home/user/.local/bin`, например `/home/user/bin/application`, то выполняется
проверка на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в домашнем каталоге сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
2020-04-13 08:31:26 +00:00
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
[cols="4,4m,5m",options="header",]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /home/user/bin/application
| Файлы настройки | systemConfigDirectory() | /home/user/.config/project
| Неизменяемые файлы | systemConstDataDirectory() | /home/user/.local/share/project/data
| Изменяемые файлы | systemVarDataDirectory() | /home/user/.local/share/project/lib
| Журналы работы | systemLogDirectory() | /home/user/.local/share/project/log
|===
==== Проверка на работу в окружении для разработки
Если исполняемый файл находится в каталоге `bin` и при этом окружение не совпадает
ни с одним из перечисленных выше, то делается предположение, что исполняемый файл
запускается из окружения, сформированного
или
`/home/user/.local/bin`, например `/home/user/bin/application`, то выполняется
проверка на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в домашнем каталоге сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
2020-04-13 08:19:37 +00:00
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
2020-04-13 08:25:28 +00:00
[cols="3,4m,5m",options="header",]
2020-04-13 08:19:37 +00:00
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /home/user/bin/application
| Файлы настройки | systemConfigDirectory() | /home/user/.config/project
| Неизменяемые файлы | systemConstDataDirectory() | /home/user/.local/share/project/data
| Изменяемые файлы | systemVarDataDirectory() | /home/user/.local/share/project/lib
| Журналы работы | systemLogDirectory() | /home/user/.local/share/project/log
|===
2020-04-13 07:54:15 +00:00
2020-04-13 07:33:11 +00:00