Fedora copr Build System

Share on:

Fedora copr is an easy-to-use automatic build system providing an RPM repository for packages that you build. You can start with making your own repository in three simple steps: create a project, choose a system and architecture that you want to build for; start a new build by providing copr with a github repo where you have your .spec and other associated files; and then sit back and let copr do all the work!

In this post I will create an example repository to demonstrate how copr can integrate with github. This will create a simple package named fedora-copr-example. While it is an extremely simple C program, I have also included a patch to demonstrate how patch files can be used with the system. In addition, the sources (https://www.pbdigital.org/tarballs/fedora-copr-example-1.0.0.tar.gz) are external and will be downloaded by copr during its build process.

Signing Up for Fedora copr

If you wish to build your own packages via Fedora copr you will need to go to https://copr.fedorainfracloud.org/. In the upper right hand corner, and click "sign up" to start the registration. You will be redirected to https://admin.fedoraproject.org where you need to fill in the Fedora Account form. Once that is submitted you will receive an email with a password and verification link. By clicking on the link you can verify your account and set up a new password to complete the registration process.

Once that is done, head back to https://copr.fedorainfracloud.org/ to login with your new credentials.

If you wish to just follow along without any coding you can choose to install the fedora-copr-example package by installing the repo I have built, with the following commands.

# dnf copr enable pbdigital/blog 
# dnf install fedora-copr-example

Create a New copr Project

Once we are logged in to the copr Build System, our first task will be to create a new project. Very little is needed to be specified to get a project up and running.

For the simple example I am working on, I have first given my project the name of blog as it will be associated with tutorials that I post.

Project Information

Secondly, I have chosen 2 chroots, that are current Fedora distributions at the time of this post.

Build Options

Go ahead and click "Create" at the bottom of the page and your project will be setup.

Create Build

Create a New Build For the Project

From the project page, navigate to the build section and create a new build.

In this build, I have my .spec and .patch file available at https://github.com/pbdigital-dot-org/fedora-copr-example. Therefore we will choose the SCM option and insert the details of the github repository as demonstrated in the image below.

Provide Source

Now it is just a matter of clicking the "Build" button at the bottom of the page.

Start Build

Notice how the chroots we had chosen in our project show up here for our builds.

After your code has been built successfully, the builds section of your project page will appear as below.

Project Builds

That is all there is to a simple copr build. You will now be able to add this repository to Fedora and install your package you have just created.

Adding the Repository & Installing Packages

For the sake of not having to jump up the page, I repeat here the two commands to achieve this.

# dnf copr enable pbdigital/blog 
# dnf install fedora-copr-example

Once installed you can execute the file at /usr/bin/fedora-copr-example.

Source Code & Associated Files Used in this Build

I encourage you to look at the full .spec file for the build and what it entails. You can find the full fedora-copr-example.spec file by following the link. Here I will only cover 2 directives, Source0 & Patch0.

Defining the SPEC File to Download the Source

Below is the respective directive for the source files that are downloaded during the copr build.

Source0: https://www.pbdigital.org/tarballs/fedora-copr-example-1.0.0.tar.gz

This will be pulled in from copr when it starts its build.

Patching the source code

Below are the respective directives for the patch files in the fedora-copr-example.spec.

Patch0:  fedora-copr-example-1.0.0.patch
%patch0 -p1

Now is a good time to have a quick look at the source code and patch before I move onto how the patch command works with the source code.

First, the C program, fedora-copr-example.c.

#include <stdio.h>
int main()
    printf("%s", "Fedora Copr Example.\n");
    return 0;

and then next the patch file, fedora-copr-example-1.0.0.patch.

--- fedora-copr-example-1.0.0-orig/fedora-copr-example.c	2019-10-13 10:04:38.114081000 +0100
+++ fedora-copr-example-1.0.0/fedora-copr-example.c	2019-10-13 12:19:02.830494028 +0100
@@ -2,6 +2,6 @@
 int main()
-    printf("%s", "Fedora Copr Example.\n");
+    printf("%s", "PATCHED: Fedora Copr Example.\n");
     return 0;

If you are familiar with C and patch files, this is as simple as it gets.

Patching the Source Code with the -p1 Directive

At times it can be quite confusing where the patch program will find the actual patch file. We can use the -p flag to determine if we need to strip any directories in its search for the patch file.

First let's look at the directory structure of the sources when unpacked. This will make things more familiar when we are looking at the build output.

# tree fedora-copr-example-1.0.0/
├── fedora-copr-example.c
└── Makefile

Follows is output from the copr build at the moment it patches the source code. In this example patch finds the file it is looking for and all is well and will continue onto a successful build.

Finish: build setup for fedora-copr-example-1.0.0-1.fc30.src.rpm
Start: rpmbuild fedora-copr-example-1.0.0-1.fc30.src.rpm
Building target platforms: x86_64
Building for target x86_64
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.zxijsd
+ umask 022
+ cd /builddir/build/BUILD
+ cd /builddir/build/BUILD
+ rm -rf fedora-copr-example-1.0.0
+ /usr/bin/gzip -dc /builddir/build/SOURCES/fedora-copr-example-1.0.0.tar.gz
+ /usr/bin/tar -xof -
+ '[' 0 -ne 0 ']'
+ cd fedora-copr-example-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ echo 'Patch #0 (fedora-copr-example-1.0.0.patch):'
Patch #0 (fedora-copr-example-1.0.0.patch):
+ /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0
patching file fedora-copr-example.c
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.33wjh6
+ umask 022
+ cd /builddir/build/BUILD
+ cd fedora-copr-example-1.0.0
+ make -j2
gcc -g -c fedora-copr-example.c
gcc -Wall -o fedora-copr-example fedora-copr-example.o
+ exit 0

You will notice that copr cd's into the fedora-copr-example-1.0.0 directory. Looking at the patch file above, the diff statement includes the fedora-copr-example-1.0.0 directory, therefore this directory needs to be stripped out and why we have used the -p1 directive in the .spec file.

If we use -p0, the patched file will use fedora-copr-example-1.0.0/fedora-copr-example.c in its entirety. This is not desired as copr has already changed into the fedora-copr-example-1.0.0 directory, and will produce the following output causing the build to fail.

+ cd fedora-copr-example-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ echo 'Patch #0 (fedora-copr-example-1.0.0.patch):'
Patch #0 (fedora-copr-example-1.0.0.patch):
+ /usr/bin/patch --no-backup-if-mismatch -p0 --fuzz=0
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
|--- fedora-copr-example-1.0.0-orig/fedora-copr-example.c	2019-10-13 10:04:38.114081000 +0100
|+++ fedora-copr-example-1.0.0/fedora-copr-example.c	2019-10-13 12:19:02.830494028 +0100

For more information on this have a look at the GNU Documentaion on stripping directories in patch files.

Wrapping Up

You can check out new interesting projects that are using Fedora copr as their repository by keeping up to date with Fedora Magazine. The have regular spotlights on cool programs that they discover. My favorite has to be the Signal Desktop app that is provided by luminoso.

Happy Hacking!