Packaging CustomAsm for Ubuntu

I'm using CustomAsm to compile code for my 8-bit-CPU. It works quite nice locally, but I thought it would be nice, if I could also run the compilation as part of GitHub Actions workflow.

I will not go into deep details about how to set up those workflows, there's documentation for that. Basically you create a .yml file in your Git repository for GitHub to act on. There's a choice of OSes for the workflows to run on, my selection is Ubuntu.

There's a slight issue, though. CustomAsm is a Rust program and normally it is installed using cargo install command. To do that, each time I'd have to install Rust, compile CustomAsm and only then I'd be able to use it. It might work, but there's too much of preparation.

Wouldn't it be nice, if I could just apt-get install customasm and be ready to use it. That's what I'm about to enable.

Ubuntu Personal Package Archives

In order for package to be installable in the runner, it must be available at publicly-accessible repository. One of such services is called Personal Package Archives at https://launchpad.net/.

So the first step would be to set up an account there if not done already. Then there are 2 things to do: create the PPA and register an OpenPGP key.

The PPA part is quite straightforward, the key requires some work:

First one needs to generate it. In terminal run

gpg --full-generate-key

and follow instructions (there's something similar in GitHub's documentation).

Next step is to find out ID of the key:

gpg --list-secret-keys --keyid-format=long

there's a line that looks like

sec   rsa3072/XXXXXXXXXXXXXXXX    2023-08-19 [SC]

The XXXXX part is the ID we're looking for.

The following step is to upload key to Ubuntu keyring:

gpg --keyserver hkp://keyserver.ubuntu.com --send-key XXXXXXXXXXXXXXXX

Now we're ready to register the key in Launchpad. First - find out the fingerprint of the key:

gpg --fingerprint

the fingerprint looks something like

27E0 7815 B47C 0397 90D5  8589 27D9 A27B F3F9 6058

Copy and paste it into the website and press Import Key. An e-mail will be sent to an address, specified when generating the key.

The message contains an encrypted text enclosed by:

-----BEGIN PGP MESSAGE-----


-----END PGP MESSAGE-----

It has to be decrypted to get further instructions. Start by copying it (complete with the opening and closing lines) into a text file. Then:

gpg --decrypt message.txt

The text will contain an URL to follow, to complete the registration.

Congratulations! Launchpad is now ready to receive the package.

Preparing the package

Launchpad accepts only source packages, it then builds and publishes binary ones. So we need to prepare a proper source package to upload.

I'm only targeting the latest LTS release (currently that is 22.04 Jammy), the instructions may change slightly with time.

My host machine does not run neither Ubuntu, nor that particular version, also I do not want to pollute it with "once-used" packages. The easy choice is to do most of the work inside Docker container and discard it when done.

Assuming that Docker is already installed, create an empty directory, switch to it and run the container:

docker run -it --mount type=bind,source=.,target=/customasm-ppa ubuntu:jammy

Once the container has started, cd to /customasm-ppa directory.

Install necessary packages:

apt update
apt install debcargo nano

Set some environment variables (if name requires Unicode characters, prepare a file on host system and source it inside the container).

export DEBFULLNAME="Velko"
export DEBEMAIL="velko@example.com"

Create file debcargo.toml containing:

overlay = "overlay"

[source]
section = "devel"

[packages.bin]
section = "devel"

Create an empty directory overlay,  then start packaging:

debcargo package customasm --config=debcargo.toml

It will download sources and prepare the package, but there are some FIXMEs to handle.

Adjust debian/copyright file as needed. Edit debian/changelog, change the first line so it resembles:

rust-customasm (0.13.2-jammy1) jammy; urgency=medium

Copy both files into overlay directory (you may need them if you decide to make the package again). It might be a good idea to save them into a Git repository for later use, they may become useful when new upstream version is released.

Try to build the package:

dpkg-buildpackage -S -uc -us

it will complain about unsatisfied dependencies. Install whatever it requires:

apt install librust-getopts-0.2+default-dev librust-num-bigint-0.4+default-dev librust-vergen-3+default-dev

Note that version of the package librust-vergen-dev installed is 3.0.4, which is older that requested version 3.1.0. Not sure, why exactly this version was required, but package seems to compile fine with the older version as well.

The requirements, however has to be adjusted. Change the version numbers in debian/control and Cargo.toml

Changes in latter file, however, counts as "unexpected upstream changes" and has to be recorded as a patch.

dpkg-source --commit

Now, if we try to build the package again, it should succeed.

Our work within the container is done, but as a last step, let's change owner of the files to something that makes sense in host system:

chown -R 1000:1000 .

The final step must be performed on host system: package has to be signed (look up the key id as before).

debsign -k XXXXXXXXXXXXXXXX rust-customasm_0.13.2-jammy1_source.changes

Done, it is ready for upload!

Uploading and using the package

Launchpad documentation suggests to use command dput ppa:your-lp-id/ppa <source.changes> to upload the package.  On Debian (host system I'm using), it fails. Instructions meant for older versions of Ubuntu, however, appear to work.

Create a file ~/.config/dput/dput.cf with contents:

[my-ppa]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~velko/ubuntu/dev-tools/
login = anonymous
allow_unsigned_uploads = 0

And finally, run 

dput my-ppa rust-customasm_0.13.2-jammy1_source.changes

Now you have to wait for Launchpad to process your upload. It should send an email that the package is accepted, but it still takes some time until package is published. Check the status in website.

There's only one step remaining to make customasm available as a command: add a step in the GitHub Actions workflow .toml file to install it.

    - name: Install tools
      run: |
        sudo add-apt-repository -y ppa:velko/dev-tools
        sudo apt-get install -y customasm 

There, now you can CI/CD your assembly code like a pro!

About the published packages

The packaged version of CustomAsm I prepared, is available at my PPA and anybody can use it. I, however, do not make any promises about keeping it up to date. Package updates likely will co-incide with my on-again, off-again involvement in my 8-bit-CPU project, which may not be in sync with upstream releases.

My main goal here was to support my own hobby project and to document the packaging process (I had to re-learn the steps for 0.13.2 update).

I'm happy to help a little, but I'm not making it my duty - that takes all the fun out of it.

Comments

Popular posts from this blog

8-bit CPU: Clock module

8-bit CPU: ALU and Flags

8-bit CPU: Memory