 Yeah, welcome at this afternoon. I'm Roland. I will talk to you about PTXDist as my previous speaker already mentioned it. I'm a systems integration hacker at Pingotronics. We are a small company in Hildesheim near Hanover. If you've heard about it, yeah. So what is this? Oh, sorry. So what is PTXDist in one slide? It's basically a build system, like if you know Yachto or OpenEmbedded or BuildRoot or even OpenWRTE. So you put in things you want on your platform, on your embedded device, and then you wait some hours and then you get an image out of it, which you can flash on your target. And our building blocks are basically GNUmake. We do a lot of dependency handling with it because it's basically built for this so we can reuse it. We do the dependency handling in kconfig and which also gives us a nice menu for the user to select the packages that you want and select the sub-options and whatnot. There is some glue code in Bash and AWK, which handles the dependencies between kconfig and make. So it basically transforms the kconfig symbols, the dependencies from kconfig into the GNUmake dependencies and does some other things under the hood so you don't have to type so much. Yeah. The first versions of PTX just go back to at least 2003. That's the earliest version I could find. There are probably some older versions, but I couldn't find those. Yeah, so it's basically older than, I think BuildRoot started in 2010 and Jocto is... 2001. 2001, oh, okay, then I'm wrongly informed. Excuse me about that. But well, it's an old project and I think it isn't known so much so basically that's what this talk is trying to change. But now we do monthly releases so every month there's a new release and which is basically just version bums for packages. The overall license for PTX tests and all the recipes are a GPL2, yeah. And now we also have this shiny new logo since I think one year ago because we're basically just a collection of recipes. We have this cooking penguin and an online documentation which is generated from restructured text in swings and you can read this online. Yeah, some statistics. I did this for the previous release. 2020.01 is already out but my slides were prepared last month so we have about 914 target packages and 184 host packages and we're also providing some prebuilt two chains for about 18 plus minus platforms. Architectures like mostly ARM, like ARM 4.4 and V7 are very big and of course the 64-bit version of ARM and there are also some people using it on x86 but this is not the main focus and of course RISC-5 and then some older PowerPC architectures, yeah. I think the basic thing which you got to see on the user interface side is this menu config. We have two big, I said two big but they're not very big menu configs. On the one hand we have the menu config for your user space, for your user land which you can select in which you can select all your target packages like, I don't know, we have here Shell and console tools scripting languages like Python for example, networking tools, I don't know, IP tables, NF tables, what you need, disk file utilities, communication applications. Well, everything that doesn't fit into the other. Editors like VM and Nano. Test roots, web applications, engine eggs, you name it, and graphics and multimedia like QTE, Wayland, yeah, and XORG still. And on the other side, everything that's not user land like kernel and barebox, sorry, bootloader which is barebox for us, but you can also build, of course, U-boot and I don't know, Opti is there in it. Basically everything that's below the user land is selectable in this platform config. So you have this bare metal side on the platform config side and everything that's above it in the menu config. And this is also what the typical BSP looks like on the file level. You have one folder configs, which you have here the PTX config which is what gets selected in the menu config. And this is basically the key config configuration for the, from which the menu is generated. And in it you have a platform. So this is everything you select in the platform config. And in the platform there are usually some other packages that are also using key config for their own configuration like for example here the kernel you, I guess you have a kernel without the kernel. I don't know if anyone's ever tried it but maybe it's possible, I don't know. But also the config for you bootloader which in this case is barebox. And yeah, that's basically everything in configs and you have some rules, some package rules if you want to build some custom software which is not already in PTX test, you can generate package rules in your BSP. And this is basically a .in file which contains the key config menu entry and the make file which handles everything about building the packages. Yeah, and then there is this fold in between here project route, I will come to this later. This is basically everything which you want to override but I will say something about this later. Yeah, the basic structure is, the basic idea is that your BSP directory structure is structured exactly like the PTX test upstream structure so we have the same structure in PTX tests when you install it. So everything that's not found here in your BSP is searched instead in the upstream PTX test installation folder so you can extend PTX tests however you want and use the same structure with it. Yeah, every packages built in stages, I guess you have this in other build systems too. Yeah, it has a get stage and extract stage, prepare a compile and install and a target install stage and which basically the get stage fetches everything from the web and then the extract stage extracts the tar ball which you just fetched and applies the local patches which you maybe have in your BSP or in upstream PTX test. The prepare stage runs basically a configure or CMake or MISON or whatever built your system in your package uses. PTX tests has already support for many of those and I think it is fairly easy to provide support for other build systems too. And we'll see later how this is handled in the rule file itself, in the Mac file for the package. It's basically just a variable you said. Yeah, then the compile stage basically just compiles the packages, a package like it is normally used. The install stage installs it into a isolated directory so many packages install many files by default which you don't use or don't need on your target system. For example, if you build a Qt then you have a whole lot of libraries which you maybe don't want to install. So the next step is this target install stage with terapix, a set of files into your root file system or your IPKG package later. And you can override any one of those stages in your Mac file rule, in your package Mac file but you can also reuse a lot of them which we see just now. Oh no, just a quick information on how to apply patches. You put your patch queue into a patches folder in your BSV or in the upstream PDX test package structure if you're using PDX test in a development version. And you name it like the version and the name of your package, in this case, bodybox with a version number. And there is a serious file and the patch file, yeah. And the usual thing is that you put packages for the... The usual thing is to put patches for your packages which are from the platform config like the kernel or the bootloader or anything else in this area into this configs slash platform folder. Yeah, but you can also put it in there and have it for all the platforms that you want. So you can edit this patch tag by using quilt or git after extracting the package and then changing to the package directory where it's extracted, yeah. Okay, this is what I wanted to tell how a package looks like in the inside. This is basically the menu section for the package. You just give a section in which of these one you want to have it, project specific is the default section which is just here. And then you select basically the dependencies that your package uses like in this case LibUSB so LibUSB gets built before your package gets built so all the headers are found and so on. And also in this case because we're using CMake in this example you also have to select the CMake host tool so PDX test can build your package, yeah. And every package is a tri-state option so you can set it to yes, no or module which you can see which we'll see later what that does. Then we have the make file. As I said, it's a lot of assigning variables like the version number and the MB5 for the downloaded package version for this URL and the source where it gets extracted and the license files. And the license files are really cool because PDX test can put them all together in one big PDF so you have kind of a report about all the licenses you're using in your package, yeah, in your image. And if you're using the default tools like CMake or Automake you often don't really have to do a lot of these and can reuse all the internal PDX test functionality to build it. So the next steps are really short and reuse everything except the prepare and the target install stage. And in the prepare stage we are also only setting this config tool variables to CMake and we are setting these config options for the CMake to maybe enable our USB functionality. But this depends of course on the package you're using. And then in the target install stage we set up our variables for the IPKG package which gets built later and basically we're then only copying, oh, here should be a file name which I missed in the example, but yes, this is the terry picking part. And we have three package types. As I already said, we have target packages which I'll get installed on the hosts like some key busybox, core utils, whatever. And the host packages are only there for having a compatible built environment. So we try to support most of the Linux distributions that are out there. I think the earliest is something like CentOS 6, yes. Which doesn't have an up-to-date core utils. So we have to build the core utils ourselves. So all the packages which are using, I don't know, tar with dash dash M time versions or something can do that, yeah. And the third part is image packages which are also from the platform config and you can decide there what kind of images you want to build. So I will talk about layering a bit. So PTIX just started up with platforms. So platforms are the oldest mechanism to layer things on top of each other but there are five different others. We'll start with platforms. In this example, I'm maybe using a platform for Raspberry Pi. So I have a kernel with a version 4.19. I built an HD image for it and the Raspberry Pi needs a boot partition for the boot loader. So I enable this and because it already has a boot loader internally, I don't build a barebox for it. And in the user land, in this example, I built a system, a busybox and a cups. And if I now want to extend this support to other platforms, I can just add another platform. Like for example, a platform containing ARM V7A and ARM 64-bit V8 and I can choose different kernel versions here and with this also maybe a different patch stack if your platform support is not good enough upstream and I can choose different images which I need and maybe a boot loader and other boot loader like in the other platforms. And I talked about that packages are tri-state options in Kconfig. So you can set these options to maybe M, so modular. And maybe you want to have a debug collection, software collection that doesn't get installed by default on a user's or a customer's target, but you still want to be able to debug some packages in your system. So you set these debug packages to M and then choose them at the latest step in a collection config file and in the debug collection, you enable them and maybe in the release collection, you don't enable them. Yeah, these are collections. Then we have alternative config files, as I said before. We had this additional folder here, project root and here are two config files, everstep and shadow in ETC. And you can use this with packages that are using this install alternative macro in their target install stage. For example, in this example for CUPS, CUPS is installing the ETC print cap file and you can override this by any one of these locations. So first locally in your BSP then it gets searched, follow up. Then in the project root directly from the PyTex test installer and then in the CUPS installer and then in the CUPS built here. So you have a lot of options to override config files for different configurations. A new mechanism which exists about a year now is kconfig divs, which is basically just simple divs on kconfig files. If you are using a custom kernel image, for example, you want to have some debug symbols in there. You set the config file to something like kconfig debug, which is living in the platform config as earlier. But you tell PyTex is this refconfig variable and this points to another kernel config in this case and then internally PyTex just computes the div between what you select in this kconfig file and this kconfig file. So you do a many config for your kernel debug and then enable these three symbols and these two symbols later get written into the kconfig div. And at the first stage, the first line is an MD5 sum of the refconfig and so PyTex just knows when to recalculate this div. And kconfig divs are also one of the building blocks for base layers. So as I said before, we had this idea to have the same structure in our BSP like in the upstream PyTex, this installation folder and extend locally where we need it but we have a better idea and all problems on computer science can be solved by another level of indirections. So we use recursion. In this case, we have one BSP which is a whole BSP by itself. It has the same structure as before and we want to layer our BSP on top of it. So all we have to do is just create a link named base to this upper or lower layer in this case. And everything you now select in the PyTex config is calculated as a div to this PyTex config on the districate layer and you can enhance your BSP in relation to the lower layer by adding rules, for example. And this is great if you don't want to share all your rules in one layer. For example, your customer only gets an open source layer. It gives you only an open source layer and wants to layer their own proprietary software on top of it. And this is one way you can do it. Some more goodies which got added in the last stage. There's now a command to give information about one package and one to give information about your BSP. And as I already mentioned is the license report which basically collects all the information from the package recipes and dumps them into one big PDF and also extracts all the copyright files. Yeah. If you want to try this out, you can have a look at districate which is a pre-configured BSP for a variety of deaf boards like nitrogen six or even the Raspberry Pi. Some versions of it, not the four versions, sadly. And you can also use a QMO if you want. Yeah. Short things about contribution. You can patch, send patches, patches are welcome. Currently about 85% of patches are in-house but maybe the changes, yeah. So are there questions? So my package example that you showed us has a USB in the prepare section. It has a dash D USB on. What would you suggest if I want to have that configurable? You can add another Kconfig symbol which is dependent onto the top symbol. So you basically extend this symbol by another sub-symbol, yeah. And you can switch it on and off and then you can use a macro here which just looks if this Kconfig symbol is switched on and off, yeah. All right, and is this something that is halfway common in the packages? I just used a simple example here but this is really common. And also for controlling what dependencies my package will pull in. In the CUPS example which I showed here you can build CUPS with many different dependencies like PNG support or what not, yeah. And does that have to be then set per package in the PTX config? Yeah, this is also written to the PTX config because it is in the menu so it gets written into the PTX config. Yes, but does it have to be configured per package or is there some standardization on the naming, let's say, of these sub-options so that I can set them globally for the whole image in one place? Yeah, this is usually for the whole image, yes. Okay. Then I think the time is up, thank you.