Eclipse and mbed: Managed makefile project

10 Nov 2015

I'm trying to configure an Eclipse project for my LPC1768-based Ublox C027 with the following requirements:

  • It should not be based on a sample project exported from the online mbed compiler, as those include pre-built objects, and only the mbed headers required for the current state of that project.
  • gcc4mbed should not be used because automatic version control of the mbed source code is not possible.
  • mbed sources shall instead be kept in a separate project under git version control.
  • Instead of importing and manually modifying makefiles from sample projects, I'd like to create a base Eclipse project with automatic makefile creation and keep it in git, from which we (my co-workers and myself, and maybe many other people) can easily fork whenever a new mbed-based Eclipse project is started.

I'm working in the following environment (installation described here in great detail: https://gnuarmeclipse.github.io/):

  • Windows 7x64 (shouldn't matter)
  • Eclipse Luna 4.4.2 CDT with GNU ARM Eclipse plugins
  • GNU ARM Eclipse build tools 2.6-201507152002
  • GNU Tools ARM Embedded 4.9 2015q3

My Eclipse's Project Explorer is now looking like this:

/media/uploads/guarndt/eclipseprojects.jpg

The 'mbed' project has been cloned via git and imported to Eclipse without a build configuration or something alike - I'm trying to include it to other Projects by adding its subfolders to the include path there.

/media/uploads/guarndt/mbedprojectsettings.png

As found out here, it seems to be impossible to use the project template 'Hello World ARM Cortex-M C/C++ Project' provided with GNU ARM Eclipse, as it includes unistd.h, which conflicts with mbed: https://developer.mbed.org/forum/bugs-suggestions/topic/17173/

Thus, I'm trying to create a project starting from a simple C++ project in Eclipse, with the GNU ARM toolchain. I've so far tried to replicate the settings from the Makefile taken from a project exported from mbed online, but some settings remain unclear. For example, I get this warning:

c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: 
warning: 
cannot find entry symbol Reset_Handler; defaulting to 00000000

The Reset_Handler, as far as my humble understanding reaches, should have been defined by the linker script? Another Problem is that the bin file has only 128 Bytes, whereas the elf file has 35 KB.

You can download my Eclipse project /media/uploads/guarndt/c027_base_simple.zip, but you must not forget to add an 'mbed' project cloned from https://github.com/mbedmicro/mbed to your workspace in addition. I suggest to start with a look at 'C/C++ Build -> Settings -> Tool Settings' in the project's properties.

In general, I have to admit that I'm not sure if my approach of adding the mbed headers as a separate project without a build configuration (maybe as a static library) can work, but I hope that I've only missed a few smaller problems which one of you guys might spot. I'm looking forward to your suggestions - thank you in advance.

13 Nov 2015

I could help myself: Compiling mbed with the included Python script as described in https://developer.mbed.org/teams/SDK-Development/wiki/Mbed-SDK-build-script-introduction with

python build.py -m UBLOX_C027 -t GCC_ARM

and adding the created binaries to the Eclipse project as shown in the following screenshot did the trick:

/media/uploads/guarndt/mbedprojectsettings2.png

It shouldn't be very difficult to adapt this approach for other devices, but it has the obvious disadvantage that it depends on Eclipse - manually created Makefiles, like those used in gcc4mbed, are IDE independent.

18 Nov 2015

Hi again,

I expect to stumble over a tumbleweed each time I come around. Do the cool kids play elsewhere? If so, please let me know ;-)

Or maybe they just don't use Eclipse, who knows...?

However, I'm still trying to complete my mbed Eclipse project described previously. You can download its current working state: /media/uploads/guarndt/c027_base_simple.zip

Please note that you have to check out mbed, compile it as described in the previous post, and import it as a Makefile-based Eclipse project named 'mbed' to fulfill my C027 base project's dependencies. Alternatively, you can add this tiny .project file to your mbed folder and import it to Eclipse: /media/uploads/guarndt/.project.

Your Eclipse Project Explorer should look something like this:

/media/uploads/guarndt/project.jpg

Now, to get to the point, the remaining problem with my project is that I cannot use stuff from the C++ standard library. The following program works fine as long as no object from the libstdc++ is constructed (note the comment in the code):

#include <string>
#include <mbed.h>

std::string str("LED"); // causes linker to fail

int main() {
    DigitalOut led(LED);
    while (true) {
//        printf("%s = %d\n", str.c_str(), led.read());
        led = !led;
        wait(1);
    }
}

If a string, or a vector, or whatever is constructed, or just std::cout is used, linking results in the following error message:

...
C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/board.o C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/cmsis_nvic.o C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/mbed_overrides.o C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/retarget.o C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/startup_LPC17xx.o C:/firedect/git/mbed/build/mbed/TARGET_UBLOX_C027/TOOLCHAIN_GCC_ARM/system_LPC17xx.o -lmbed -lstdc++_nano -lsupc++_nano -lgcc -lnosys -lstdc++_nano -lm -lc_nano --start-group -lgcc -lg_nano -lc_nano --end-group --start-group -lgcc -lc_nano --end-group c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-m/crtend.o c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-m/crtn.o -T C:\firedect\git\mbed\libraries\mbed\targets\cmsis\TARGET_NXP\TARGET_LPC176X\TOOLCHAIN_GCC_ARM\LPC1768.ld
c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libc_nano.a(lib_a-signalr.o): In function `_kill_r':
signalr.c:(.text._kill_r+0xe): undefined reference to `_kill'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libc_nano.a(lib_a-signalr.o): In function `_getpid_r':
signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid'
collect2.exe: error: ld returned 1 exit status
makefile:57: recipe for target 'C027_Base_simple.elf' failed
make: *** [C027_Base_simple.elf] Error 1

17:12:23 Build Finished (took 904ms)

The same error can be provoked by unchecking

Remove unused sections (-Xlinker --gc-sections)

in the linker settings, or by unchecking

Do not use exceptions (-fno-exceptions)

in the C++ compiler settings. Otherwise, I've tried to replicate the settings from the Makefile provided with the C027 Hello World project exported from the mbed online compiler as closely as possible. As using C++ stuff in that project works no problem, I guess I've missed something setting up my project. I know, it's a lot to read, but maybe there are other people interested in using Eclipse, and another pair of eyes to review my stuff would be of great help. Thank you for reading till here, and for any suggestion to come.

18 Nov 2015

Dear Gunnar Arndt,

I've just answered to the similar question here https://developer.mbed.org/forum/mbed/post/40272/

PlatformIO can be integrated to Eclipse IDE too. Also, take a look into this manual "Improvised" FRDM-K64F Eclipse/Platformio Setup

Regards, Ivan.

http://thomasweldon.com/tpw/courses/embeddsp/frdmK64_eclipsePlatformio_Debug2.jpg http://docs.platformio.org/en/latest/_images/ide-platformio-eclipse.png

19 Nov 2015

Hi Ivan,

thank you for your hint. I've successfully installed PlatformIO and found a small problem - the Eclipse project's PATH variable looked like this, preventing the 'platformio' script to be found:

...;C:\Program Files\Python27\;&quot;C:\Program Files\Python27\Scripts&quot;

That may have been caused by my environment and could easily be fixed.

I like that PlatformIO downloads libraries and stuff to the user's home, not to the project, allowing to recycle it for multiple projects.

However, I have a similar problem as before: As soon as I use something from iostream, building fails with the following message:

12:39:54 **** Incremental Build of configuration Default for project C027_PlatformIO_HelloWorld ****
platformio -f -c eclipse run 
[11/19/15 12:39:55] Processing ubloxc027 (platform: nxplpc, targets: upload, framework: mbed, board: ubloxc027)

arm-none-eabi-g++ -o .pioenvs\ubloxc027\src\main.o -c -std=gnu++98 -fno-rtti -fdata-sections -ffunction-sections -Wno-unused-parameter -fno-exceptions -Wextra -fno-delete-null-pointer-checks -fmessage-length=0 -mthumb -Wno-missing-field-initializers -c -fno-builtin -O2 -fomit-frame-pointer -Wall -MMD -mcpu=cortex-m3 -DTARGET_FF_ARDUINO -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_CORTEX_M -DTARGET_LPC176X -DTARGET_NXP -DARM_MATH_CM3 -DMBED_BUILD_TIMESTAMP=1441270533.12 -DTARGET_LPC1768 -D__CORTEX_M3 -DTARGET_UBLOX_C027 -DTARGET_M3 -D__MBED__=1 -DPLATFORMIO=020305 -I.pioenvs\ubloxc027\FrameworkMbedInc248832578 -I.pioenvs\ubloxc027\FrameworkMbedInc-213564679 -I.pioenvs\ubloxc027\FrameworkMbedInc-250686161 -I.pioenvs\ubloxc027\FrameworkMbedInc-1127856032 -I.pioenvs\ubloxc027\FrameworkMbedInc-1237439628 -I.pioenvs\ubloxc027\FrameworkMbedInc1677912003 -I.pioenvs\ubloxc027\FrameworkMbedInc3792846 -I.pioenvs\ubloxc027\FrameworkMbedInc-707181728 src\main.cpp
arm-none-eabi-g++ -o .pioenvs\ubloxc027\firmware.elf -Wl,--gc-sections -Wl,--wrap,main -mcpu=cortex-m3 -mthumb --specs=nano.specs "-u _printf_float" "-u _scanf_float" -Wl,-T C:\Users\guarndt\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\LPC1768.ld .pioenvs\ubloxc027\src\main.o -LC:\Users\guarndt\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM -L.pioenvs\ubloxc027 -Wl,--start-group -lc -lgcc -lm -lstdc++ -lsupc++ -lnosys -lmbed -lc -lgcc .pioenvs\ubloxc027\libFrameworkMbed.a -Wl,--end-group
.pioenvs\ubloxc027\libFrameworkMbed.a(retarget.o): In function `__gnu_cxx::__verbose_terminate_handler()':
retarget.cpp:(.text._ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x0): multiple definition of `__gnu_cxx::__verbose_terminate_handler()'
c:/users/guarndt/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libstdc++_s.a(vterminate.o):vterminate.cc:(.text._ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
scons: *** [.pioenvs\ubloxc027\firmware.elf] Error 1
 [ ERROR ] Took 2.18 seconds 
19 Nov 2015

Dear Gunnar Arndt,

Which version of PlatformIO do you use? We've just re-tested your example(including Eclipse IDE) and didn't find any problems.

See the output of this code

#include <string>
#include <mbed.h>
 
std::string str("LED"); // causes linker to fail
 
int main() {
    DigitalOut led(LED);
    while (true) {
		printf("%s = %d\n", str.c_str(), led.read());
        led = !led;
        wait(1);
    }
}

platformio run
[11/19/15 17:07:30] Processing ubloxc027 (platform: nxplpc, board: ubloxc027, framework: mbed)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- arm-none-eabi-g++ -o .pioenvs\ubloxc027\src\main.o -c -std=gnu++98 -fno-rtti -fdata-sections -ffunction-sections -Wno-unused-parameter -fno-exceptions -Wextra -fno-delete-null-pointer-checks -fmessage-length=0 -mthumb -Wno-missing-field-initializers -c -fno-builtin -O2 -fomit-frame-pointer -Wall -MMD -mcpu=cortex-m3 -DTARGET_FF_ARDUINO -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_CORTEX_M -DTARGET_LPC176X -DTARGET_NXP -DARM_MATH_CM3 -DMBED_BUILD_TIMESTAMP=1441270533.12 -DTARGET_LPC1768 -D__CORTEX_M3 -DTARGET_UBLOX_C027 -DTARGET_M3 -D__MBED__=1 -DPLATFORMIO=020400 -I.pioenvs\ubloxc027\FrameworkMbedInc248832578 -I.pioenvs\ubloxc027\FrameworkMbedInc-213564679 -I.pioenvs\ubloxc027\FrameworkMbedInc-250686161 -I.pioenvs\ubloxc027\FrameworkMbedInc-1127856032 -I.pioenvs\ubloxc027\FrameworkMbedInc-1237439628 -I.pioenvs\ubloxc027\FrameworkMbedInc1677912003 -I.pioenvs\ubloxc027\FrameworkMbedInc3792846 -I.pioenvs\ubloxc027\FrameworkMbedInc-707181728 src\main.cpp
arm-none-eabi-ar rcs .pioenvs\ubloxc027\libFrameworkMbed.a C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\startup_LPC17xx.o C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\cmsis_nvic.o C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\system_LPC17xx.o C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\mbed_overrides.o C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\retarget.o C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\board.o
arm-none-eabi-ranlib .pioenvs\ubloxc027\libFrameworkMbed.a
arm-none-eabi-g++ -o .pioenvs\ubloxc027\firmware.elf -Wl,--gc-sections -Wl,--wrap,main -mcpu=cortex-m3 -mthumb --specs=nano.specs "-u _printf_float" "-u _scanf_float" -Wl,-T C:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM\LPC1768.ld .pioenvs\ubloxc027\src\main.o -LC:\Users\ROOT\.platformio\packages\framework-mbed\variant\UBLOX_C027\mbed\TARGET_UBLOX_C027\TOOLCHAIN_GCC_ARM -L.pioenvs\ubloxc027 -Wl,--start-group -lc -lgcc -lm -lstdc++ -lsupc++ -lnosys -lmbed -lc -lgcc .pioenvs\ubloxc027\libFrameworkMbed.a -Wl,--end-group
arm-none-eabi-objcopy -O binary .pioenvs\ubloxc027\firmware.elf .pioenvs\ubloxc027\firmware.bin
"arm-none-eabi-size" -B -d .pioenvs\ubloxc027\firmware.elf
text       data     bss     dec     hex filename
11880       124     572   12576    3120 .pioenvs\ubloxc027\firmware.elf
======================================================================================================== [SUCCESS] Took 1.59 seconds ========================================================================================================

Regards Ivan.

20 Nov 2015

Ivan,

thank you for the quick response. The given example compiles no problem indeed. As mentioned, the problems arise when using iostream:

#include <iostream>
#include <mbed.h>

int main() {
    DigitalOut led(LED);
    while (true) {
//        printf("%s = %d\n", str.c_str(), led.read());
        std::cout << led.read();
        led = !led;
        wait(1);
    }
}

Maybe I'll never need iostream in my project, but a member of the standard library causing problems makes me suspicious - they might appear elsewhere at the wrong time...

I'm using the latest version of PlatformIO, as I've just installed, following your initial suggestion. 'platformio update' says it's up to date.

20 Nov 2015

Dear Gunnar Arndt,

I recommend you to create separate issue with this problem. It looks like "mbed"-related issue, while the subject of this topic is "Eclipse and mbed: Managed makefile project"

Regards, Ivan Kravets

23 Nov 2015

Dear Ivan,

as the project exported from the mbed online compiler works fine, this does not seem to be an mbed issue. There are similar problems which only occur with my Eclipse-approach and PlatformIO: The inclusion of <iostream> fails, and I have no idea, why it fails.

Maybe someone else has one?

23 Nov 2015

Hi Gunnar,

I've tried to compile your last example in the mbed online compiler, but I have the following errors:

Error: Undefined symbol __fread_bytes_avail (referred from ios.o).
Error: Undefined symbol mbsinit (referred from ios.o).
Error: Undefined symbol wmemmove (referred from ios.o).
23 Nov 2015

Valeriy,

thank you for testing, but I cannot confirm your observation - I've copied the code from the last example back to my copy of the 'C027 Hello World' project in the mbed online compiler, and it compiles successfully. You can acquire it here: https://developer.mbed.org/users/guarndt/code/C027_HelloWorld_iostream/