= Overview = For the most part it's like building software from source the old-school way, roughly: {{{ configure --prefix=/usr/local make make DESTDIR=/tmp/package install-strip # or is it DESTDIR=/tmp/package make install-strip # jiggle things around so the files are clean and sane: chmod as needed to remove setgid bit make separate dirs as needed, if your software should be split into multiple components (eg. executable + library/headers) mksquashfs /tmp/package package.tcz -all-root -noappend }}} Some software is more tedious because they're made for other build systems. So you need to install that first before you can build. = Tooling = Assuming you're building on a TCL system then you'll need to load a few extensions first. * file * binutils * the compiler * squashfs-tools * bash is probably nice to have {{{ # DEP file, binutils (for stripping) for i in file binutils squashfs-tools ; do tce-load -i $i ; done }}} = Worked example with Jose = I'm not sure why I have two install phases shown in my old notes... {{{ tc@primer:~/jose/build$ sudo meson install --no-rebuild Installing lib/libjose.so.0.0.0 to /usr/local/lib Installing cmd/jose to /usr/local/bin Installing /home/tc/jose/build/jose/jose.h to /usr/local/include/jose Installing /home/tc/jose/jose/cfg.h to /usr/local/include/jose Installing /home/tc/jose/jose/io.h to /usr/local/include/jose Installing /home/tc/jose/jose/b64.h to /usr/local/include/jose Installing /home/tc/jose/jose/jwk.h to /usr/local/include/jose Installing /home/tc/jose/jose/jws.h to /usr/local/include/jose Installing /home/tc/jose/jose/jwe.h to /usr/local/include/jose Installing /home/tc/jose/jose/openssl.h to /usr/local/include/jose Installing /home/tc/jose/doc/ronn/jose.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-alg.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-fmt.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-b64-dec.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-b64-enc.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwe-dec.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwe-enc.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwe-fmt.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwk-exc.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwk-gen.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwk-pub.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwk-thp.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jwk-use.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jws-fmt.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jws-sig.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/ronn/jose-jws-ver.1 to /usr/local/share/man/man1 Installing /home/tc/jose/doc/doxygen/man/man3/jose_b64.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_jwk.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_jws.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_cfg.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_jwe.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_io_t.3 to /usr/local/share/man/man3 Installing /home/tc/jose/doc/doxygen/man/man3/jose_io.3 to /usr/local/share/man/man3 Installing /home/tc/jose/build/meson-private/jose.pc to /usr/local/lib/pkgconfig DESTDIR=/home/tc/BUILDROOT/jose ninja install }}} Now some sanitisation of the outputs: {{{ # current working directory is probably ~/BUILDROOT/jose/ rm -rf usr/local/share/ chmod -R g-s ~/BUILDROOT/jose/ find . | xargs file | grep "executable" | grep ELF | grep "not stripped" | cut -f1 -d':' | xargs strip --strip-unneeded find . | xargs file | grep "shared object" | grep ELF | grep "not stripped" | cut -f1 -d':' | xargs strip -g # Now check that usr/local/lib/pkgconfig/jose.pc looks vanilla and sane. }}} Make the archive and checksum: {{{ mksquashfs jose jose.tcz md5sum jose.tcz > jose.tcz.md5.txt }}} Generate the file listing, you might need to select the subtree manually like in this case where I only captured `usr/`: {{{ cd jose/ find usr -not -type d > jose.tcz.list }}} libjansson is a dependency for jose that we built earlier, so make note of that {{{ echo jansson.tcz > jose.tcz.dep }}} Write a `.info` file that describes the package, crib from existing files where possible. Wrangle the deps some more so that it can get jose => jansson => libcrypto from jansson-dev. = Another example with more scripting for http-parser = Ideally we'd like to set a couple variables and then run a fixed set of commands that don't require much thinking. This is pretty close to that. {{{ NAME=http-parser mkdir -p /home/tc/BUILDROOT/$NAME DESTDIR=/home/tc/BUILDROOT/$NAME make install-strip cd ~/BUILDROOT/ chmod -R g-s $NAME find $NAME/usr/local/include -type f -execdir chmod -x {} \; mksquashfs $NAME $NAME.tcz md5sum $NAME.tcz > $NAME.tcz.md5.txt }}} Then the other steps as mentioned above. = Building tangd = This is what I wanted all along, but tang has a few dependencies. Thankfully not a very deep chain. Random notes, unordered. I think part of it was that I wanted it to generate new keys if it's a fresh install and you don't have any yet. In the end I think I made it part of the startup process, not the package post-install. {{{ mkdir -p -m 0700 /usr/local/var/db/tang mkdir -p -m 0700 /usr/local/var/cache/tang /usr/local/libexec/tangd-update /usr/local/var/db/tang /usr/local/var/cache/tang /usr/local/libexec/tangd-keygen /usr/local/var/db/tang /usr/local/libexec/tangd /usr/local/var/cache/tang /home/tc/BUILDROOT/tang/usr/local/libexec/tangd-update DEP: bash sudo /home/tc/BUILDROOT/tang/usr/local/libexec/tangd-keygen /usr/local/var/db/tang sudo ./libexec/tangd /usr/local/var/cache/tang 2>/dev/null }}} Packaging steps: {{{ NAME=tang cd ~/BUILDROOT/ # strip binaries find $NAME | xargs file | grep "executable" | grep ELF | grep "not stripped" | cut -f1 -d':' | xargs strip --strip-unneeded find $NAME | xargs file | grep "shared object" | grep ELF | grep "not stripped" | cut -f1 -d':' | xargs strip -g rm -fv "$NAME.tcz" mksquashfs $NAME $NAME.tcz -all-root md5sum $NAME.tcz > $NAME.tcz.md5.txt cd "$NAME" find usr -not -type d > "../${NAME}.tcz.list" cd .. echo http-parser.tcz >> tang.tcz.dep echo jose.tcz >> tang.tcz.dep echo inetutils-servers.tcz >> tang.tcz.dep write a .info file }}} Saving it for loading on boot: {{{ # cp it all to /mnt/mmcBLAH sudo cp -v $NAME.tcz* /mnt/mmcblk0p2/tce/optional/ # Define a named TCP port on the system echo -e "tangd\t\t8264/tcp" >> /etc/services # This goes in the inetd config tangd stream tcp4 nowait root /usr/local/libexec/tangd-wrapper tangd /usr/local/var/cache/tang # Load the extension tce-load -i tang bash sudo killall inetd sudo tangd-firstrun # add keys to your backups in /opt/.filetool.lst /usr/local/var/db/tang /usr/local/var/cache/tang # run a backup sudo filetool.sh -b # test it, make sure it comes up after reboot sudo reboot }}}