C++ Usage Issues - Problems, Solutions, and Suggestions

Robert S. Grimes rsg at alum.mit.edu
Thu Jun 21 14:03:05 UTC 2007


Hello,

I'm using RTEMS to develop a three processor system, and I'd like to use
C++ for my application development; not trying to get too fancy, but I
do like some of the "better C" type features of C++.  Anyway, I decided
to see what needs to be changed to make a simple C application compile,
link, and of course, run when built as a C++ application.

<WARNING>This email is rather long and tedious, and does not represent a
pressing problem.  For those too busy, feel free to exit now.  Or if you
just want the summary, skip ahead to SUMMARY, as there are two
conclusions that I (finally) make!</WARNING>

So, I simply copied the netdemo program  from the networking demos,
renamed the .c files to .cc, and changed the C_PIECES to CC_PIECES in th
Makefile.  Next, of course, I modified the networkconfig.h
appropriately.  Here is what I found.

1.  First attempt at make:

    $ make
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/init.o init.cc
    init.cc:42:22: error: confdefs.h: No such file or directory
    init.cc: In function 'rtems_task Init(rtems_task_argument)':
    init.cc:59: error: 'exit' was not declared in this scope
    make: *** [o-optimize/init.o] Error 1

The first error is a bug from the original init.c, and seems to exist in
many places in the network demos.  This line

    #include <confdefs.h>

needs to be changed to this:

    #include <rtems/confdefs.h>

The second error is fixed most appropriately by adding to init.cc:

    #include <stdlib.h>

2. Second attempt at make:

    $ make
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/init.o init.cc
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/test.o test.cc
    test.cc: In function 'void showbroad(int)':
    test.cc:39: error: invalid conversion from 'int*' to 'socklen_t*'
    test.cc:39: error:   initializing argument 5 of 'int getsockopt(int,
    int, int, void*, socklen_t*)'
    test.cc: In function 'void echoServer(short unsigned int)':
    test.cc:227: error: invalid conversion from 'int*' to 'socklen_t*'
    test.cc:227: error:   initializing argument 3 of 'int accept(int,
    sockaddr*, socklen_t*)'
    make: *** [o-optimize/test.o] Error 1

This is fixed by changing the definitions of optlen and addrlen from int
to socklen_t, and a few typecasts when they are used as integers.

3. Third attempt at make:

    $ make
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/init.o init.cc
    powerpc-rtems-gcc --pipe -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/
    -specs bsp_specs -qrtems   -g -Wall  -O4 -fno-keep-i
    nline-functions -g -g      -mcpu=403 -Dppc405 -Dvirtex         -o
    o-optimize/netdemo.exe   o-optimize/init.o o-optimize/
    test.o  /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-dpmem.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-msg.rel /usr/rte
    ms/4.8/powerpc-rtems/virtex/lib/no-mp.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-part.rel
    /usr/rtems/4.8/powerpc-rte
    ms/virtex/lib/no-signal.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-timer.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib
    /no-rtmon.rel
    o-optimize/init.o:(.eh_frame+0x11): undefined reference to
    `__gxx_personality_v0'
    o-optimize/test.o: In function `showStatistics':
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:49:
    undefined reference
     to `rtems_bsdnet_show_inet_routes()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:50:
    undefined reference
     to `rtems_bsdnet_show_mbuf_stats()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:51:
    undefined reference
     to `rtems_bsdnet_show_if_stats()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:52:
    undefined reference
     to `rtems_bsdnet_show_ip_stats()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:53:
    undefined reference
     to `rtems_bsdnet_show_icmp_stats()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:54:
    undefined reference
     to `rtems_bsdnet_show_udp_stats()'
    /cygdrive/c/Home/ll/etill/development/apps/experiments/network-demos-4.7.99.1/netdemo-cc/test.cc:55:
    undefined reference
     to `rtems_bsdnet_show_tcp_stats()'
    o-optimize/test.o:(.eh_frame+0x11): undefined reference to
    `__gxx_personality_v0'
    collect2: ld returned 1 exit status
    make: *** [o-optimize/netdemo.exe] Error 1

There are really only two problems here.  First, the
__gxx_personality_v0 error (apparently) comes from a missing C++
library, and is fixed by adding -lstdc++ to LD_LIBS in the Makefile:

    LD_LIBS   += -lstdc++

The other errors are due to the rtems/rtems_bsdnet.h header file, and
can be eliminated by changing the inclusion of this file like this:

    extern "C" {
    #include <rtems/rtems_bsdnet.h>
    }

4. Fourth attempt at make - success!

    $ make
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/test.o test.cc
    powerpc-rtems-gcc --pipe -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/
    -specs bsp_specs -qrtems   -g -Wall  -O4 -fno-keep-i
    nline-functions -g -g      -mcpu=403 -Dppc405 -Dvirtex         -o
    o-optimize/netdemo.exe   o-optimize/init.o o-optimize/
    test.o  /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-dpmem.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-msg.rel /usr/rte
    ms/4.8/powerpc-rtems/virtex/lib/no-mp.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-part.rel
    /usr/rtems/4.8/powerpc-rte
    ms/virtex/lib/no-signal.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-timer.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib
    /no-rtmon.rel -lstdc++
    powerpc-rtems-objcopy -O srec o-optimize/netdemo.exe
    o-optimize/netdemo.srec
    powerpc-rtems-nm -g -n o-optimize/netdemo.exe > o-optimize/netdemo.num
    powerpc-rtems-size o-optimize/netdemo.exe
       text    data     bss     dec     hex filename
     413052   12048   61308  486408   76c08 o-optimize/netdemo.exe

However, this application doesn't work!  Here is the output on the console:

    Exception handling initialization done
    opb_intc_init: mask = 0x7
    rtems_glue: Waiting for time

This is because, in init.cc, there are these obsolete lines:

    #define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
    #define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER

Changing them to this fixes the problem:

    #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
    #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

Note - the fact that we got any output at all without the console driver
is just a happy accident with the virtex BSP.

5. Fifth attempt - working application!!!  Clean make output:

    $ make
    test -d o-optimize || mkdir o-optimize
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/init.o init.cc
    powerpc-rtems-g++ -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/ -specs
    bsp_specs -qrtems   -g -Wall  -g    -mcpu=403 -Dppc4
    05 -Dvirtex      -c   -o o-optimize/test.o test.cc
    powerpc-rtems-gcc --pipe -B/usr/rtems/4.8/powerpc-rtems/virtex/lib/
    -specs bsp_specs -qrtems   -g -Wall  -O4 -fno-keep-i
    nline-functions -g -g      -mcpu=403 -Dppc405 -Dvirtex         -o
    o-optimize/netdemo.exe   o-optimize/init.o o-optimize/
    test.o  /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-dpmem.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-msg.rel /usr/rte
    ms/4.8/powerpc-rtems/virtex/lib/no-mp.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-part.rel
    /usr/rtems/4.8/powerpc-rte
    ms/virtex/lib/no-signal.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib/no-timer.rel
    /usr/rtems/4.8/powerpc-rtems/virtex/lib
    /no-rtmon.rel -lstdc++
    powerpc-rtems-objcopy -O srec o-optimize/netdemo.exe
    o-optimize/netdemo.srec
    powerpc-rtems-nm -g -n o-optimize/netdemo.exe > o-optimize/netdemo.num
    powerpc-rtems-size o-optimize/netdemo.exe
       text    data     bss     dec     hex filename
     415228   12100   61292  488620   774ac o-optimize/netdemo.exe

Console output:

    Exception handling initialization done
    opb_intc_init: mask = 0x7
    rtems_glue: Waiting for time
    rtems_glue: Done waiting for time
    xiltemac: Creating shared RX/TX threads
    xiltemac: Initializing driver for 'eth0'
    xiltemac: base address 0x81200000, intnum 0x00,
    xiltemacStart, default linkspeed: 84000000
    xiltemacStart, new linkspeed:     44000000
    xiltemac: xiltemacStart, ipier: 00007F0E
    Destination     Gateway/Mask/Hw    Flags     Refs     Use Expire
    Interface
    default         192.168.0.27       UGS         0        0      0 eth0
    192.168.0.0     255.255.255.0      U           0        0      1 eth0
    192.168.0.27                       UHL         1        0      1 eth0
    Create socket.
    Bind socket.
    Listen.
    Accept.
    Create socket.
    Bind socket.
    Listen.
    Accept.
    u
    Create socket.
    Bind socket.
    Opt:0    Optlen:4
    Opt:32    Optlen:4

SUMMARY:

Two main problems have been encountered that should definitely be addressed.

1. The network-demos-4.7.99.1 are horribly out of date, though the good
news is that the fixes are all minor.  Specifically, there are the easy
ones (change all "CONFIGURE_TEST_xxx" macros to
"CONFIGURE_APPLICATION_xxx" and all "#include <confdefs.h>" to "#include
<rtems/confdefs.h>"), and a few slightly more tedious ones (change some
int variables to socklen_t).  There may be other issues in the other
demo applications that exhibit similar problems.

2. Some header files are not quite ready for C++ compatibility. 
Specifically, this exercise found one, rtems/rtems_bsdnet.h, that does
not include appropriate measures.  Having to type this:

    extern "C" {
    #include <rtems/rtems_bsdnet.h>
    }

is ugly and just plain wrong.  This header, and others like it, should
be modified to use the _BEGIN_STD_C and _END_STD_C appropriately to
encapsulate definitions that the C++ compiler will otherwise mangle. 
Using these macros are better then simply extern "C" { }  approach too,
because they seem to handle the std namespace correctly.

I'm willing to help in whatever way seems appropriate.  I certainly
don't mind reporting other issues as my work progresses.  Please advise
me as to the best approach to balance being helpful against being a PITA.

Thanks,
-Bob



More information about the users mailing list