Arm Mbed OS support forum

Mbed compiles and links a lot of unnecessary files

Hi,

I found this trying to speed up the build process. When I start from mbed-os-example-blinky or mbed-os-empty, no matter the target I select, I get a 4-minute compile, with a lot of stuff that I don’t even use.

All Lora drivers, AT command drivers, GSM modem drivers, lwip drivers… and so on.

I thought the problem was .mbedignore so I ignored a lot of stuff from the list, and now I get linker errors. I dug deeper and found that in the BUILD folder, in mbed_config.h there are about 260 defines that I have never set. I guess during the compile-time, these define cause the dependencies to get compiled. But I can’t remove those since mbed_config.h is a generated file.

But there is no way to turn them off? Let’s say for example I want just Mbed that has RTOS and can blink an led, no connectivity whatsoever, no drivers for any OSI layer of communication, no device drivers, no TCP/IP. How can I do that?

And also, as a general opinion - why is this backward? The best I can find to remove those dependencies is to add overrides to mbed_app.json, but I don’t want to write exclusion for everything that I don’t use.

A blinky project should have just whatever is required to - blink a LED on a given OS. And if you want to connect to the LoRA for example, you would build up and add something along “#define USE_LORA” in your config and start with that.

I guess this is a known problem of Mbed and there is a new build system being developed as mentioned in [MBed CLI Alternative] mbed-cmake. In the meantime you can use the bare-metal profile, where you have to indicate which components you want to use explicitly in mbed_app.json, otherwise they don’t get compiled. Downside is of course that you cannot use the RTOS.

BTW, the mbed_config.h is generated after the components are selected, i.e. it does not enable/disable anything. It is just an artifact in this context.

I have tried the Mbed-CMake and it is much much better with Ninja.

But, still what bothers me is those files are still compiled and linked. (30k for a blinky)

I tried to delete fo example Lora drivers from mbed-os so they are not compiled, but then I get Link errors. Both on mbed-cli and mbed-cmake.

I figured that mbed_config is generated after, but my question is - what do I need to change to limit unnecessary defines that end up in there.

Or what is the quickest way to E.g. Remove the Lora support?

Are you sure they are linked? 30K can easily be reached by the RTOS and HAL alone.

Analyze your map file to see what is linked. Mbed generates a HTML file in the build directory where you can see the linked object files and their sizes (albeit with some error margin, as discussed here: https://github.com/ARMmbed/mbed-os/issues/10922)

the 30k are ok incl. RTOS. With RTOS, the leaner newlib-nano (with gcc) cannot be used, its not thread safe. In bare-metal, the blinky will be smaller. But also in bare-metal you will have some basic stuff like timer and IO.

Hmmm

I will check the map in few hours when I come home.

I know that full fledged Freertos wit h almost all features enabled, using blinky example uses about 8k of ROM, and also that I get linker errors when I delete code.

I will get back to you

The default mbed-cmake configuration removes all of the extra features such as cellular and networking. However, it does use the full phat printf() for compatibility’s sake so you can save a few more kB by switching to minimal printf. Also note that GCC’s linker is garbage collecting, so any code not called will be stripped out of the final binary. Because of this, ignoring those extra libraries via .mbedignore is mainly about build time, I don’t think it actually affects the binary size, at least not by very much.

Also, apparently the new official CMake build system (which is coming in the next few months) will separate Mbed into a number of different modules, and you can select for your app which ones you actually need to link to. It should be a huge improvement over the current system!

1 Like

Hi Ante,

Thanks for sharing your experience - first of all I totally agree this is something that clearly needs fixing on our end, this is simply bad UX. Historically this “compile all” system worked pretty well for simple projects but as we’ve added functionality in the OS the overheads have become bigger and bigger.

We’re currently doing a couple things to address this. First, back in Mbed OS 6 we introduced a basic concept of modules to try and reverse this approach as @boraozgen notes. You can actually use this with the RTOS - a basic mbed_app.json would look like:

{
    "requires": ["platform", "drivers", "rtos", "rtos-api"]
}

Beyond that, we’re working on a couple of things to improve the building experience. We’re developing new tools and a new CMake-based build system, and we’re trying to learn as much as we can from the awesome work done around Mbed-CMake!
You can check out the PR here:

And the new tools here:

As you might have noted, the directory structure of Mbed OS has evolved quite a bit recently - we’re trying to componentize the OS a bit more cleanly, and following that we’ll clean-up dependencies between those components. The corresponding CMake work to take advantage of it is happening here:

For instance this is what the dependencies of a BLE example might look like:

target_link_libraries(${APP_TARGET}
    mbed-os
    mbed-os-events
    mbed-os-ble
    mbed-os-ble-cordio
    mbed-os-ble-blue_nrg
)

We’re very keen to get feedback on this work, if you have the chance to check it out and let us know your thoughts we’d love to hear about them.

Cheers,

Don Garnier
Mbed OS Tech Lead

2 Likes

So you are right, I looked at the memory map and it doesn’t link those files.

@donatien I will definitely check it out, in a couple of weeks. The deadline is near and currently, I am crunching so no time now :slight_smile:

Thanks Ante, good luck with the project :slight_smile:!

I haven’t done any Mbed stuff for a bit, so perhaps things are different if you are bang up-to-date, but…

I used mbedignore to reduce build times. It took a bit a fiddling, remove something, break the build, put some subset of it back, repeat.

My .mbedignore also needed updating when directories moved around.

Summary, if you can’t wait for cmake I believe you can do what you want with .mbedignore, it’s just a bit of a pain!