Can a .deb package include sources that are to be compiled by dpkg?

I have a pkg with some c++ code. Currently I'm compiling some of the c++ code as binary, some as library, and I can ship and deploy it on other platforms.

However, I also have a driver there, which I can't cross compile due to its dependency on the kernel, which makes it so that every kernel might need a different binary.

So, what I want to have is a .deb where I will store the binary under /usr/bin (done), the library under /usr/lib (also done) and the driver source code under /opt/driver (I guess... Is this a legit place for that?)

Packing this is the easy part, since all I need to do is put it in my workspace, and call dpkg-deb. What I'm not sure about are two things

  1. Is it legit to pack source code in a .deb? (In python terminology - is .deb a bdist(binary distribution) or also can be an sdist (source distribution))
  2. If it is legit, how can I invoke the make commands? Can dpkg / apt do that for me? Or do I need to run dpkg -i pkg and then run make? [looking at postinst but I'm not sure if this is the right way to go]

I'm open to any kind of build system if it can solve this though I'm currently using cmake and would much prefer sticking to it


My POC:

tree bla_x86_64
bla_x86_64
├── DEBIAN
│   ├── control
│   └── postinst
├── opt
│   └── bla.cpp
└── usr
    ├── bin
    │   └── bla.bin
    └── lib
        └── bla.lib
cat bla_x86_64/DEBIAN/postinst 
#!/bin/sh

set -e

echo hello world!
echo compiling $(ls /opt/bla.cpp)
echo cleanup
rm -rvf /opt/bla.cpp
$ dpkg-deb --build --root-owner-group bla_x86_64/
dpkg-deb: building package 'bla' in 'bla_x86_64.deb'.
$ sudo dpkg -i bla_x86_64.deb 
(Reading database ... 407519 files and directories currently installed.)
Preparing to unpack bla_x86_64.deb ...
Unpacking bla (4.0) over (3.0) ...
Setting up bla (4.0) ...
hello world!
compiling /opt/bla.cpp
cleanup
removed '/opt/bla.cpp'

Solution 1:

Technically there is no such thing as "legitimate" or "illegitimate" content of a .deb file. You may pack anything you want in it.

A good place where to put your source code on the target system would be under /usr/share/${packagename}.

To have dpkg or apt invoke your make commands, just place them in your package's postinst script. Make sure that you declare as dependencies all the programs needed for the build process, such as cmake, g++ and binutils, as well as the kernel headers, otherwise installation will fail on systems that happen to have no compiler installed. Also make sure you do proper error handling in your postinst script to avoid rendering the target system non-operational by installing a bad kernel module as a result of a failed compilation.

Note that this solves only half of your problem. In addition to compiling your driver for the kernel in use when your package is installed, you also need to make sure it is recompiled for the new kernel after each kernel update. The solution for this is DKMS, short for Dynamic Kernel Module Support. So you'll want to look into supporting DKMS in your .deb package, too.