📜 ⬆️ ⬇️

Creating a Debian package from scratch

Creating a Debian package from scratch is a kind of magical process. You could start googling with the query “Creating a Debian Package from Scratch” and get a lot of results, none of which would be what you need. You will undoubtedly have a great overview of the commands that are used in Debian and, if you dig deep enough, you can still find a couple of commands that will help you create a basic Debian package, but cannot explain what is happening. You can get more detailed information about what is “happening”, in this post we will try to partially touch on this.



First, you need to start by installing some dependencies. All of this manual was made based on Ubuntu 14.04, but is suitable for most Debian based operating systems. Run the following command to get started.
')
sudo apt-get install build-essential dh-make 

Next, we will need to create a package in which we will place all the components. In this case, the package will be called “mylittledeb”. To install the package, use the following commands:

 mkdir mylittledeb touch mylittledeb/Makefile touch mylittledeb/hello.c 

The content of hello.c should contain the classic “Hello, World”.

 #include <stdio.h> int main() { printf(“Hello, World\n”); return 0; } 

Makefile should have the following content. Information for someone who is not familiar with the Make-files - you need to use "_", and not a space or later when you run some commands, you risk getting errors. Also note that the cleaning of the target element is set to ||true after removing the binary file. We will use the indicated mismatch and other elements of Debian later by running make clean before creating it.

 all: gcc hello.c -o hello clean: rm hello || true 

At this point, you have a Debian package created that will allow users to type "Hello, World". This is not the most interesting part, but further will be more. At this point, make sure that running make makes a binary hello call and starts the binary "Hello, World" outputs. If this did not happen, it means that something went wrong and this must be corrected in order to move on.

Finally, we can begin to actually create the package! To initialize the Debian package, we will use the handy dh_make program we installed earlier. When executing the next command with entering the same settings as below, you should receive an error, but this is a planned error. In this case, it is important to understand what dh_make is and how to solve other problems that you are likely to encounter later when working with more advanced packages.

 dh_make -p mylittledeb_0.0.1 Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch? [s/i/m/l/k/n] s Maintainer name : root Email-Address : root@unknown Date : Sun, 10 Apr 2016 14:38:32 -0400 Package Name : mylittledeb Version : 0.0.1 License : blank Type of Package : Single Hit <enter> to confirm: Could not find mylittledeb_0.0.1.orig.tar.xz Either specify an alternate file to use with -f, or add --createorig to create one. 

We received an error message. Now consider a few things that concern this error. First, what is the orig.tar.xz file. Second, why was the -p flag used? Let's start with a simple question. The -p flag is used because dh_make looks at the name of the directory you are currently in to find out the package name and version. Many may agree that it is foolish to call the directory in this way, so the -p flag when you first run dh_make passes data in the form of <package name> _ <version>.

Now let's find out what is the orig.tar.xz file. The official documentation says that this is just a source code tarball, which in our case is just the current state of the directory. However, there may be something special about this orig.tar.xz file. So let's see how it is created. Running the following command will allow you to demolish the source code for dh-make. You can do this in tmp, since you will need to clear all the files if you do this in your mylittledeb package.

 apt-get source dh_make 

Now that we have the source code, let's see what happens. Opening the dh_make script can be found inside the Perl file. When searching for orig.tar.xz with Vim we come to the next line.

 system('tar', 'cfJ', “../$package_name\_$version.orig.tar.xz”, “.”); 

This is just an old archive tar file. However, you should have some understanding that all these magic Debian scripts are made in case everything goes wrong. Now let's go back to our mylittledeb folder and run the following:

 dh_make -p mylittledeb_0.0.1 --createorig 

You should now see the DEBiAN folder in your mylittledeb folder with the following contents:

 changelog compat control copyright docs init.d.ex manpage.1.ex manpage.sgml.ex manpage.xml.ex menu.ex mylittledeb.cron.d.ex mylittledeb.default.ex mylittledeb.doc-base.EX postinst.ex postrm.ex preinst.ex prerm.ex README.Debian README.source rules source watch.ex 

The .ex and .EX files are examples of files. Most of them have no need.

changelog - this file manages your version of the package, and also briefly explains what has changed since the last update. Here is what the main file should look like.

 mylittledeb (0.0.1–1) unstable; urgency=low * Initial release (Closes: #nnnn) <nnnn -    ITP> — root <root@unknown> Sun, 10 Apr 2016 15:00:11 -0400 

'mylittledeb' will contain in the title '0.0.1' this is the version of the package and the '1' at the end is the version of Debian. An unstable distribution for which the Debian package is targeted and migrated to various distributions is made outside of this process. In this case, we will simply use trusty, since all of this is built on Ubuntu 14.04. After you've all done it looks something like this:

 mylittledeb (0.0.1–1) trusty; urgency=low * Intial package release — root <root@unknown> Sun, 10 Apr 2016 15:00:11 -0400 

The last line should contain the name associated with the GPG key if you want to sign your packages. But we still get to the package signature. At the moment you can ignore this item.

compat is a magic file, and you should always use the number 9. This is just about the only information you can find on it. Why exactly 9? Well, it is used by all the tools in the debhelper package, this will ensure that your Debian file is compatible.

control - the control file contains the version, independent information about your package that people will see when executing 'apt-cache show mylittledeb'. This is all pretty well explained on the Debian wiki . Your package should look like this.

 Source: mylittledeb Section: devel Priority: optional Maintainer: root <root@unknown> Build-Depends: debhelper (>= 8.0.0) Standards-Version: 3.9.4 #Vcs-Git: git://git.debian.org/collab-maint/mylittledeb.git #Vcs-Browser: http://git.debian.org/?p=collab-maint/mylittledeb.git;a=summary Package: mylittledeb Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: An example debian package that says “Hello, World” 

You need to understand that the assembly of dependencies must be built correctly, as it includes all the dependencies for your package. They should not be added to Depends , which only includes dependencies that run your program. It is important to note here that {shlibs: Depends} and {misc: Depends} are two magic lines called by the dh_shlibdeps command. This command is useful for determining the dependencies, your binary needs, which are not immediately obvious.

copyright is the most obvious of the files, and if you are interested in releasing the package to the public, it simply must contain the file.

docs - this file can list the names of all the files that you would like to see included in the kit.

rules is a Debian rules file, contains all the information about creating your package and is a special version of the Makefile. The file contains additional targets that are used in creating Debian files. By default, this is a very simple file that simply runs the basic commands. However, if you need to redefine something, for example, how your directory will be cleaned before building, you should do something like this.

 #!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 override_dh_auto_clean: rm /tmp/random.file %: dh $@ 

All available overrides are listed in this wiki article , as well as a more detailed description of the rules file. By default, all debhelper tools use this file in this way, for example, if we want to clear a directory, this must be done before creating a new package, then the following command 'dh clean' is executed. This command in turn calls dh_testdir, dh_auto_clean, and dh_clean, which in turn invokes some perl scripts.

You do not need to edit this file at this time, but remember that you can customize the functionality later if you need it when you make your own Debian package.

source / format - this file seems pretty simple. At the moment you can leave it as is. Just know that this is a compiling format, a specific way of applying patches to the ascending tarball that we created earlier.

* .install- this file is not created automatically, so you will need to make a file named mylittledeb.install. Any file that was added with the installation will be used to install the binary file. The file or directory located in the system is used when installing the package. Since we have a “hello world” binary, we will have to put it in the user system. The following file will put our “hello world” binary file in the user directory / usr / bin.

 hello /usr/bin 

The rest of the files ending in .ex and .ex contain descriptions of what the various files do. It is better to save them, of course, but nothing terrible will happen from removal.

Now the easy part. Run the following command.

 dpkg-buildpackage 

If you uncomment export DH_VERBOSE=1 you can see all the commands that are currently being executed. You can redefine all these commands, so if you have a problem with your own package, you can determine its cause.

Here is the output of the above command:

 dpkg-buildpackage: source package mylittledeb dpkg-buildpackage: source version 0.0.1-1 dpkg-buildpackage: source distribution trusty dpkg-buildpackage: source changed by root <root@unknown> dpkg-buildpackage: host architecture amd64 dpkg-source --before-build mylittledeb debian/rules clean dh clean dh_testdir dh_auto_clean make -j1 clean make[1]: Entering directory `/root/mylittledeb' rm hello || true rm: cannot remove 'hello': No such file or directory make[1]: Leaving directory `/root/mylittledeb' dh_clean rm -f debian/mylittledeb.substvars rm -f debian/mylittledeb.*.debhelper rm -rf debian/mylittledeb/ rm -f debian/*.debhelper.log rm -f debian/files find . \( \( -type f -a \ \( -name '#*#' -o -name '.*~' -o -name '*~' -o -name DEADJOE \ -o -name '*.orig' -o -name '*.rej' -o -name '*.bak' \ -o -name '.*.orig' -o -name .*.rej -o -name '.SUMS' \ -o -name TAGS -o \( -path '*/.deps/*' -a -name '*.P' \) \ \) -exec rm -f {} + \) -o \ \( -type d -a -name autom4te.cache -prune -exec rm -rf {} + \) \) rm -f *-stamp dpkg-source -b mylittledeb dpkg-source: info: using source format `3.0 (quilt)' dpkg-source: info: building mylittledeb using existing ./mylittledeb_0.0.1.orig.tar.xz dpkg-source: info: building mylittledeb in mylittledeb_0.0.1-1.debian.tar.gz dpkg-source: info: building mylittledeb in mylittledeb_0.0.1-1.dsc debian/rules build dh build dh_testdir dh_auto_configure dh_auto_build make -j1 make[1]: Entering directory `/root/mylittledeb' gcc hello.c -o hello make[1]: Leaving directory `/root/mylittledeb' dh_auto_test debian/rules binary dh binary dh_testroot dh_prep rm -f debian/mylittledeb.substvars rm -f debian/mylittledeb.*.debhelper rm -rf debian/mylittledeb/ dh_auto_install install -d debian/mylittledeb dh_install install -d debian/mylittledeb//usr/bin cp -a ./hello debian/mylittledeb//usr/bin/ dh_installdocs install -g 0 -o 0 -d debian/mylittledeb/usr/share/doc/mylittledeb chown -R 0:0 debian/mylittledeb/usr/share/doc chmod -R go=rX debian/mylittledeb/usr/share/doc chmod -R u\+rw debian/mylittledeb/usr/share/doc install -g 0 -o 0 -m 644 -p debian/README.Debian debian/mylittledeb/usr/share/doc/mylittledeb/README.Debian install -g 0 -o 0 -m 644 -p debian/copyright debian/mylittledeb/usr/share/doc/mylittledeb/copyright dh_installchangelogs install -o 0 -g 0 -p -m644 debian/changelog debian/mylittledeb/usr/share/doc/mylittledeb/changelog.Debian dh_perl dh_link dh_compress cd debian/mylittledeb chmod ax usr/share/doc/mylittledeb/changelog.Debian gzip -9nf usr/share/doc/mylittledeb/changelog.Debian cd '/root/mylittledeb' dh_fixperms find debian/mylittledeb -print0 2>/dev/null | xargs -0r chown --no-dereference 0:0 find debian/mylittledeb ! -type l -print0 2>/dev/null | xargs -0r chmod go=rX,u+rw,as find debian/mylittledeb/usr/share/doc -type f ! -regex 'debian/mylittledeb/usr/share/doc/[^/]*/examples/.*' -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb/usr/share/doc -type d -print0 2>/dev/null | xargs -0r chmod 755 find debian/mylittledeb/usr/share/man debian/mylittledeb/usr/man/ debian/mylittledeb/usr/X11*/man/ -type f -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb -perm -5 -type f \( -name '*.so.*' -or -name '*.so' -or -name '*.la' -or -name '*.a' \) -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb/usr/include -type f -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb/usr/share/applications -type f -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb -perm -5 -type f \( -name '*.cmxs' \) -print0 2>/dev/null | xargs -0r chmod 644 find debian/mylittledeb/usr/lib/perl5 debian/mylittledeb/usr/share/perl5 -type f -perm -5 -name '*.pm' -print0 2>/dev/null | xargs -0r chmod aX find debian/mylittledeb/usr/bin -type f -print0 2>/dev/null | xargs -0r chmod a+x find debian/mylittledeb/usr/lib -type f -name '*.ali' -print0 2>/dev/null | xargs -0r chmod uga-w dh_strip strip --remove-section=.comment --remove-section=.note debian/mylittledeb/usr/bin/hello dh_makeshlibs rm -f debian/mylittledeb/DEBIAN/shlibs dh_shlibdeps install -o 0 -g 0 -d debian/mylittledeb/DEBIAN dpkg-shlibdeps -Tdebian/mylittledeb.substvars debian/mylittledeb/usr/bin/hello dh_installdeb dh_gencontrol echo misc:Depends= >> debian/mylittledeb.substvars dpkg-gencontrol -ldebian/changelog -Tdebian/mylittledeb.substvars -Pdebian/mylittledeb chmod 644 debian/mylittledeb/DEBIAN/control chown 0:0 debian/mylittledeb/DEBIAN/control dh_md5sums (cd debian/mylittledeb >/dev/null ; find . -type f ! -regex './DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums) >/dev/null chmod 644 debian/mylittledeb/DEBIAN/md5sums chown 0:0 debian/mylittledeb/DEBIAN/md5sums dh_builddeb dpkg-deb --build debian/mylittledeb .. dpkg-deb: building package `mylittledeb' in `../mylittledeb_0.0.1-1_amd64.deb'. signfile mylittledeb_0.0.1-1.dsc gpg: skipped "root <root@unknown>": secret key not available gpg: [stdin]: clearsign failed: secret key not available dpkg-genchanges >../mylittledeb_0.0.1-1_amd64.changes dpkg-genchanges: including full source code in upload dpkg-source --after-build mylittledeb dpkg-buildpackage: full upload (original source is included) dpkg-buildpackage: warning: failed to sign .dsc and .changes file 


Please note that it was not possible to sign the changes, because, as mentioned above, the GPG key was not created. This is not terrible, even though the package received such an error was actually created successfully.

Now you should see a set of new files in the same directory where your mylittledeb folder is located. We are interested in a file called "mylittledeb_0.0.1-1_amd64.deb", which can be installed using the command:

 sudo dpkg -i mylittledeb_0.0.1–1_amd64.deb 

You should now be able to run “Hello” from anywhere on your computer and get the text “Hello, World”.

Source: https://habr.com/ru/post/281983/


All Articles