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