compiling ACE + TAO under QNX Neutrino

Hi folks,

I am trying to build ACE+TAO under QNX Neutrino 6.3.2. So far I tried different versions of ACE and TAO: 5.6 and an older one 5.4.6. I tried two different attempts:

  1. ACE+TAO 5.6 the common way with autoconf, like described on the page:
    dre.vanderbilt.edu/~schmidt/ … STALL.html

The “…/configure” command stops with following message:
“checking for working POSIX realtime signals… rtsig 41”

Does anyone have an idea how to solve this problem?

  1. ACE+TAO 5.4.6 the way described by Ingo Brauckhoff:
    groups.google.com/group/comp.sof … 98d78df78c

The “make” command brakes while compiling SSL.

Does anyone made it with that description? Or does anyone know an other way to compile ACE+TAO under QNX Neutrino?

Thx,
Alexej

The “…/configure” command stops with following message:
“checking for working POSIX realtime signals… rtsig 41”
and configure make a conftest.cc:
/* confdefs.h. */

#define PACKAGE_NAME “ACE”
#define PACKAGE_TARNAME “ace”
#define PACKAGE_VERSION “5.6.4”
#define PACKAGE_STRING “ACE 5.6.4”
#define PACKAGE_BUGREPORT “ace-bugs@cs.wustl.edu”
#ifdef __cplusplus
extern “C” void exit (int) throw ();
#endif
#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1
#define ACE_HAS_GPERF 1
#define ACE_INLINE 1
#define ACE_LACKS_GETSERVBYNAME 1
#define ACE_HAS_PTHREADS 1
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define HAVE_DLFCN_H 1
#define ACE_HAS_AIO_CALLS 1
/* end confdefs.h. */

extern “C” {
#include <signal.h>
}
#ifndef ACE_LACKS_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifndef ACE_LACKS_SYS_TYPES_H

include <sys/types.h>

#endif
#include <sys/stat.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

#include <limits.h>

#include <aio.h>
#ifdef __cplusplus
extern “C”
#endif
void null_handler (int /* signal_number /,
siginfo_t * /
info /,
void * /
context */);

int file_handle = -1;
char mb1[BUFSIZ + 1];
char mb2[BUFSIZ + 1];
aiocb aiocb1, aiocb2;
sigset_t completion_signal;

// Function prototypes.
int setup_signal_delivery (void);
int issue_aio_calls (void);
int query_aio_completions (void);
int test_aio_calls (void);
int setup_signal_handler (void);
int setup_signal_handler (int signal_number);

int
setup_signal_delivery (void)
{
// Make the sigset_t consisting of the completion signal.
if (sigemptyset (&completion_signal) == -1)
{
perror (“Error:Couldn’t init the RT completion signal set\n”);
return -1;
}

if (sigaddset (&completion_signal, SIGRTMIN) == -1)
{
perror (“Error:Couldn’t init the RT completion signal set\n”);
return -1;
}

// Mask them.
if (pthread_sigmask (SIG_BLOCK, &completion_signal, 0) == -1)
{
perror (“Error:Couldn’t make the RT completion signals\n”);
return -1;
}

return setup_signal_handler (SIGRTMIN);
}

int
issue_aio_calls (void)
{
// Setup AIOCB.
aiocb1.aio_fildes = file_handle;
aiocb1.aio_offset = 0;
aiocb1.aio_buf = mb1;
aiocb1.aio_nbytes = BUFSIZ;
aiocb1.aio_reqprio = 0;
aiocb1.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aiocb1.aio_sigevent.sigev_signo = SIGRTMIN;
aiocb1.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb1;

// Fire off the aio write.
if (aio_read (&aiocb1) == -1)
{
// Queueing failed.
perror (“Error:Asynch_Read_Stream: aio_read queueing failed\n”);
return -1;
}

// Setup AIOCB.
aiocb2.aio_fildes = file_handle;
aiocb2.aio_offset = BUFSIZ + 1;
aiocb2.aio_buf = mb2;
aiocb2.aio_nbytes = BUFSIZ;
aiocb2.aio_reqprio = 0;
aiocb2.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aiocb2.aio_sigevent.sigev_signo = SIGRTMIN;
aiocb2.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb2;

// Fire off the aio write.
if (aio_read (&aiocb2) == -1)
{
// Queueing failed.
perror (“Error:Asynch_Read_Stream: aio_read queueing failed\n”);
return -1;
}
return 0;
}

int
query_aio_completions (void)
{
int result = 0;
size_t number_of_completions = 0;
for (number_of_completions = 0;
number_of_completions < 2;
number_of_completions++)
{
// Wait for <milli_seconds> amount of time.
// @@ Assigning <milli_seconds> to tv_sec.
timespec timeout;
timeout.tv_sec = 5;
timeout.tv_nsec = 0;

  // To get back the signal info.
  siginfo_t sig_info;

  // Await the RT completion signal.
  int sig_return = sigtimedwait (&completion_signal,
                                 &sig_info,
                                 &timeout);

  // Error case.
  // If failure is coz of timeout, then return *0* but set
  // errno appropriately. This is what the WinNT proactor
  // does.
  if (sig_return == -1)
    {
      perror ("Error:Error waiting for RT completion signals\n");
      return -1;
    }

  // RT completion signals returned.
  if (sig_return != SIGRTMIN)
    {
      //printf ("Unexpected signal (%d) has been received while waiting for RT Completion Signals\n",
      //        sig_return);
      return -1;
    }

  // @@ Debugging.
  //printf ("Sig number found in the sig_info block : %d\n",
  //        sig_info.si_signo);

  // Is the signo returned consistent?
  if (sig_info.si_signo != sig_return)
    {
      //printf ("Inconsistent signal number (%d) in the signal info block\n",
      //        sig_info.si_signo);
      return -1;
    }

  // @@ Debugging.
  //printf ("Signal code for this signal delivery : %d\n",
  //        sig_info.si_code);

  // Is the signal code an aio completion one?
  if ((sig_info.si_code != SI_ASYNCIO) &&
      (sig_info.si_code != SI_QUEUE))
    {
      //printf ("Unexpected signal code (%d) returned on completion querying\n",
      //        sig_info.si_code);
      return -1;
    }

  // Retrive the aiocb.
  aiocb* aiocb_ptr = (aiocb *) sig_info.si_value.sival_ptr;

  // Analyze error and return values. Return values are
  // actually <errno>'s associated with the <aio_> call
  // corresponding to aiocb_ptr.
  int error_code = aio_error (aiocb_ptr);
  if (error_code == -1)
    {
      perror ("Error:Invalid control block was sent to <aio_error> for compleion querying\n");
      return -1;
    }

  if (error_code != 0)
    {
      // Error occurred in the <aio_>call. Return the errno
      // corresponding to that <aio_> call.
      //printf ("Error:An AIO call has failed:Error code = %d\n",
      //        error_code);
      return -1;
    }

  // No error occured in the AIO operation.
  int nbytes = aio_return (aiocb_ptr);
  if (nbytes == -1)
    {
      perror ("Error:Invalid control block was sent to <aio_return>\n");
      return -1;
    }

  //if (number_of_completions == 0)
    // Print the buffer.
    //printf ("Number of bytes transferred : %d\n The buffer : %s \n",
    //        nbytes,
    //        mb1);
  //else
    // Print the buffer.
    //printf ("Number of bytes transferred : %d\n The buffer : %s \n",
    //        nbytes,
    //        mb2);
}

return 0;
}

int
test_aio_calls (void)
{
// Set up the input file.
// Open file (in SEQUENTIAL_SCAN mode)
file_handle = open (“test_aiosig.txt”, O_RDONLY);

if (file_handle == -1)
{
perror (“open”);
return -1;
}

unlink (“test_aiosig.txt”); // Unlink now so we don’t have to do so later.

if (setup_signal_delivery () < 0)
return -1;

if (issue_aio_calls () < 0)
return -1;

if (query_aio_completions () < 0)
return -1;

if (close (file_handle) != 0)
{
perror (“close”);
return -1;
}

return 0;
}

int
setup_signal_handler (int signal_number)
{
// Setting up the handler(!) for these signals.
struct sigaction reaction;
sigemptyset (&reaction.sa_mask); // Nothing else to mask.
reaction.sa_flags = SA_SIGINFO; // Realtime flag.
#if defined (SA_SIGACTION)
// Lynx says, it is better to set this bit to be portable.
reaction.sa_flags &= SA_SIGACTION;
#endif /* SA_SIGACTION */
reaction.sa_sigaction = null_handler; // Null handler.
int sigaction_return = sigaction (SIGRTMIN,
&reaction,
0);
if (sigaction_return == -1)
{
perror (“Error:Proactor couldn’t do sigaction for the RT SIGNAL”);
return -1;
}

return 0;
}

void
null_handler (int /* signal_number /,
siginfo_t * /
info /,
void * /
context */)
{
}

int
main ()
{
if (test_aio_calls () == 0)
{
// printf (“RT SIG test successful:\n”
// “ACE_POSIX_SIG_PROACTOR should work in this platform\n”);
return 0;
}

//printf (“RT SIG test failed:\n”
// “ACE_POSIX_SIG_PROACTOR may not work in this platform\n”);
return -1;

}

error is in the function query_aio_completions ():
sig_return = sigtimedwait (&completion_signal, &sig_info, &timeout);

./conftest2

Sig number found in the sig_info block : 41
Signal code for this signal delivery : 0
Unexpected signal code (0) returned on completion querying
rtsig 41

at this moment I don`t know how resolve this problem.
bogdan

Hmm, ok I am not the only one with that problem.

I think its definitely an ACE Problem. So if someone managed to compile current ACE under QNX Neutrino I would be very thankful to get some hints.

Best regards,
Alexej

Autoconf is really not tested on QNX. Use the traditional way of compilation using config.h/platform_macros.GNU to build ACE/TAO on QNX

autoconf works in QNX very well.
ACE/TAO is the very difficult system and will be written on Linux that is why rewriting him on the different method of the compilation always very difficult.
POSIX realtime signals… relates to the problem described by alekseja and not autoconf.
I do not deal with realtime signals in QNX now hard he is to answer me if the introduced programme conftest.cc works in QNX correctly.
Disconnection in the configure of checking POSIX realtime signals… is one from ways.
To be only well to be sure that realtime signals in QNX work correctly.

I am not saying that autoconf doesn’t work, mostly pointing out that we as ACE/TAO core developers have never tested ACE/TAO autoconf on QNX. We do know that the traditional way works better, but QNX is not a main platform we test on. At the moment QNX doesn’t support a feature it should report this correctly, not just give a rtsig and stop.

ok, thanks so far. I tried the traditional way (described here: dre.vanderbilt.edu/~schmidt/ … raditional).

This was my approach:

  1. export ACE_ROOT=/root/ACE_wrappers

  2. Create a configuration file, $ACE_ROOT/ace/config.h, with following content:

#include “ace/config-qnx-neutrino.h”

  1. Create a build configuration file, $ACE_ROOT/include/makeinclude/platform_macros.GNU with following content:

include $(ACE_ROOT)/include/makeinclude/platform_qnx_neutrino.GNU

  1. export LD_LIBRARY_PATH=$ACE_ROOT/lib:$LD_LIBRARY_PATH

  2. cd $ACE_ROOT

  3. make

The make process fails after 2 seconds with following error:

make[1]: *** [.obj/Local_Name_Space.o] Error 1
make[1]: Leaving directory ‘/root/ACE_wrappers/ace’
make: *** [ACE] Error 2

Additionally I tried to switch to gcc V3.3.5 (instead of V2.95.3) with following commands:

7 ) export QCC_CONF_PATH=/usr/qnx632/host/qnx6/x86/etc/qcc
8 ) qcc -V3.3.5,gcc_ntox86_gpp -set-default
9 ) cd $QCC_CONF_PATH/gcc/3.3.5
10) rm gcc_ntox86_gpp.conf
11) ln -s gcc_ntox86_gpp++.conf gcc_ntox86_gpp.conf

This also didn’t help.

This leads me to following questions:
A) Is anything missing in my approach? Does anyone have any hints?

B) There are different config files: (for example config-qnx-rtp-62x.h). Which of them should I use?

C) Has anyone compiled ACE/TAO under QNX Neutrino successfully?

Best regards,
Alexej

Do you have a full build log? Visited today a potential customer that is also interested in QNX. We are discussing how we could validate ace/tao on qnx and what the costs are. Contact me directly if you are interested in this.

Hi,

Restore the QNX 6.3.2 to default configuration and try this:

[$ACE_ROOT/ace/config.h]
#include “ace/config-qnx-rtp.h”

[$ACE_ROOT/include/makeinclude/platform_macros.GNU]
debug=1
optimize=0
inline=0
CC=ntox86-gcc-3.3.5
CXX=ntox86-g+±3.3.5
include $(ACE_ROOT)/include/makeinclude/platform_qnx_rtp_gcc.GNU

[$TAO_ROOT]
mwc.pl -type gnuace TAO_ACE.mwc

Now you will be able to run “make”

Thanks

Thank you “rperrones” very much!

Your post helped me a lot to compile ACE+TAO. However there are some steps left out, that are probably to obvios for you, so here is the complete compilation instruction:

Installation of ACE+TAO-5.6 under QNX Neutrino 6.3.2 (x86):

pre-condition: QNX Neutrino 6.3.2 Standard Installation

  1. install Perl package:
    Open QNX Software installer:
  • Launch → Installer
  • Bookmarks → QNX WWW Repository
  • Perl (x86)
  • Install
  1. download ACE+TAO-5.6.tar.gz (I used /root as destination directory)
    download.dre.vanderbilt.edu/prev … 5.6.tar.gz

  2. unpack ACE+TAO-5.6.tar.gz (using Terminal):

tar -zxf ACE+TAO-5.6.tar.gz

  1. set environment variable for ACE

export ACE_ROOT=/root/ACE_wrappers

  1. set environment variable for TAO

export TAO_ROOT=/root/ACE_wrappers/TAO

  1. create [$ACE_ROOT/ace/config.h] with following content:
    #include “ace/config-qnx-rtp.h”

  2. create [$ACE_ROOT/include/makeinclude/platform_macros.GNU] with following content:
    debug=1
    optimize=0
    inline=0
    CC=ntox86-gcc-3.3.5
    CXX=ntox86-g+±3.3.5
    include $(ACE_ROOT)/include/makeinclude/platform_qnx_rtp_gcc.GNU

(There is really no # before include !!!)

  1. run perl script mwc.pl

cd $TAO_ROOT

$ACE_ROOT/bin/mwc.pl -type gnuace TAO_ACE.mwc

  1. run make

cd $ACE_ROOT

make

(takes approximately 5 mins on my intel core 2 duo)

cd $TAO_ROOT

make

(takes approximately 30 mins)

  1. Install and run Tests

cd $ACE_ROOT/tests

make

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ACE_ROOT/lib

./run_test.pl

Thats it. I hope this will ease the compilation process a bit for unexperienced users. Next step is to check wether the libs are working correctly. Even so most of the tests runned with 0 return value, I don’t know how to analyze all the log files (created by run_tes.pl).

Best regards,
Alexej

I would recommend you to use x.6.5, that is much better then x.6

Thanks very much for an excellent step-by-step!

If the test fails it runs != 0 and then run_test.pl prints the log file.