Sources

Создание дистрибутивов связано с использованием большого количества исходных пакетов сторонних производителей. Хранятся исходные пакеты, в глобальной сети, на множестве ресурсов, таких, например, как sourceforge.net, github.com и savannah.gnu.org. Большие проекты, такие как GNU, X.org, KDE, Gnome и другие, имеют собственные сетевые ресурсы.

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

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

На нашем сервере организовано зеркалирование ключевых Git-репозиториев и хранение архивов исходных пакетов для того, чтобы ускорить загрузку исходных пакетов перед началом сборки Radix.Linux платформы. Зеркала Git-репозиториев расположены по адресу https://cgit.radix.pro.

Архивы сторонних производителей, необходимых для сборки платформы, можно найти на FTP-сервере в каталоге https://ftp.radix.pro/sources.

Фактически, каталог https://ftp.radix.pro/sources представляет собой клон репозитория https://cgit.radix.pro/radix/sources.git, который обновляется по мере необходимости и доступен для клонирования посредством, команды

$ git clone https://git.radix.pro/radix/sources.git

Создание зеркалированного хранения исходных пакетов позволяет весьма существенно сократить время загрузки исходных пакетов перед сборкой. Например, если FTP-сервер находится в собственной локальной сети, то загрузка всех, необходимых платформе, исходных архивов занимает около пяти минут. С другой стороны, если создать клон репозитория https://cgit.radix.pro/radix/sources.git и попытаться выполнить загрузку пакетов из глобальной сети путем выполнения команд

$ git clone https://cgit.radix.pro/sources.git sources
$ cd sources
$ make

то такая загрузка будет длиться несколько суток.

Система сборки по умолчанию использует FTP-сервер https://ftp.radix.pro. Однако пользователи могут самостоятельно организовать зеркалированное хранение исходных пакетов на собственном сервере и изменить значение переменной DOWNLOAD_SERVER в файле 'build-system/constants.mk'.

Toolchains

Система сборки поддерживаемых toolchain-ов хранится в SVN-репозитории https://csvn.radix.pro/radix/toolchains и доступна для клонирования посредством команды

$ svn co svn://svn.radix.pro/radix/toolchains/trunk

Релизы, фиксированные тегами, можно получить на нашем FTP-сервере https://ftp.radix.pro/radix/toolchains/x86_64 в каталоге, соответствующем номеру версии.

В разделе Build System in Practice, приведен пример загрузки toolchain-а для платы Firefly-RK3288.

Build System

Репозиторий системы сборки расположен по адресу https://csvn.radix.pro/radix/build-system.

Кроме того, исходные архивы можно загрузить с FTP-сервера по адресу https://ftp.radix.pro/radix/build-system/releases.

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

$ svn co svn://svn.radix.pro/radix/build-system/tags/build-system-1.9.2 build-system

В разделе Build System in Practice, приведен пример загрузки архива системы сборки с FTP-сервера.

Git-mirror Creation

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

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

Итак, для создания Git-зеркала необходимо выполнить команду

$ git svn clone \
      --no-metadata           \
      --branches=/branches    \
      --tags=/tags            \
      --trunk=/trunk          \
      --preserve-empty-dirs   \
      --placeholder-filename=README \
      svn://svn.radix.pro/radix/build-system \
      -s build-system

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

$ cd build-system/.git/refs/remotes/origin/tags
$ cp build-system-?.?.? ../../../tags

Для приведения имен тегов к виду, который наиболее приемлем для системы версионного контроля Git, можно воспльзоваться следующим скриптом на языке Perl:

#!/usr/bin/perl

use FindBin;
use lib $FindBin::Bin;

use strict;
use warnings FATAL => 'all';

use IO::Handle;
use File::Basename;
use File::Copy qw(copy);

my $program = basename( $0 );

my $dirname = ".";

opendir( DIR, "$dirname" ) or
    die( "Copy Tags: Could not open directory: $dirname: $!" );
  my @tags = grep { -f "$_" } readdir( DIR );
closedir DIR;

foreach my $tag (@tags)
{
  if( $tag =~ /^build\-system\-([0-9]+\.[0-9]+\.[0-9]+)/ )
  {
    my $target = $1;
    print "Copy: $tag --> ../../../$target\n";
    copy( $tag, "../../../tags/$target" );
  }

  if( ( $tag !~ /^build\-system\-([0-9]+\.[0-9]+\.[0-9]+)/ ) and ( $tag !~ /$program/) )
  {
    print "Bad tag name: $tag -- Have to be removed.\n";
    unlink $tag;
  }
}

Данный скрипт копирует теги в файлы, имена которых равны цифровой части имени исходного тега.

Для того чтобы воспользоваться данным скриптом, его надо скопировать в каталог build-system/.git/refs/remotes/origin/tags:

$ cp copy-tags.pl  build-system/.git/refs/remotes/origin/tags/
$ cd build-system/.git/refs/remotes/origin/tags/
$ ./copy-tags.pl
$ rm -f ./copy-tags.pl

Кроме того, после создания зеркала, желательно удалить ветки, которые в основном SVN репозитории расположены в каталоге deadwood, поскольку они больше не понадобятся. В понимании Git, ветка – это всего лишь файл с hash-суммой, расположенный в соответствующем каталоге, поэтому удаление веток может быть осуществлено следующим образом.

$ cd build-system/.git/refs/remotes/origin
$ rm -f BS-external deadwood genext4fs

В каталоге build-system/.git/logs/refs/remotes/origin можно так же удалить ненужные ветки и неликвидные теги.

Теперь в репозитории можно оперировать ветками,

$ git branch -a
* master
  remotes/origin/build-system-1.1.x
  remotes/origin/build-system-1.2.x
  remotes/origin/tags/build-system-0.0.1
  remotes/origin/tags/build-system-1.0.0

      .
      .
      .

  remotes/origin/tags/build-system-1.1.5
  remotes/origin/tags/build-system-1.1.6
  remotes/origin/tags/build-system-1.1.7
  remotes/origin/trunk

а также ссылаться на теги

$ git tag
0.0.1
1.0.0

   .
   .
   .

1.1.5
1.1.6
1.1.7

$

Заметим здесь, что SVN-теги мы оставили в каталоге build-system/.git/refs/remotes/origin/tags и они представлены как обычные ветки исходного SVN-репозитория.

Для того, чтобы отслеживать только необходимые нам ветки оригинального SVN репозитория можно отредактировать файл build-system/.git/config, который в настоящий момент выглядит так, как показано на следующем листинге.

[core]
       repositoryformatversion = 0
       filemode = true
       bare = false
       logallrefupdates = true
[svn-remote "svn"]
       noMetadata = 1
       preserve-empty-dirs = true
       placeholder-filename = README
       url = svn://radix.pro/build-system
       fetch = trunk:refs/remotes/origin/trunk
       branches = branches/*:refs/remotes/origin/*
       tags = tags/*:refs/remotes/origin/tags/*
       added-placeholder = doc/README
       added-placeholder = branches/BS-external/3pp/sources/packages/dialog/patches/README
       added-placeholder = pkgtool/README
       added-placeholder = 3pp/README
       added-placeholder = branches/deadwood/genext4fs/3pp/sources/packages/dialog/patches/README
       added-placeholder = branches/deadwood/BS-external/3pp/sources/packages/dialog/patches/README

Удалим ненужные строки, касающиеся веток, которые нам не нужны:

       added-placeholder = branches/BS-external/3pp/sources/packages/dialog/patches/README
       added-placeholder = branches/deadwood/genext4fs/3pp/sources/packages/dialog/patches/README
       added-placeholder = branches/deadwood/BS-external/3pp/sources/packages/dialog/patches/README

и закомментируем строки, обеспечивающие обновление транка и веток репозитория:

#      fetch = trunk:refs/remotes/origin/trunk
#      branches = branches/*:refs/remotes/origin/*

оставив только обновление тегов:

       tags = tags/*:refs/remotes/origin/tags/*

Таким образом мы получим следующее содержание файла build-system/.git/config.

[core]
       repositoryformatversion = 0
       filemode = true
       bare = false
       logallrefupdates = true
[svn-remote "svn"]
       noMetadata = 1
       preserve-empty-dirs = true
       placeholder-filename = README
       url = svn://radix.pro/build-system
#      fetch = trunk:refs/remotes/origin/trunk
#      branches = branches/*:refs/remotes/origin/*
       tags = tags/*:refs/remotes/origin/tags/*
       added-placeholder = doc/README
       added-placeholder = pkgtool/README
       added-placeholder = 3pp/README

Добавим теперь только интересующие нас ветки:

[svn-remote "trunk"]
       url = svn://radix.pro/build-system/trunk
       fetch = :refs/remotes/origin/trunk
[svn-remote "build-system-1.1.x"]
       url = svn://radix.pro/build-system/branches/build-system-1.1.x
       fetch = :refs/remotes/origin/build-system-1.1.x
[svn-remote "build-system-1.2.x"]
       url = svn://radix.pro/build-system/branches/build-system-1.2.x
       fetch = :refs/remotes/origin/build-system-1.2.x

Заметим, что при необходимости в каталоге refs/remotes/origin можно поддерживать структуру каталогов соответствующую возможностям SVN, например, следующим способом:

[svn-remote "build-system-1.0.x"]
       url = svn://radix.pro/build-system/branches/deadwood/build-system-1.0.x
       fetch = :refs/remotes/origin/deadwood/build-system-1.0.x

Итак, результирующий файл конфигурации Git репозитория будет выглядеть так:

[core]
       repositoryformatversion = 0
       filemode = true
       bare = false
       logallrefupdates = true
[svn-remote "svn"]
       noMetadata = 1
       preserve-empty-dirs = true
       placeholder-filename = README
       url = svn://radix.pro/build-system
       tags = tags/*:refs/remotes/origin/tags/*
       added-placeholder = doc/README
       added-placeholder = pkgtool/README
       added-placeholder = 3pp/README
[svn-remote "trunk"]
       url = svn://radix.pro/build-system/trunk
       fetch = :refs/remotes/origin/trunk
[svn-remote "build-system-1.1.x"]
       url = svn://radix.pro/build-system/branches/build-system-1.1.x
       fetch = :refs/remotes/origin/build-system-1.1.x
[svn-remote "build-system-1.2.x"]
       url = svn://radix.pro/build-system/branches/build-system-1.2.x
       fetch = :refs/remotes/origin/build-system-1.2.x

Добавление новых веток для отслеживания изменений в них возможно как путем непосредственного редактирования файла build-system/.git/config, так и с помощью команд Git. Например, для добавления ветки build-system/branches/build-system-1.3.x из основного SVN репозитория в Git репозиторий достаточно добавить в файл build-system/.git/config следующие строки:

[svn-remote "build-system-1.3.x"]
       url = svn://radix.pro/build-system/branches/build-system-1.3.x
       fetch = :refs/remotes/origin/build-system-1.3.x

или выполнить команды:

$ git config --add svn-remote.build-system-1.3.x.url \
                    svn://radix.pro/build-system/branches/build-system-1.3.x
$ git config --add svn-remote.build-system-1.3.x.fetch :refs/remotes/origin/build-system-1.3.x

Для работы с созданным нами Git репозиторием необходимо создать локальные ветки. Сделать это можно с помошью команд:

$ git checkout -b build-system-1.1.x origin/build-system-1.1.x
$ git checkout -b build-system-1.2.x origin/build-system-1.2.x

Для получения свежих изменений SVN репозитория системы сборки необходимо выполнить команду git-fetch, например, следующим образом.

$ cd build-system
$ git svn fetch -q --all

Чтобы обновить состояние локальных веток согласно поступившим изменениям из SVN репозитория надо воспользоваться командой git-merge:

$ git svn fetch -q --all

$ git checkout build-system-1.1.x
$ git merge origin/build-system-1.1.x

$ git checkout build-system-1.2.x
$ git merge origin/build-system-1.2.x

$ git checkout master
$ git merge origin/trunk

Если использовать созданный нами Git репозиторий для создания зеркала, представляющего собой, так называемый, bare-репозиторий содержащий только копии локальных веток, то все предыдущие действия можно оформить в виде отдельного скрипта, выполнение которого можно поручить cron-демону для периодического обновления нашего промежуточного зеркала. А bare-репозиторий создать с помощью команды:

$ git clone --mirror build-system build-system.git

После создания данного зеркала можно удалить ненужные ссылки на SVN ветки. Для этого достаточно удалить из файла build-system.git/packed-refs строки ссылающиеся на каталог remotes/origin:

93611bc9e765a5878795792e463302dad6addd2e refs/remotes/origin/build-system-1.1.x
1336179d6627d1492470b35c07054b8ad7c1cb99 refs/remotes/origin/build-system-1.2.x
bb06af52607d55098b1bded3b2fa6d88078d1ff8 refs/remotes/origin/tags/build-system-0.0.1
b60ca9986f939a14bc6575879d7dd2460a8edc58 refs/remotes/origin/tags/build-system-1.0.0

      .
      .
      .

3cb4bddcd0069da5c45391608cdcc035cf596ace refs/remotes/origin/tags/build-system-1.1.5
9f9981f58890a7a8d61131bc32e58bf6518ca155 refs/remotes/origin/tags/build-system-1.1.6
49c8ed507ed3421f85e922b67b167d804e370518 refs/remotes/origin/tags/build-system-1.1.7
eebc0d630b8b0859c33af6965468ce52900e3023 refs/remotes/origin/trunk

Таким образом, обновляя содержимое репозитория build-system.git через промежуточное звено (репозиторий build-system) можно либо организовать работу с использованием только локальных веток Git репозитория, либо вообще перейти на систему Git и отказаться от SVN сохранив историю разработки.

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