54

I want to create a DEB file manually. I would like to just provide a folder which contains data to install, and a script to be executed after installation.

Is this possible?

Mat
  • 52,586
daisy
  • 54,555
  • I've used the knowledge embedded in the answers below to implement a deb generator for the Guix tool; perhaps its source can be a useful reference; see: https://git.savannah.gnu.org/cgit/guix.git/tree/guix/scripts/pack.scm#n659. It's usable via the CLI like: guix pack --format=deb hello, where hello is the name of a Guix package to archive as a deb. – user30747 Jun 30 '21 at 15:24

9 Answers9

63

Making a source package

My recommendation is to make a source package. Install build-essential, debhelper, dh-make. Change to the directory where the files you want to install are (the directory name must be of the form $PACKAGE-$VERSION, e.g. myapp-4.2-1 for your first attempt at packaging Myapp V4.2), and run dh_make --createorig. Answer the questions. Debhelper will create the basic infrastructure needed to build a package by generating files in a subdirectory called debian, both some mandatory files and templates for optional files. You may need to modify some of these files:

  • Edit debian/rules to build what needs building and install the files in the right place. If you just need to copy some files and not to compile stuff, just edit the file debian/install to specify which files need to be installed where.
  • Edit debian/copyright to add license information about your package and information on where to get the latest version (if relevant).
  • Edit debian/changelog to remove the reference to an ITP (that's only relevant if you're working for the Debian project). Rename debian/postinst.ex to debian/postinst and add your post-installation commands there. If you later update your package, run debchange -i to add a changelog entry or edit the file in Emacs (with dpkg-dev-el installed).

Run dpkg-buildpackage -rfakeroot -us -uc to build the .deb package (remove -us -uc if you want to sign the package with your PGP key).

Making a binary package directly

If you decide to make a binary package directly without building it from a source package, which is not really easier because there aren't as many tools to facilitate the process, you'll need some basic familiarity with the format of deb packages. It is described in the Debian Policy Manual, in particular ch. 3 (format of binary packages), ch. 5 (control files), ch. 6 (installation scripts) and appendix B (binary package manipulation).

You make sure that your package installs the expected files /usr/share/doc/copyright (containing the license of the package contents, as well as where to find the latest version of the package) and /usr/share/doc/changelog.Debian.gz (containing the changelog of the deb package). You don't need these if you're only going to use the package in-house, but it's better to have them.

On Debian and derivatives

If you have the Debian tools available, use dpkg-deb to construct the package. In the directory containing the data to install, add a directory called DEBIAN at the top level, containing the control files and maintainer scripts.

$ ls mypackage-42
DEBIAN etc usr var
$ dpkg-deb -b mypackage-42

The hard way

If you don't have the Debian tools, build an archive of the files you want to package called data.tar.gz, a separate archive of the control files called control.tar.gz (no subdirectories), and a text file called debian-binary and containing the text 2.0.

cd mypackage-42
tar czf ../data.tar.gz [a-z]*
cd DEBIAN
tar czf ../../control.tar.gz *
cd ../..
echo 2.0 > debian-binary
ar r mypackage-42.deb debian-binary control.tar.gz data.tar.gz

You need at least a control file with the fields Package, Maintainer, Priority, Architecture, Installed-Size, Version, and any necessary dependency declaration.

The script to be executed after installation is called postinst. Be sure to make it executable. It goes alongside control.

Converting a binary package from a different format

If you already have a binary package from another distribution, you can use alien to convert it.

  • 1
    The answer presupposes the OP knows how to use emacs. Is emacs really necessary here? For editing changelogs, I think one can use dch -i. – Faheem Mitha Jan 31 '12 at 04:27
  • What is ar doing that tar is not? – mmstick Jun 20 '16 at 17:00
  • @mmstick It's a different format. I don't know why the designers of the deb format chose to use ar here. – Gilles 'SO- stop being evil' Jun 20 '16 at 17:06
  • changelog.Debian.gz may as much be changelog.gz. It just must be compressed with gzip --best or else Lintian will complain. – Hibou57 Sep 25 '17 at 04:04
  • About ar r mypackage-42.deb debian-binary control.tar.gz data.tar.gz it could be worth to stress the order is important: control must come before data. – Hibou57 Sep 25 '17 at 04:15
  • 1
    If you want to change the name and email that dh_make --createorig uses, you need to export DEBEMAIL="me@example.com" and export DEBFULLNAME="Firstname Lastname" beforehand. – Ryan May 28 '18 at 03:35
  • Thanks a lot for showing how to do this manually. The format as documented at https://manpages.debian.org/unstable/dpkg-dev/deb.5.en.html mentions that the ar archive should have a "magic value of !"; would you know how this can be added? – user30747 Jun 15 '21 at 03:42
  • 1
    @user30747 You don't need to add anything. That's just part of the ar format produced by ar from GNU binutils, which is what you'd normally have on Linux. I think this format is the same as BSD ar. If you're using a different OS it might have a different format, but GNU binutils are usually easy to install everywhere. And the tar format likewise has to be a format understood by GNU tar, but I think it can read all the classic tar formats. – Gilles 'SO- stop being evil' Jun 15 '21 at 08:28
  • +1 For the very important commentary: the control file should have no subdirectories. I was trying to create a .deb file with a control file with all files in the subdirectory control—What a waste of time! – loved.by.Jesus Jan 22 '23 at 02:27
11

First off you need to create a build folder and an archive of your files: tar czvf data.tar.gz files

Then in the build folder you must create a control file with some wanted informations:

 Package: xxxxxx
 Version: 0.0.1
 Section: user/hidden 
 Priority: optional
 Architecture: armel
 Installed-Size: `du -ks usr|cut -f 1`
 Maintainer: Your Name <xxx@xxx.xx>
 Description: This is optional, but creates warnings if left out

Then you can add independently preinst, postint, prerm and postrm shell scripts to control pre and post install and pre and post remove behaviour of the .deb file and then you can create the control archive with tar: tar czvf control.tar.gz control preinst postinst prerm postrm

Then you need a debian-binary file: echo 2.0 > debian-binary. In your build folder you should have now these files: debian-binary control.tar.gz and data.tar.gz.

Finally you need ar package to create the .deb file: ar -r xxx.deb debian-binary control.tar.gz data.tar.gz

Micromega
  • 4,211
  • 1
    About ar -r xxx.deb debian-binary control.tar.gz data.tar.gz it could be worth to stress the order is important: control must come before data. – Hibou57 Sep 25 '17 at 04:16
  • @Bytemain, the top voted answer looks indeed partially based on your text, but it adds details to it, and it's better readable. the sequence we can copy/paste makes it particularly more handsome. – mariotomo Mar 02 '18 at 19:50
3

I do a lot of packages, and to do a full one is not a trivial matter. On a positive note, files and scripts are much less work. You can create such a package, very simply, with a tool known as debreate.

Debreate is a really simple GUI, for just creating simple DEB packages. You can just specify which files, where they go, and if/what should execute on post/pre install/uninstall. I used to just do all my packages the standard way, but after I started using this tool, I will only go back when necessary.

Matija Nalis
  • 3,111
  • 1
  • 14
  • 27
J. M. Becker
  • 4,891
2

See the Debian Wiki on Packaging, maybe equivs (see link) already satisfies your requirements.

Wikipedia's page on the deb file format also includes many useful links.

sr_
  • 15,384
1

Ran into this with Zimbra 7 on Debian using its Ubuntu packages. (I'm stubborn, I like Debian > bUbuntu despite Zimbra releasing only for Ubuntu.) Not sure how I worked around this before, I'm certain I didn't have to do this when I installed this previously!

mkdir new
for i in *.deb
 do echo `date`: working on $i
 ar x $i
 cd control
 rm * 2> /dev/null
 tar -xzpvf ../control.tar.gz
 tr "_" "-" < control > control2
 mv -v control2 control
 tar -czpvf ../control.tar.gz .
 cd ..
 ar r new/$i debian-binary control.tar.gz data.tar.gz
done
rm -rf debian-binary control.tar.gz data.tar.gz control

All your new .deb files will be in new/.

Note: this was on squeeze - dpkg on wheezy has --force-bad-version now.

math
  • 311
1

For quick creating of packages you can user checkinstall program. It do a instalation of program, watch changes - and create a deb or rpm package of it.

undefine
  • 1,410
  • This sounds like a great option for tracking packages you have to install from source. Can you offer more details? E.g., in the course of installation you can change symlinks, delete files, edit config files, add daemons, etc ... to what extent doees checkinstall track and undo these changes? Can you easily modify its output to add prerm and postrm scripts? – AatG Jun 12 '15 at 23:10
  • look at https://wiki.debian.org/CheckInstall If you want to change things during install - easiest way is modify Makefile to change install section. prerm/postrm - i didn't find way to modify it. It's just for small programs to allow simple uninstall. – undefine Jun 14 '15 at 20:51
1

If you don't want to use official debian helpers, the termux-create-package python script can also be used to create binary deb files as per debian policies based on yaml/json manifest files and provides some utility config parameters as well.

https://github.com/termux/termux-create-package

0

You can use Alien to convert to .deb format from Slackware tgz. Slackware packages are insanely simple in that they don't really do anything much more than what the OP was asking for namely, copy some files, and run a script. This would save creating the control file and so on because Alien will generate it.

mkdir pkg
pushd pkg
mkdir -p usr/local/bin install
touch usr/local/bin/xxx   # <--- something to install
touch install/slack-desc   # <---- optional description
cp <<script>> install/doinst.sh  # <---- your post-install
tar zcvf ../xxx-1-x86_64-1.tgz *
popd
alien --to-deb --scripts xxx-1-x86_64-1.tgz

If you are unfamiliar with the Slackware package format, note that your install directory in the tarball will not be installed to the target, and if you want a .deb that does update files under /install this is probably not going to work!

Keeely
  • 101
-3
$ apt-get install build-essential dh-make debhelper devscripts
$ wget http://nmap.org/dist/nmap-LAST.tar.bz2
$ tar xf nmap-LAST.tar.bz2
$ cd nmap-LAST
$ dh_make -s -e youremail@site.org -f ../nmap-LAST.tar.bz2
$ apt-get install libgtk2.0-dev flex bison libpcap0.8-dev \
  libpcre3-dev binutils-dev python-all-dev
$ dpkg-buildpackage