improve deployment time of yocto based development - deployment

In our company we have switched to Linux embedded systems (2 different platforms). Our build is based on yocto.
Unfortunately we are all quite unexperienced with it. Especially I have some questions about collaboration within yocto and with reusing its deployment (SDK).
In our company there are multiple teams involved in development:
Team1: Maintaining yocto and the Linux base system
Team2: Developing company-own libraries which will become part of the base system (own git repository, which is added in yocto recipe)
Team3: Developing software (based on Linux base system + company-own libraries)
The problem: Our current development workflow is quite slow.
For example:
There is some bug in a small company-own library LibA.
Team2 commits some bugfix for LibA (small project, a standalone build would take ~2min).
In a next step there has to be a Pull-Request updating the CommitID within LibA's yocto recipe (~15min including a small CI build + merge checks).
As soon as the Pull-Request is merged, a release-build can be triggered (CI). The result of this build is a SDK and a MfgTool (~120min for all platforms/variants).
Now Team3 has to download the new SDK and update their build to use the new SDK (~5min).
Then they trigger a release build of their software (~10min) which results in a flashable image.
So all in all a small change of LibA takes about 2 hours until it can be integrated by Team3, and another 15min for the complete software to be available to our test team.
What is the recommended standard way for this (I think we are not the only company with this issue)?
How can we improve the yocto build workflow?
Is there any way to prevent that the yocto build must be used if LibA changes?
Thank you very much for your help.

I would takle your main issue, the build time of 120m seems very long.
I would recommend to create use Source Mirror , sstate mirror. Do one buildjob in the night which creates those contents. Take a build machine with at least 8 cores and 16-32GB ram.

Related

Difference between Yocto Project and OpenEmbedded?

On Yocto Project FAQ:
The Yocto Project and OpenEmbedded share a core collection of metadata
called openembedded-core. However, the two organizations remain
separate, each with its own focus. OpenEmbedded provides a
comprehensive set of metadata for a wide variety of architectures,
features, and applications. The Yocto Project focuses on providing
powerful, easy-to-use, interoperable, well-tested tools, metadata, and
board support packages (BSPs) for a core set of architectures and
specific boards.
I still not getting nothing clear. The two frameworks are meant to build Linux distributions. But I would like to know on what they are distinct specifically. Not only techically but also objectivly, so I can argue why to choose one or another.
Moreover, why Yocto has so much prominence? altough OE being the first build framework.
ps: I have worked with Yocto Project, but not with OE.
The key point is that the Yocto Project is a community/organisation, and not something you can buy/download/install.
Some of the things that the Yocto Project works on includes bitbake (the build tool), OpenEmbedded Core (the essential recipes to build systems, such as glibc/gcc/systemd), some BSPs, and tooling/services (error reporting service, autobuilder, etc).
The OpenEmbedded community predates Yocto and at the time had a different focus, but now we both contribute to the same projects so there's no real difference.

Improving Fastlane's runtime for Scan -> Gym -> Deploy

I've been trying to include Fastlane in a CI environment where the following should happen:
any commit to the master branch should trigger a test run and then a build into Testflight.
any commit to the development branch should trigger a test run and then a build into Fabric Beta.
any other commit or pull request should trigger a test run.
The lanes are working with all the code signing through match.
In order to avoid building twice I'm building through Gym and then Scan with skip_build: true and clean: false, as mentioned in #3353.
Although this does seem to help with the build time, due to the amount of cocoapods dependencies, it goes over the 50 minute limit in travis-ci.org. (Feel free to check the build logs)
How can this be improved in terms of running time? (Aside from fixing the slow compiling Swift functions mentioned in #3)
For reference, here's my Fastfile.
One way you can speed up your build phase is using prebuilt frameworks. It's like importing AVFoundation or any other Apple toolkit on your project.
Try to identify which dependency is slowing the running time down and move it to a prebuilt framework.
Carthage is a nice tool that allows you to use prebuilt frameworks and manage dependencies as well. You can cache Carthage builds on your CI. Check out this great blog post on how you can achieve caching.
I don't know of a way to re-use pre-built derived data for scan, gym and snapshot. Main reason for that is that those are builds for different architectures, with potentially different xcconfigs.

Can a Yocto recipe be built using the SDK?

I have a Yocto project that takes quite some time to compile. The final image is meant to run my application and as such, I have a custom recipe in my own layer.
Since building the whole Yocto image takes a couple of ours, I do build an SDK so I can cross-compile my application and transfer the binary to the running device for testing.
Instead of compiling the binary and having to transfer it manually to the device,
can I use the Yocto recipe I've written for my application with the SDK so that I can "call" its do_package()? If other devs could build the .deb (assuming PACKAGE_CLASSES = "package_deb" in local.conf) simply from the SDK that could simplify greatly our workflow.
Thanks!
Huh, bluelightning beat me to the punch. That'll teach me for not hitting refresh. Anyhoo, here's my 2ยข:
Yes, have a look at devtool. The goal of the devtool script is to improve and simplify the development of software for target devices.
First, have your developers install the extensible SDK (eSDK), which is built using this command:
bitbake -c populate_sdk_ext my-image-name
Once you source this SDK, run these commands:
devtool modify my-recipe-name
...make your changes to [sdk]/workspace/source/my-recipe-name...
devtool build my-recipe-name
devtool package my-recipe-name
This should produce a package of your app in [sdk]/tmp/deploy/rpm/[arch]/my-recipe-name, which can then be deployed to the target machine.
Also, have a look at devtool deploy-target if your target machine has network connectivity.
If you give me some more details on your setup I may be able to help more. Hope this at least gets you pointed in the right direction.
This is really what the Extensible SDK is designed to do - provide a pre-built and pre-configured environment and allow you to build applications and other components in pretty much the same way they are built with the full build system. You can even deploy output files over to the target device easily if an ssh server is running on the target.
You can build the extensible SDK with the following command:
bitbake -c populate_sdk_ext <imagename>
For more information you may wish to read the new SDK manual.

Version control workflow with 'external' binary files

I'm working with an embedded system software project right now, and we're facing some problems dealing with some precompiled binaries living inside our repository.
We have several repositories for different parts of our project: One for the application itself, one for the OS, one for the bootloader and several libraries. All of them, except the one for our application, are shared with other teams, for other projects. We are using git (and changing is not an option right now), but I think we'd have the same problem with any VCS.
Right now, we have a precompiled binary for each of those components living inside our application repository. The idea was to speed up the build time, since the OS alone takes about 20 minutes to build from scratch and most guys work only with the application.
Problem is, there are several bugs/features in those binaries (and related application code) to be integrated at any time and, as you know, diffing and merging binaries won't work.
So, how do you guys do when you have to work with those external dependencies?
Thanks a lot =)
One viable solution is to use an external binary repository like Nexus.
It is not linked to a VCS, meaning you can easily clean up old versions of said binaries you don't need anymore
It is light-weight (simple HTTP client-server protocol, no need to clone all the repo with all the versioned binaries like you would with a DVCS -- git or mercurial --)

How to version control the build tools and libraries?

What are the recommendations for including your compiler, libraries, and other tools in your source control system itself?
In the past, I've run into issues where, although we had all the source code, building an old version of the product was an exercise in scurrying around trying to get the exact correct configuration of Visual Studio, InstallShield and other tools (including the correct patch version) used to build the product. On my next project, I'd like to avoid this by checking these build tools into source control, and then build using them. This would also simplify things in terms of setting up a new build machine -- 1) install our source control tool, 2) point at the right branch, and 3) build -- that's it.
Options I've considered include:
Copying the install CD ISO to source control - although this provides the backup we need if we have to go back to an older version, it isn't a good option for "live" use (each build would need to start with an install step, which could easily turn a 1 hour build into 3 hours).
Installing the software to source control. ClearCase maps your branch to a drive letter; we could install the software under this drive. This doesn't take into account non-file part of installing your tools, like registry settings.
Installing all the software and setting up the build process inside a virtual machine, storing the virtual machine in source control, and figuring out how to get the VM to do a build on boot. While we capture the state of the "build machine" with ease, we get the overhead of a VM, and it doesn't help with the "make the same tools available to developers issue."
It seems such a basic idea of configuration management, but I've been unable to track down any resources for how to do this. What are the suggestions?
I think the VM is your best solution. We always used dedicated build machines to get consistency. In the old COM DLL Hell days, there were dependencies on (COMCAT.DLL, anyone) on non-development software installed (Office). Your first two options don't solve anything that has shared COM components. If you don't have any shared components issue, maybe they will work.
There is no reason the developers couldn't take a copy of the same VM to be able to debug in a clean environment. Your issues would be more complex if there are a lot of physical layers in your architecture, like mail server, database server, etc.
This is something that is very specific to your environment. That's why you won't see a guide to handle all situations. All the different shops I've worked for have handled this differently. I can only give you my opinion on what I think has worked best for me.
Put everything needed to build the
application on a new workstation
under source control.
Keep large
applications out of source control,
stuff like IDEs, SDKs, and database
engines. Keep these in a directory as ISO files.
Maintain a text document, with the source code, that has a list of the ISO files that will be needed to build the app.
I would definitely consider the legal/licensing issues surrounding the idea. Would it be permissible according to the various licenses of your toolchain?
Have you considered ghosting a fresh development machine that is able to build the release, if you don't like the idea of a VM image? Of course, keeping that ghosted image running as hardware changes might be more trouble than it's worth...
Just a note on the versionning of libraries in your version control system:
it is a good solution but it implies packaging (i.e. reducing the number of files of that library to a minimum)
it does not solves the 'configuration aspect' (that is "what specific set of libraries does my '3.2' projects need ?").
Do not forget that set will evolves with each new version of your project. UCM and its 'composite baseline' might give the beginning of an answer for that.
The packaging aspect (minimum number of files) is important because:
you do not want to access your libraries through the network (like though dynamic view), because the compilation times are much longer than when you use local accessed library files.
you do want to get those library on your disk, meaning snapshot view, meaning downloading those files... and this is where you might appreciate the packaging of your libraries: the less files you have to download, the better you are ;)
My organisation has a "read-only" filesystem, where everything is put into releases and versions. Releaselinks (essentially symlinks) point to the version being used by your project. When a new version comes along it is just added to the filesystem and you can swing your symlink to it. There is full audit history of the symlinks, and you can create new symlinks for different versions.
This approach works great on Linux, but it doesn't work so well for Windows apps that tend to like to use things local to the machine such as the registry to store things like configuration.
Are you using a continuous integration (CI) tool like NAnt to do your builds?
As a .Net example, you can specify specific frameworks for each build.
Perhaps the popular CI tool for whatever you're developing in has options that will allow you to avoid storing several IDEs in your version control system.
In many cases, you can force your build to use compilers and libraries checked into your source control rather than relying on global machine settings that won't be repeatable in the future. For example, with the C# compiler, you can use the /nostdlib switch and manually /reference all libraries to point to versions checked in to source control. And of course check the compilers themselves into source control as well.
Following up on my own question, I came across this posting referenced in the answer to another question. Although more of a discussion of the issue than an aswer, it does mention the VM idea.
As for "figuring out how to build on boot": I've developed using a build farm system custom-created very quickly by one sysadmin and one developer. Build slaves query a taskmaster for suitable queued build requests. It's pretty nice.
A request is 'suitable' for a slave if its toolchain requirements match the toolchain versions on the slave - including what OS, since the product is multi-platform and a build can include automated tests. Normally this is "the current state of the art", but doesn't have to be.
When a slave is ready to build, it just starts polling the taskmaster, telling it what it's got installed. It doesn't have to know in advance what it's expected to build. It fetches a build request, which tells it to check certain tags out of SVN, then run a script from one of those tags to take it from there. Developers don't have to know how many build slaves are available, what they're called, or whether they're busy, just how to add a request to the build queue. The build queue itself is a fairly simple web app. All very modular.
Slaves needn't be VMs, but usually are. The number of slaves (and the physical machines they're running on) can be scaled to satisfy demand. Slaves can obviously be added to the system any time, or nuked if the toolchain crashes. That'ss actually the main point of this scheme, rather than your problem with archiving the state of the toolchain, but I think it's applicable.
Depending how often you need an old toolchain, you might want the build queue to be capable of starting VMs as needed, since otherwise someone who wants to recreate an old build has to also arrange for a suitable slave to appear. Not that this is necessarily difficult - it might just be a question of starting the right VM on a machine of their choosing.