omniORB 4 uses an Autoconf configure script to support configuration of the build system. Many configure scripts support cross-compiling with the use of the --host
and --build
flags. Unfortunately, omniORB explicitly states in their README.unix
file that cross compiling is not supported.
The Autoconf build does not currently work for cross compiling.
Here's what happens when you do try to use the --host
and --build
Autoconf flags:
Environment:
PATH
set to include the cross-compilation toolsCPPFLAGS
set to include the ARM sysroot/include folder -I.../sysroot/include
LDFLAGS
set to include the ARM sysroot/lib folder -L.../sysroot/lib
Note: I use three dots (...) to omit parts of file paths or unimportant output.
$ pwd
.../omniORB-4.1.6
$ mkdir build
$ cd build
$ ../configure --build=x86_64-linux-gnu --host=arm-linux-gnueabihf
...
$ make
...
omniidl: ERROR!
omniidl: Could not open IDL compiler module _omniidlmodule.so
omniidl: Please make sure it is in directory .../omniORB-4.1.6/build/lib
omniidl: (or set the PYTHONPATH environment variable)
omniidl: (The error was '.../omniORB-4.1.6/build/lib/_omniidlmodule.so: wrong ELF class: ELFCLASS32')
...
I believe the important message there to be wrong ELF class: ELFCLASS32
. I inspected this shared object library with file
.
$ file lib/_omniidlmodule.so.4.1
lib/_omniidlmodule.so.4.1: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, ...
So it appears the build system builds this shared object module for use by omniidl during the omniORB build. The issue is that it is built for ARM, and cannot be used on the host system.
How can I cross-compile omniORB given the lack of support from their build system?
I came to my solution with the help of an instructional post on the website of a company called Tango Controls. While their instructions may be enough for some, they were not adequate for me. The first problem was that it did not consider the need to include/link against libraries (e.g. Python) built for the host system. The second problem is that it does not address installation properly - when you follow their instructions you will end up installing some executables and libraries built for the build system.
System Terminology (as defined by Autoconf):
Here are the steps I took to cross-compile omniORB:
$ pwd
.../omniORB-4.1.6
$ mkdir build
$ cd build
Set up your environment
PATH
set to include the cross-compilation toolsCPPFLAGS
set to include the ARM sysroot/include folder -I.../sysroot/includeLDFLAGS
set to include the ARM sysroot/lib folder -L.../sysroot/libConfigure
Set your own --prefix
as necessary and modify CC
and CXX
for your setup. You may also need to change the --build
and --host
settings.
$ ../configure --build=x86_64-linux-gnu --host=arm-linux-gnueabihf --prefix=.../sysroot \
CC=.../bin/arm-linux-gnueabihf-gcc \
CXX=.../bin/arm-linux-gnueabihf-g++
...
Note: I use three dots (...) to omit parts of file paths or unimportant output.
beforeauto.mk
for the x86_64 tool build$ sed -i 's#CPPFLAGS = -I.*include \$(DIR_CPPFLAGS) \$(IMPORT_CPPFLAGS)#CPPFLAGS = $(DIR_CPPFLAGS) $(IMPORT_CPPFLAGS)#' mk/beforeauto.mk
$ sed -i 's#CLINKOPTIONS = -L.*lib \$(CDEBUGFLAGS) \$(COPTIONS)#CLINKOPTIONS = $(CDEBUGFLAGS) $(COPTIONS)#' mk/beforeauto.mk
$ sed -i 's#CXXLINKOPTIONS = -L.*lib \$(CXXDEBUGFLAGS) \$(CXXOPTIONS)#CXXLINKOPTIONS = $(CXXDEBUGFLAGS) $(CXXOPTIONS)#' mk/beforeauto.mk
These sed
commands are generalized, but you may still need to modify them for your own setup.
These tools are used during the compilation of omniORB, so they need to be compiled for the build system. We force make to use the build system compilers with the CC
and CXX
variables. These may need modification depending on the name of your build system compilers. Ensure these compilers are on your PATH
.
$ make CC=gcc -C src/tool/omniidl/cxx/cccp
...
$ make CXX=g++ -C src/tool/omniidl/cxx
...
$ make CC=gcc -C src/tool/omkdepend
...
The instructions from the Tango post say to add the stdc++
lib to some of the make commands with the -l
flag. The below sed
commands may be used for this patch.
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/omniMapper/dir.mk
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/omniNames/dir.mk
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/utils/catior/dir.mk
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/utils/convertior/dir.mk
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/utils/genior/dir.mk
$ sed -i 's/@(libs="$(CORBA_LIB_NODYN)"; $(CXXExecutable))/@(libs="$(CORBA_LIB_NODYN) -lstdc++"; $(CXXExecutable))/' ../src/appl/utils/nameclt/dir.mk
I have not yet determined if this patch is necessary for all systems and software versions. For my own setup, the build succeeds with or without this patch. I will update this answer if I learn more about this patch.
beforeauto.mk
for the ARM omniORB buildYou will need to put in your own paths in place of ...
.
$ sed -i 's#CPPFLAGS = \$(DIR_CPPFLAGS) \$(IMPORT_CPPFLAGS)#CPPFLAGS = -I.../sysroot/include $(DIR_CPPFLAGS) $(IMPORT_CPPFLAGS)#' mk/beforeauto.mk
$ sed -i 's#CLINKOPTIONS = \$(CDEBUGFLAGS) \$(COPTIONS)#CLINKOPTIONS = -L.../sysroot/lib $(CDEBUGFLAGS) $(COPTIONS)#' mk/beforeauto.mk
$ sed -i 's#CXXLINKOPTIONS = \$(CXXDEBUGFLAGS) \$(CXXOPTIONS)#CXXLINKOPTIONS = -L.../sysroot/lib $(CXXDEBUGFLAGS) $(CXXOPTIONS)#' mk/beforeauto.mk
$ make
...
$ make -C src/tool/omniidl/cxx/cccp clean
...
$ make -C src/tool/omniidl/cxx clean
...
$ make -C src/tool/omkdepend clean
...
$ make -C src/tool/omniidl/cxx/cccp
...
$ make -C src/tool/omniidl/cxx
...
$ make -C src/tool/omkdepend
...
$ make install
...
We're done! You should now be able to inspect the installed binaries with the file
command and see that they are built for ARM.