From Fedora Project Wiki

(Adding some sections)
(More things about patches)
Line 12: Line 12:


You will also need to configure Kerberos authentication in order to use <code>fedpkg</code>.  See [[Infrastructure/Kerberos]] for details.
You will also need to configure Kerberos authentication in order to use <code>fedpkg</code>.  See [[Infrastructure/Kerberos]] for details.
I personally like to use the following bash function when building the package.  It guarantees that the full build will happen at the current directory, instead of <code>~/rpmbuild/</code> or something else.
<pre>
# Function for building an RPM at $PWD.
function rpmbuildlocal
{
  MAKEFLAGS= rpmbuild \
    --define "_topdir $PWD" \
    --define "_builddir $PWD" \
    --define "_rpmdir $PWD" \
    --define "_sourcedir $PWD" \
    --define "_specdir $PWD" \
    --define "_srcrpmdir $PWD" \
    --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
    "$@"; rmdir &>/dev/null BUILDROOT;
}
</pre>


== Cloning the repository ==
== Cloning the repository ==
Line 42: Line 60:
fedpkg sources
fedpkg sources
</pre>
</pre>
== Satisfying the build-dependencies ==
You can do:
<pre>
rpmbuildlocal -bs --with testsuite gdb.spec
sudo dnf builddep gdb-*.src.rpm
</pre>
Notice the <code>--with testsuite</code> option.  This will generate a source RPM whose list of dependencies includes the packages needed to run GDB's testsuite.
== Dealing with patches ==
Because we have several local patches, it is necessary to understand how to handle them in a way that doesn't cause too many conflicts.
To help with the job, Fedora GDB carries two shell scripts that automate the process of applying patches to and extracting patches from a tree.
=== Applying patches to a repository ===
You should use the script called <code>generate-git-repo-from-patches.sh</code> for this task.  It takes one argument, <code>REPOSITORY</code>, which points to a cloned upstream GDB git repo.  All it does is enter the directory, checkout a specific commit (the one pointed by the file <code>_git_upstream_commit</code>, itearate over the list of local patches and apply them sequentially.
If you already have a cloned upstream GDB repository, you can do:
<pre>
git clone git://sourceware.org/git/binutils-gdb.git --reference=/path/to/local/gdb/repo new-fedora-release
./generate-git-repo-from-patches.sh binutils-gdb
</pre>
I like calling the cloned directory <code>new-fedora-release</code>, but that's just a personal preference.
=== Extracting patches from a repository ===
You should use the script called <code>generate-patches-from-git-repo.sh</code> for this task.  It takes two arguments:
* <code>REPOSITORY</code>, the directory where you cloned the upstream GDB git repository (and where the local patches are applied).
* <code>COMMIT_OR_TAG_OR_BRANCH</code>, which is the commit/tag/branch against which the rebase was performed.  If no rebase was performed (e.g., if you just backported a patch a placed it on top of the others), you don't need to provide this argument.
=== Mandatory patch header ===
When extracting the patches, the script automatically generates the <code>*.patch</code> files, along with other two files: <code>_gdb.spec.patch.include</code> (which contains the <code>%patch</code> directives), and <code>_gdb.spec.Patch.include</code> (which contains the <code>Patch:</code> directives).
In order to generate the patches, the script must know how to name them.  The script must also know if there should be any comment on top of the <code>Patch:</code> directive for each patch.  The way we do that is by having two mandatory headers in the commit message:
* The '''first line (subject) of the commit message must''' be the patch filename.  The convention is to use <code>gdb-rhbzNNNNNN-short-desc.patch</code>.
* The '''first line(s) of the commit body''' can be the comment that will be placed on top of the <code>Patch:</code> directive.  It '''must''' start with two semicolons <code>;;</code>.
An example of a proper commit message would be:
<pre>
gdb-rhbz1553104-s390x-arch12-test.patch
;; [s390x] Backport arch12 instructions decoding (RH BZ 1553104).
;; =fedoratest
</pre>
== Preparing a new release ==
There are a few ways to prepare a new release, depending on what you want to do.
=== Case 1: Backport an upstream fix (no rebase) ===
If you just want to backport an upstream fix, but don't want to rebase the code, then you would:
<pre>
cd new-fedora-release
git fetch origin
git cherry-pick --no-commit 0a1b2c3d
</pre>
I like using <code>--no-commit</code> because it lets me revert the changes made to the <code>ChangeLog</code> files.  They are not needed (because they are already listed in the commit message), and can easily cause conflicts in the future.  You can do that by using the <code>git checkout</code> command, by the way.
Once everything is fine, you can commit the changes:
<pre>
git commit
</pre>
It is really important to

Revision as of 15:05, 1 April 2020

Introduction

This is a guide for the Fedora GDB package maintainer. The reason we have a specific document for the package (which builds on top of the existing official Fedora packaging documentation) is because we carry several local patches along with the project's official codebase.

Getting ready

You will need to install some packages before we start.

dnf install fedpkg rpm-build

You will also need to configure Kerberos authentication in order to use fedpkg. See Infrastructure/Kerberos for details.

I personally like to use the following bash function when building the package. It guarantees that the full build will happen at the current directory, instead of ~/rpmbuild/ or something else.

# Function for building an RPM at $PWD.
function rpmbuildlocal
{
  MAKEFLAGS= rpmbuild \
    --define "_topdir $PWD" \
    --define "_builddir $PWD" \
    --define "_rpmdir $PWD" \
    --define "_sourcedir $PWD" \
    --define "_specdir $PWD" \
    --define "_srcrpmdir $PWD" \
    --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
    "$@"; rmdir &>/dev/null BUILDROOT;
}

Cloning the repository

The Fedora GDB repository is located at [1]. You can clone it by doing:

fedpkg clone gdb

After this, you will see a gdb directory, where you can use git switch to switch to a specific release branch.

If you are like me and prefers to have each branch in its own directory, you can do that using:

fedpkg clone --branches gdb

You should see several directories named like f28/, f29/, f30/, etc. If you choose this approach, you will have to manually clone every time Fedora branches. For example, supposing that Fedora branches f30, you will have to do:

fedpkg clone --branch f30 gdb && mv gdb f30

Downloading the sources

Fedora stores the source files (i.e., the tarballs) for the package in a separate cache. This means that when you clone the repository, you will not automatically obtain the tarballs necessary to build the package. In order to do that, you should execute:

fedpkg sources

Satisfying the build-dependencies

You can do:

rpmbuildlocal -bs --with testsuite gdb.spec
sudo dnf builddep gdb-*.src.rpm

Notice the --with testsuite option. This will generate a source RPM whose list of dependencies includes the packages needed to run GDB's testsuite.

Dealing with patches

Because we have several local patches, it is necessary to understand how to handle them in a way that doesn't cause too many conflicts.

To help with the job, Fedora GDB carries two shell scripts that automate the process of applying patches to and extracting patches from a tree.

Applying patches to a repository

You should use the script called generate-git-repo-from-patches.sh for this task. It takes one argument, REPOSITORY, which points to a cloned upstream GDB git repo. All it does is enter the directory, checkout a specific commit (the one pointed by the file _git_upstream_commit, itearate over the list of local patches and apply them sequentially.

If you already have a cloned upstream GDB repository, you can do:

git clone git://sourceware.org/git/binutils-gdb.git --reference=/path/to/local/gdb/repo new-fedora-release
./generate-git-repo-from-patches.sh binutils-gdb

I like calling the cloned directory new-fedora-release, but that's just a personal preference.

Extracting patches from a repository

You should use the script called generate-patches-from-git-repo.sh for this task. It takes two arguments:

  • REPOSITORY, the directory where you cloned the upstream GDB git repository (and where the local patches are applied).
  • COMMIT_OR_TAG_OR_BRANCH, which is the commit/tag/branch against which the rebase was performed. If no rebase was performed (e.g., if you just backported a patch a placed it on top of the others), you don't need to provide this argument.

Mandatory patch header

When extracting the patches, the script automatically generates the *.patch files, along with other two files: _gdb.spec.patch.include (which contains the %patch directives), and _gdb.spec.Patch.include (which contains the Patch: directives).

In order to generate the patches, the script must know how to name them. The script must also know if there should be any comment on top of the Patch: directive for each patch. The way we do that is by having two mandatory headers in the commit message:

  • The first line (subject) of the commit message must be the patch filename. The convention is to use gdb-rhbzNNNNNN-short-desc.patch.
  • The first line(s) of the commit body can be the comment that will be placed on top of the Patch: directive. It must start with two semicolons ;;.

An example of a proper commit message would be:

gdb-rhbz1553104-s390x-arch12-test.patch

;; [s390x] Backport arch12 instructions decoding (RH BZ 1553104).
;; =fedoratest

Preparing a new release

There are a few ways to prepare a new release, depending on what you want to do.

Case 1: Backport an upstream fix (no rebase)

If you just want to backport an upstream fix, but don't want to rebase the code, then you would:

cd new-fedora-release
git fetch origin
git cherry-pick --no-commit 0a1b2c3d

I like using --no-commit because it lets me revert the changes made to the ChangeLog files. They are not needed (because they are already listed in the commit message), and can easily cause conflicts in the future. You can do that by using the git checkout command, by the way.

Once everything is fine, you can commit the changes:

git commit

It is really important to