adef files & c++

Hiya,

This is for those trying to use C++ in the Legato environment.

I’ve just found that the adef parser doesn’t like C++ files (i.e. files with the extensions .cc or .cpp) when configuring the project executables. This was a problem for me as the application I’m porting across to the Legato is based around a C++ class that contains all the application logic.

I did find a workaround:

I turned my application into a static library (using a separate DS3 project - note the bug in DS3 that doesn’t let you create a 'static library project - create a normal C++ project then change the Target type after creation). I also removed the code for ‘main()’ from my library.

Inside my library, I wrote a ‘factory’ function to instantiate my class and return a void pointer to it. I also wrote wrapper functions for the class public member functions so that they could be called from C. Finally, I wrapped the appropriate functions in 'extern “C” {} ’ so that the names wouldn’t be mangled by the compilers and linker.

I then turned main() into the Legato ‘main()’ - using COMPONENT_INIT { } and referencing my application class via the wrapper functions in the library.

Finally, I added both my static library AND the yocto stdlib++ static library to my adef definitions like so:executables: MyApp ( "legato_main.c" "libMyAppLib.a" "/opt/swi/y14-ext/tmp/sysroots/swi-mdm9x15/usr/lib/libm.a" "/opt/swi/y14-ext/tmp/sysroots/swi-mdm9x15/usr/lib/libstdc++.a" "/opt/swi/y14-ext/tmp/sysroots/swi-mdm9x15/usr/lib/libz.a" )

and all is sweet :smiley:

Note that I had to use the full path to the cross-compiler system libs … the adef parser can’t find them otherwise.

ciao, Dave

Mmmm, I guess that we should:

  • As a minimum, provide an environment variable (or any other convenient way) to allow pointing on the toolchain provided libs in the adef
  • Provide a way to toggle on C++ support in the adef (and Component.cdef) files (automatically as soon as a C++ source file is included in the list?)

Hi daav,

Adding both of these would be a good idea. Building an environment variable at runtime sure beats hardcoding paths!

For me, getting C++ support in the adef files is probably slightly more important/useful than the environment variable (I can live with the hardcoded paths).

ciao, Dave

Out of curisoity, what revision of C++ are you using? Are you using C++11?

One of the things we’re thinking of doing is adding a C++11 compatablity header to add support for creating C++ objects using memory pools and enable use of lambdas as callbacks. Among other things.

I don’t have a timeline on this, but since you are already using C++ some real world info would be really helpful.

Thanks,
-Kelly

Hi, David,

Thanks for pushing the envelope and trying new things. We plan to do C++ support, but haven’t got around to it yet. (So much to do!) Your input on this is a big help.

The ‘mk’ tools (mkexe, mkapp) detect the source code language based on the file name extension. That’s missing the checks for the various C++ file name extensions.

I think we should be able to fix this fairly easily. We’ll look into it.

Thanks again!

–Jen

Hiya,

Thanks all for the info and thoughts.

We’re not using any of the fancy bits of C++ - just using it to provide enforced object orientation and encapulation of data where it is required - mostly around protocol state machine handling and I/O devices.

Whoa! Way over my head here! I’m a hardware engineer that programs - not a programmer that does hardware… although I guess I need to learn some more.

No probs. As we find things I’ll keep feeding them up to the forum.

It’s exciting to be working on this stuff - I like to push it hard and It’s nice that you guys are so responsive when I hit a wall. There’s always plenty to do …

Sounds like an easy fix. Well, easy to talk about anyway.

Cool. If you want any more info, let me know.

ciao, Dave

Hello David,

Jen and I took a look at this. Like Jen said, the mktools were rejecting the C++ because of it’s extension.

I’ve also modified the tools to automaticly pull in the C++ standard lib. And I added some extern “C” definitions to the header files. So the result of this is that it will be easer to use C++ in Legato, for example, yet another hello world, but now in C++:

“helloPP.adef”

executables:
    hello ( hello.cpp )

processes:
    run: (hello)

“hello.cpp”

#include "legato.h"
#include <sstream>

COMPONENT_INIT
{
    std::stringstream buffer;

    buffer << "Hello world, #" << 1024 << ".";
    LE_INFO("%s", buffer.str().c_str());
}

I’ve pushed the changes into our internal review system, so this should make it to GitHub for our next milestone.

Thanks a lot for finding this!

-Kelly

Hiya,

WOW! That’s quick work! Look forward to getting the next release.

No problems - if I find more, I’ll let you know.

One question - while you’re working on this, can you make the adef parser manage C++ files with the .cc extension as well as .cpp? I’m test porting code from other platforms to the Legato, and a lot of the code has .cc as the file extension. GCC doesn’t really care - it processes .cc as C++ by default.

I’m impressed!

Thanks, Dave

Hey David,

Already done! We actually followed GCC’s example and the tools will now see all of the following as C++:

.cc
.cp
.cxx
.cpp
.c++
.C
.CPP

Edit: Missed .CC in my list.

-Kelly

Hi Kelly,

Great minds think alike :question:

Ta, Dave

Hi Kelly,

Could you please tell us when the new adef parser will be available?

Thanks, Andrea

The current plan is to have this in for the end of July.

Hi everyone,

I’m trying to implement a small C++ sample but get the following error when building the app:

mkapp -t wp76xx helloCPP.adef
[1/1] Regenerating build script
[3/9] Compiling C++ source
FAILED: _build_helloCPP/wp76xx/component/b130cd0656327c8de99a44179d5831dc/obj/4c01286321aa8b611d1cea84c8618f67.o
/home/mangoh/workspace/leaf-data/wp76stable/wp76-toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ --sysroot=/home/mangoh/workspace/leaf-data/wp76stable/wp76-toolchain/sysroots/armv7a-neon-poky-linux-gnueabi -MMD -MF _build_helloCPP/wp76xx/component/b130cd0656327c8de99a44179d5831dc/obj/4c01286321aa8b611d1cea84c8618f67.o.d -c /home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp -o _build_helloCPP/wp76xx/component/b130cd0656327c8de99a44179d5831dc/obj/4c01286321aa8b611d1cea84c8618f67.o -DLE_FILENAME=basename /home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp -Wall -fPIC -Werror -fvisibility=hidden -DMK_TOOLS_BUILD -DLEGATO_EMBEDDED -I ./_build_helloCPP/wp76xx -I/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/interfaces -I/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/framework/include -I/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP -I./_build_helloCPP/wp76xx/component/b130cd0656327c8de99a44179d5831dc/src -DLE_COMPONENT_NAME=helloCPPComponent -DLE_LOG_SESSION=helloCPPComponent_LogSession -DLE_LOG_LEVEL_FILTER_PTR=helloCPPComponent_LogLevelFilterPtr “-DCOMPONENT_INIT=LE_CI_LINKAGE LE_SHARED void _helloCPPComponent_COMPONENT_INIT()”
:0:16: error: ‘LE_CI_LINKAGE’ does not name a type; did you mean ‘LE_FILENAME’?
/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp:7:1: note: in expansion of macro ‘COMPONENT_INIT’
COMPONENT_INIT{
^~~~~~~~~~~~~~
/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp: In function ‘int greet()’:
/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp:11:5: error: ambiguating new declaration of ‘int greet()’
int greet() {
^~~~~
/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp:5:6: note: old declaration ‘void greet()’
void greet(void);
^~~~~
/home/mangoh/workspace/leaf-data/wp76stable/fx30-cat1-legato/apps/helloCPP/helloCPPComponent/helloCPP.cpp:14:1: error: no return statement in function returning non-void [-Werror=return-type]
}
^
cc1plus: all warnings being treated as errors

#include <iostream>
using namespace std;

void greet(void);

COMPONENT_INIT{ 
    greet();
}

void greet() {
  cout << "Hello World!";
  return;
}

What am I doing wrong? Any help is greatly appreciated.