[Announcement] JUCE support for Embedded Linux

Hi all,

I would like to share here some news regarding JUCE and Embedded Linux: I have upstreamed JUCE support for the OpenEmbedded (also Yocto) build system for Embedded Linux! All the JUCE related work is already upstreamed as well. :grinning:

Introduction

I would like to introduce myself since I am quite new here. My name is Felipe Tonello and I work at ROLI mainly on Audio for Embedded Linux. (check out the Seaboard GRAND for a really cool Embedded Linux device running JUCE!)

Embedded Linux support is all about building. Besides the architecture support that most libraries and system developers have to worry about, application developers care about how to build to a different platform other than the one they are using. This task is quite complicated so I will not discuss it here. And that is why we use build systems - tools developed in order to solve that and many other problems.

Important: This post considers that you are running on any major GNU/Linux distribution and have an OpenEmbedded (or Yocto) setup done.

How to build

There are two ways to cross-compile your application:

  1. Using a build system (for production)
  2. Using a SDK (for development)

Build System

Here I provide some of the basics in order to build your application on a build system, considering you already have an openembedded (or yocto) environment setup:

  1. Add the meta-multimedia layer from meta-openembedded repository to your build configuration.
  2. Create a recipe for your application containing the following skeleton:
inherit juce

JUCE_JUCERS = "${B}/cool-project.jucer"

SRC_URI = "git://path-to-my-repo.git"

do_compile() {
  cd ${B}/LinuxMakefile
  CONFIG=Release oe_runmake
}

do_install() {
  install -D ${B}/my-binary ${D}${bindir}/my-binary
}

A little explanation

The first line is where the magic happens, inherit juce will perform all the basic dependency configuration for the build. The bbclass for that can be found here. That class defines two main variables that application recipes should define:

  • JUCE_MODULES (optional): What JUCE modules your application depends on? It defaults to what the build system supports. Values should be JUCE modules names separated by spaces.
  • JUCE_JUCERS (required): The path of the .jucer your application uses to build. It can be multiple .jucer files separated by spaces.

SRC_URI, do_compile(), do_install() and oe_runmake (runs make with some arguments) are part of the OpenEmbedded build system. install is a normal Unix command.

SDK

For SDK builders

In order to add JUCE support to an OpenEmbedded based SDK, add nativesdk-projucer dependency to TOOLCHAIN_HOST_TASK like this: TOOLCHAIN_HOST_TASK += "nativesdk-projucer"

Build your SDK as usual.

For developers

Install the SDK previously built and source the environment file that comes in it.

On the terminal (where you sourced the environment file), you will notice that Projucer will be accessible on the current $PATH, which means that you can type Pro<TAB><TAB> and the shell will autocomplete to Projucer. Then you can just run Projucer --resave my-application.jucer (or even without --resave, which will open Projucerā€™s window) normally. Just cd into the directory where the Linux Makefile is and run make. Your cross compiled binary will be ready in a short time.

It is that simple! :grin:

Conclusion

This makes things really easy for Embedded Linux development with JUCE. And yes, some Embedded Linux knowledge is required in order to setup a build system, but that can be the work of someone else. :wink:

If you want to know more

Make sure you attend ADC 2016 because, among many other reasons, I will be presenting a talk about Audio Application on Embedded Linux!

15 Likes

This is exciting stuff!

Can you recommend any inexpensive, off the shelf prototyping boards (known to work well, that is)?

Best,
Ben

Hi Ben,

Sure. The OpenEmbedded build-system (used by the Yocto project) is widely adopted by the Embedded Linux industry.

Here you can find several BSP (Board Support Package) under the Yocto Metadata Layers section.
At ROLI, we use the meta-fsl-arm BSP which supports all Freescaleā€™s SoCs and machines, such as the i.MX6Q SabreSD (base for the Seaboard GRAND).
There are also community and official support for other machines such as:

NOTE: All items below are links to each respective BSP, but for some reason this forum doesnā€™t show them as links on a bulleted list.

and so onā€¦

Back to the recommendation: they are all development boards that suppose to support a range of functionalities, such as a decent multimedia support, specially SIMD instruction set.

Raspberry Pis

The Raspberry Pi seems to be the easiest to recommend due to its adoption and more likely to have a bigger community around to try out your application or maybe to help you out.
The downside is that the audio hardware is terrible - basically non-existent. If you want a good audio support you need to add a codec expansion board, such as the Cirrus Logic Audio Card.
Its 3rd version has 64bit 4 core ARM CPU with Wi-Fi and BT 4.1 (more on this below) integrated, which is really cool.

TIā€™s boards

I have also used BeagleBoards, their Linux support is also really good too but less powerful when compared to the Pi. The BeagleBoard Black has a nice feature which is the Programmable Real-time Unit (PRU) - it can be used to handle real-time interrupts among other things.

NOTE on Bluetooth Low-Energy: I have been working on supporting the MIDI over BLE specification on Linux. Which means that, once is upstreamed and released, all these boards will support MIDI over BLE out-of-the-box.

I hope that is useful.

Cheers,
Felipe

Hi!
are there any plans to support Wayland for graphics output?

Thanks!

1 Like

No, not at the moment. :frowning:

Is it possible to make full screen Linux application without X11 overhead (and possibly with HW accelerated OpenGL ES)?

Iā€™m using i.MX6Q SabreSD and performance with X11 is poor.

It is. But that is unrelated to JUCE.

You just need to start an XServer and run the application, set the position and size to appropriate values.

This could be anything, I canā€™t judge without looking into your environment.

Hi,

I got everything working fine for my hobyist project on a raspberry pi 2.
My Juce based app (a chess UI) boots directly under X in full screen mode with a working touch screen.
It targets a raspberry pi 2 with a 5 inches TFT HDMI display (35ā‚¬ waveshare model).

I spent quite an amount of time to have this working fine, so i thought i was a good idea to share my meta layer.
https://github.com/Ixox/meta-xavier

The image (recipes-core / rpi-image-timochess) is not really minimal but it boots quite quickly (20s). I cut it down to 12s by tweaking /etc/rc5.d.

Once you have flashed your image on your SD, in conf/ youā€™ll find a little script that deploys the Juced app rpm on the raspberry pi, kills the app and relaunch it from your PC.
So code and test your app on your PC.
When ready : bitbake your recipe (crosscompile) and deploy in 5 seconds on your raspberry pi2.

JUCE + YOCTO + raspberry pi 2 is a fantasticly fun combo !

Thanks Jules, Felipe and Team,

Xavier

10 Likes

I put something like this together also, but using Buildroot instead. Here are all the files and a pre-built image:

I also recorded a little video that shows how fast this boots and what it looks like:

8 Likes

Hi,
did anybody suseccfully follow the instructions of @ftonello withe the current meta-openembedded ?
To me it seems to be brocken with Juce 5.
I can`t bitbake nativesdk-projucer or bitbake projucer-native.
I allways get errors like I described here.
Any help is very welcome. Thanks

JUCE does not officially support yocto and we rely on the yocto community for keeping it up-to-date. Iā€™ve reached out to the original author of JUCEā€™s yocto support and Iā€™m hopeful that heā€™ll fix this. Letā€™s seeā€¦

As a short fix you can disable the webkit gtk support of JUCE.

I believe we should disable Webkit support for JUCE on embedded by default. If the user really wants this, it can enable. What you guys think? This will be done in the bitbake recipe, so no need to change JUCE.

1 Like

Very good idea.

The webkit gtk support is only really used for the Projucer. So it should be enabled on the host but not on the target.

Bumping this to see if anyone has been using JUCE in the embedded space in the last 5 years? I imagine with first-party CMake support available for JUCE nowadays, a much simpler integration would be possible than with Projucer.

I have however had trouble dealing with juceaideā€™s dependencies to things like gtk+ and webkit when trying to get this working directly on my own using CMake. Is there any way of turning off these juceaide dependencies and sacrificing the ability to use the JUCE modules which depend on them?

Iā€™ve deployed JUCE 5 and 6 on various embedded devices (PI 3/4, NXP ARM and Intel embedded boards).

Iā€™ve not attempted it with the official JUCE CMake as it wasnā€™t as established at the time. Instead I included the bits I needed from the JUCE source code as another unity translation file with the appropriate definitions set.

You probably wonā€™t need juceaide for embedded targets and you can still use the standalone BinaryBuilder for building binary data, although depending on memory constraints you may want to load data from disk instead of lumping it in with the code objects.

Iā€™ve found embedded platforms usually require some specific fixes, so you might want to choose a JUCE version and stick with it.

Cross-compilation can be an issue. I usually set up a cluster of similiar boards for building. That being said however, Crosstools-NG has come a long way since I last touched it! Iā€™m going to see if its compatible with WSL2 as that would be much nicer to work with.

I will always avoid Yocto/Buildroot for building the user-level code.

Happy to answer any specific questions if I can!

3 Likes

You probably wonā€™t need juceaide for embedded targets

This is what Iā€™m currently trying to resolve right now. When building JUCE code via CMake, juceaide is invoked automatically by JUCE itself, and it tries to pull in all of its possible dependencies, including those for modules I will never use (i.e. for GUI stuff, when Iā€™m trying to just build libraries and headless console executables).

I think this is more of a question for @reuk - is there a way to control which dependencies juceaide goes looking for by specifying which modules are to be used up front? If only using juce-core, for instance, it doesnā€™t make sense that juceaide requires that I have gtk+ available in my toolchain to build.

FTR @oli1 I am using Yocto and OpenEmbedded, I donā€™t think crosstools-ng is a part of the picture presently (building with HardKnott and Morty for current and legacy NXP boards, respectively).

If you specify the option JUCE_MODULES_ONLY, I believe it wonā€™t build the juceaide.

Although, this does seem like an issue in the cmake workflow. Even when crosscompiling, the juceaide should be built for the host platform, not the target platform.

Anyone know if this is going to work smooth-as-butter on plain old Raspian as well? Seems to me like supporting RaspberryPi ā€œout of the boxā€ would be wise ā€¦