CLI compilation in Docker

I’m interested in setting up a Docker container for compiling our Mbed application. We’ve used CLI 1 for two years now without any real compilation issues. Mbed 5.15 and the ARM GCC 2019 compiler. So I made a Dockerfile based on this one: with some minor additions to copy in our sources and with a newer version of CMake. The image builds ok and runs ok, but compiling anything in it does not really proceed according to plan. Building gives a few thousand errors like this:

root@e3248872c6f7:~# mbed compile -vv
[mbed-90] Working path "/root" (program)
[mbed-90] Exec "/usr/bin/python3 -m pip list -l" in "/root"
Package            Version
------------------ -----------
appdirs            1.4.4
asn1ate            0.6.0
beautifulsoup4     4.6.3
cbor               1.0.0
cffi               1.14.5
Click              7.0
cmsis-pack-manager 0.2.10
colorama           0.3.9
cryptography       2.9.2
ecdsa              0.16.1
fasteners          0.16
future             0.18.2
gitdb              4.0.5
GitPython          3.1.13
icetea             1.2.4
idna               2.7
intelhex           2.3.0
Jinja2             2.10.3
jsonmerge          1.8.0
jsonschema         2.6.0
junit-xml          1.8
lockfile           0.12.2
Mako               1.1.4
manifest-tool      1.5.2
Markdown           3.3.3
MarkupSafe         1.1.1
mbed-cli           1.10.5
mbed-cloud-sdk     2.0.8
mbed-flasher       0.10.1
mbed-greentea      1.8.4
mbed-host-tests    1.8.4
mbed-ls            1.8.4
mbed-os-tools      1.8.4
mbed-tools         6.1.0
milksnake          0.1.5
pdoc3              0.9.2
prettytable        0.7.2
protobuf           3.5.2.post1
psutil             5.6.6
pyasn1             0.2.3
pycparser          2.20
pycryptodome       3.10.1
pyelftools         0.25
pyparsing          2.4.7
pyserial           3.4
python-dateutil    2.8.1
python-dotenv      0.15.0
pyudev             0.22.0
PyYAML             4.2b1
requests           2.20.1
semver             2.13.0
six                1.12.0
smmap              3.0.5
soupsieve          2.2
tabulate           0.8.7
tqdm               4.56.2
urllib3            1.24.2
wcwidth            0.2.5
yattag             1.14.0
[mbed-90] WARNING: Missing Python modules were not auto-installed.
       The Mbed OS tools in this program require the following Python modules: pyusb
       You can install all missing modules by running "pip install -r requirements.txt" in "/root/mbed-os"
       On Posix systems (Linux, etc) you might have to switch to superuser account or use "sudo"
[mbed-90] Exec "/usr/bin/python3 -u /root/mbed-os/tools/ -t GCC_ARM -m LPC1768 --source . --build ./BUILD/LPC1768/GCC_ARM -v" in "/root"
Building project root (LPC1768, GCC_ARM)
Scan: root
Using ROM regions bootloader, application in this build.
  Region bootloader: size 0x20000, offset 0x0
  Region application: size 0x60000, offset 0x20000
Compile [  0.1%]: 7SegmentDisplay.cpp
[Error] check_config.h@39,2: #error "mbed TLS requires a platform with 8-bit chars"
[Error] cstdint@63,11: '::int8_t' has not been declared
[Error] cstdint@64,11: '::int16_t' has not been declared
[Error] cstdint@65,11: '::int32_t' has not been declared
[Error] cstdint@66,11: '::int64_t' has not been declared
[Error] cstdint@68,11: '::int_fast8_t' has not been declared
[Error] cstdint@69,11: '::int_fast16_t' has not been declared
[Error] cstdint@70,11: '::int_fast32_t' has not been declared
[Error] cstdint@71,11: '::int_fast64_t' has not been declared
[Error] cstdint@73,11: '::int_least8_t' has not been declared
[Error] cstdint@74,11: '::int_least16_t' has not been declared
[Error] cstdint@75,11: '::int_least32_t' has not been declared
[Error] cstdint@76,11: '::int_least64_t' has not been declared
[Error] cstdint@78,11: '::intmax_t' has not been declared
[Error] cstdint@79,11: '::intptr_t' has not been declared
[Error] cstdint@81,11: '::uint8_t' has not been declared
[Error] cstdint@82,11: '::uint16_t' has not been declared
[Error] cstdint@83,11: '::uint32_t' has not been declared
[Error] cstdint@84,11: '::uint64_t' has not been declared
[Error] cstdint@86,11: '::uint_fast8_t' has not been declared
[Error] cstdint@87,11: '::uint_fast16_t' has not been declared
[Error] cstdint@88,11: '::uint_fast32_t' has not been declared
[Error] cstdint@89,11: '::uint_fast64_t' has not been declared
[Error] cstdint@91,11: '::uint_least8_t' has not been declared
[Error] cstdint@92,11: '::uint_least16_t' has not been declared
[Error] cstdint@93,11: '::uint_least32_t' has not been declared
[Error] cstdint@94,11: '::uint_least64_t' has not been declared
[Error] cstdint@96,11: '::uintmax_t' has not been declared
[Error] cstdint@97,11: '::uintptr_t' has not been declared
[Error] cmsis_os2.h@77,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@78,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@235,9: 'uint32_t' does not name a type
[Error] cmsis_os2.h@242,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@244,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@246,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@248,3: 'TZ_ModuleId_t' does not name a type
[Error] cmsis_os2.h@249,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@255,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@257,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@263,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@265,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@271,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@273,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@279,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@281,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@287,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@289,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@291,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@297,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@299,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@301,3: 'uint32_t' does not name a type
[Error] cmsis_os2.h@316,65: 'uint32_t' has not been declared
[Error] cmsis_os2.h@328,1: 'int32_t' does not name a type
[Error] cmsis_os2.h@332,1: 'int32_t' does not name a type
[Error] cmsis_os2.h@337,1: 'int32_t' does not name a type
[Error] cmsis_os2.h@341,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@345,22: variable or field 'osKernelResume' declared void
[Error] cmsis_os2.h@345,22: 'uint32_t' was not declared in this scope
[Error] cmsis_os2.h@349,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@353,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@357,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@361,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@390,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@395,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@442,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@448,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@457,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@462,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@466,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@473,1: 'uint32_t' does not name a type
[Error] cmsis_os2.h@481,21: 'uint32_t' was not declared in this scope

From what I can see the commandline used to compile is more or less identical to the one that gets used when compiling on my Mac. The compiler is the same, although it’s the Linux version for Docker of course. The compiler works when I try to compile something simple, like helloworld.c, so it’s at least working and somewhat working. I also tried to compile with Mbed master and CLI 1, but it all fails similarly.

Has anyone seen anything similar?

Well, apparently the CLI build system is the buggy culprit here. You can not have your sources in the same directory as the ARM compiler, as the build system apparently picks up stuff from the gcc-arm-none-eabi-9-2019-q4-major directory, even though I haven’t told it to. The solution is to at least create a sub directory for your project so that the ARM compiler is at least ../gcc-arm-none-eabi-9-2019-q4-major and not findable to tbe build system.

That was a great day of wasted time, but perhaps someone else that tries the same approach can find this post and save some time.


the scanning for sourcefiles makes the CLI very conveniant, you do not have to include them by yourself. But the ‘danger’ was always to include e.g. some sample or test code. In foreign libs, you can add .mbedignore to exclude unwanted sources.
For the dockerfile, I think also its a better idea to move the gcc toolchain to /opt or some other standard linux dir for this.
But I also would always use a home/projects dir for the different projects.
You should open an issue for this.