QNX 6.4.1 C++ link error

5 posts / 0 new
Last post
Offline
Last seen: 5 years 10 months ago
Joined: 02/11/2013
Posts: 3
QNX 6.4.1 C++ link error

Hi. I'm just getting started with DDS. I wrote an application that uses DDS on Windows. It ran beautfully. Then I tried to build it for QNX 6.4.1. It compiles, but refuses to link. I end up with:

undefined reference to `DDSDomainParticipantFactory::get_instance()

I am statically linking with -lnddscppz, -lnddscz, and -lnddscorez and don't know what else to link in. It's got to be something simple I'm doing wrong, but I can't figure it out.

I watered it down to try to debug. Here is the remaining program:

#include <ndds/ndds_namespace_cpp.h>int main()
{
DDSDomainParticipantFactory * participant; // = DDSDomainParticipantFactory::get_instance();
return 0;
}

Everything up to the comment compiles and links. If I uncomment the get_instance(), I end up unable to find the singleton at link time. What am I doing wrong? This worked on Windows...

Yes, I beleive my NDDSHOME environment variable is set correctly. And I believe it if finding the link libraries. Here is the relevant portion of my setup:

NDDSHOME  C:\dev\LF\sw_3rdparty\ndds\ndds.5.0.0
INCLUDE   C:\dev\LF\sw_3rdparty\ndds\ndds.5.0.0\include\; C:\dev\LF\sw_3rdparty\ndds\ndds.5.0.0\include\ndds
LIBQNX    C:\dev\LF\sw_3rdparty\ndds\ndds.5.0.0\lib\i86QNX6.4.1qcc_gpp

Actual call to the compiler:

QCC -DRTI_QNX=1 -lang-c++ -I %INCLUDE% -I %INCLUDE%ndds -Wno-unused -fno-strict-aliasing -L%LIBQNX% -lnddscppz -lnddscz -lnddscorez -lm main.cpp -o main.out

Please help me. I can't spend much more time on this basic of a problem. :-)

 

Sincerely,

  Karl

 

 

 

 

Gerardo Pardo's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 06/02/2010
Posts: 589

Hello Karl,

There is something a bit odd with what you are doing. You are mixing the compilaton of a C++ file with the linking of the final executable.

Normally when you use the "-c" option you specify a C++ file as an input and an object (".o") file as an output and no libraries to link as in:
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++ -DRTI_QNX -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c Hello_test.cpp -o Hello_test.o
Then you link the object files. At that point you do not specify the "-c" option, you just list the object files and the libraries to link.
For example this is the output from the makefile that rtiddsgen creates for a simple example created from a  Hello.idl
 
First I creted a simple IDL file containing just one type and put it intio a file called  Hello.idl
 
$ cat Hello.idl
struct Hello { 
    long count; 
};
Then I run rtiddsgen on this file with an option to generate and example for QNX:
 

rtiddsgen -ppDisable -language C++ -namespace  -example i86QNX6.4.1qcc_gpp  Hello.idl

This created some example source code and the makefile:   makefile_i86QNX6.4.1qcc_gpp

With this makefile the compilation was successful and produced the following output: 

$ make -f makefile_Hello_i86QNX6.4.1qcc_gpp 
Checking directory objs
Making directory objs
Checking directory objs/i86QNX6.4.1qcc_gpp
Making directory objs/i86QNX6.4.1qcc_gpp
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/Hello.o -DRTI_QNX   -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c Hello.cxx
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/HelloPlugin.o -DRTI_QNX   -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c HelloPlugin.cxx
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/HelloSupport.o -DRTI_QNX   -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c HelloSupport.cxx
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/Hello_subscriber.o -DRTI_QNX   -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c Hello_subscriber.cxx
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/Hello_publisher.o -DRTI_QNX   -I. -I/home/build/rti/waveworks/ndds500/ndds.4.1/include -I/home/build/rti/waveworks/ndds500/ndds.4.1/include/ndds -c Hello_publisher.cxx
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/Hello_subscriber objs/i86QNX6.4.1qcc_gpp/Hello_subscriber.o objs/i86QNX6.4.1qcc_gpp/Hello.o objs/i86QNX6.4.1qcc_gpp/HelloPlugin.o objs/i86QNX6.4.1qcc_gpp/HelloSupport.o -L/home/build/rti/waveworks/ndds500/ndds.4.1/lib/i86QNX6.4.1qcc_gpp -lnddscppz -lnddscz -lnddscorez -lm -lsocket
 
qcc -V4.3.3,gcc_ntox86 -Y_gpp -lang-c++   -o objs/i86QNX6.4.1qcc_gpp/Hello_publisher objs/i86QNX6.4.1qcc_gpp/Hello_publisher.o objs/i86QNX6.4.1qcc_gpp/Hello.o objs/i86QNX6.4.1qcc_gpp/HelloPlugin.o objs/i86QNX6.4.1qcc_gpp/HelloSupport.o -L/home/build/rti/waveworks/ndds500/ndds.4.1/lib/i86QNX6.4.1qcc_gpp -lnddscppz -lnddscz -lnddscorez -lm -lsocket

As you see the first four calls to qcc compile the ".cxx" files into object files and specify no libraries to link. The last two calls to qcc are doing the linking and specify just the objects and the libraries.

When I tried using your approach of both passing the -c option and libraries to link I do not get any link errors. But I also do not get an executable. I only get an object file... So I am not sure what your QNX command is really doing...

In any case what I would recommend you do is first try to create and example with the makefiles that rtiddsgen generates for you and see it that compiles without errors.  Basically follow the process I described above. Then you can compare the compilation commands of that rtiddsgen-generated makefile with yours and track down the differences.

Regards,

Gerardo

 

Offline
Last seen: 5 years 10 months ago
Joined: 02/11/2013
Posts: 3

Hello Gerardo.
Thank you for the response. I have no objections to compiling and linking separately. Indeed, that's what I tried first, but didn't know enough to make it succeed. Here are the results of my running rtiddsgen as in your example above:

struct Hello {
long count;
};

C:\Users\kmortensen\Desktop\compile_qnx_dds\hello>rtiddsgen -ppDisable -language C++ -namespace -example i86QNX6.4.1qcc_gpp Hello.idl
Running rtiddsgen version 5.0.0, please wait ...
Done

C:\Users\kmortensen\Desktop\compile_qnx_dds\hello>
C:\Users\kmortensen\Desktop\compile_qnx_dds\hello>make -f makefile_Hello_i86QNX6.4.1qcc_gpp
Checking directory objs
C:/Users/KMORTE~1/AppData/Local/Temp/make3564-1.sh: /c/Windows/system32/\: is a directory
Making directory objs
C:/Users/KMORTE~1/AppData/Local/Temp/make3564-1.sh: /c/Windows/system32/\: is a directory
C:/Users/KMORTE~1/AppData/Local/Temp/make3564-1.sh: /c/Windows/system32/\: is a directory
make: *** [objs.dir] Error 127C:\Users\kmortensen\Desktop\compile_qnx_dds\hello>

It appears perhaps there is an issue with my path setup?

For background, I was given the task to benchmark how DDS would affect our current architecture performancewise. (Over my protests that the level of additional overhead was in the noise.)  I created the participants and topics by hand, as demonstrated in the hello_simple example found in ...ndds.5.0.0\example\CPP\Hello_simple.

We have an architecture of many servers talking to each other with IPC in QNX. I created a generic server object and spun up a bunch of instances with vectors of DDS readers and writers on timers that communicate with individual servers at about the right data rate. I did this all in Windows and tested it. It ran beautifully. Then I tried to build targeting QNX 6.4.1 and was unable to build.

I have attached two files showing what I was trying to do. The .cpp file is representative of one of our servers. If I could just make this compile and link for QNX 6.4.1 that would be great.

I think if I were able to build your IDL example for QNX, I would be able to get my non-IDL code building. Can you point me in the right direction?

(Can you access the attachments?)

Thanks for your help.

Sincerely,

Karl

Gerardo Pardo's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 06/02/2010
Posts: 589

Hi Karl,

I see, you are trying to cross-compile from Windows to the QNX target... Sorry for the confusion. The files that rtiddsgen creates for the QNX target are intended for compiling in the QNX target itself.  The makefile could be used to cross-compile from a Linux host, but not from Windows because it does not have the necessary shell the makefile assumes.

Anyway, looking at you compile line I think I figured out what is wrong.  You need to specify the " main.cpp" file ahead the libraries to link to. As in: 

QCC -DRTI_QNX=1 -lang-c++ -I %INCLUDE% -I %INCLUDE%ndds -Wno-unused -fno-strict-aliasing main.cpp -L%LIBQNX% -lnddscppz -lnddscz -lnddscorez -lm -o main.out

Instead of:

QCC -DRTI_QNX=1 -lang-c++ -I %INCLUDE% -I %INCLUDE%ndds -Wno-unused -fno-strict-aliasing -L%LIBQNX% -lnddscppz -lnddscz -lnddscorez -lm main.cpp -o main.out

It seems like if you specify the "main.cpp" file after the libraries the compiler is not pulling out the necessary symbols because it thinks it does not need them, and then when it encounters them in the object created from the "main.cpp" it gives the unresolved symbol error you saw.

Going forward in yoru QNX development, if you wanted to use the makefiles generated by rtiddsgen you have two options:

  1. If your QNX target has a compiler,  you could  copy the  RTI DDS libraries and header files to your QNX target and run   make -f makefile_Hello_i86QNX6.4.1qcc_gpp  however this may be more trouble than is worth.
  2. If you have a Linux host configured to cross-compile to QNX you could try using that. The makefile_Hello_i86QNX6.4.1qcc_gpp  would probably work there with minor modifications...

Alternatively you could keep using your original approach and cross-compile from Windows with a hand-crafted makefile.

Gerardo

Offline
Last seen: 5 years 10 months ago
Joined: 02/11/2013
Posts: 3

Hi Gerardo.

You've resolved my problem. This is wonderful. I stared at it so hard I didn't realize I was misdirecting the compiling/linking chain.

I also should have mentioned that I am cross compiling. Sorry. :-)

I will try the rtiddsgen generated makefile on a QNX box with QCC and see how that works too.

Thank you very much for your help.

Sincerely,

  Karl