OMERO C++ language bindings
Using the Ice C++ language mapping from ZeroC, OMERO provides native access to your data from C++ code. CMake is used for building the C++ bindings.
Binaries are not provided, therefore it will be necessary for you to compile your own.
Prerequisites
The OMERO source code
A C++ compiler
GCC is recommended for Linux and MacOS X
Visual Studio or the Platform SDK for Windows
The ZeroC Ice libraries, headers and slice definitions
cmake
Google Test (optional; needed to build the unit and integration tests)
Note
Users of Visual Studio with Ice 3.6 will
encounter this error while building OmeroCpp: LINK : fatal error
LNK1189: library limit of 65535 objects exceeded
and will be
unable to build OMERO C++ language bindings for Windows as a result of a 16-bit
limitation in the Windows PE-COFF executable format used for DLLs,
even on 64-bit systems. It is hoped that Ice 3.7
will resolve the problem since it generates
far fewer symbols than 3.6.
Restrictions
If you are restricted to a specific version of GCC or Ice, you may need to obtain or build a compatible version of Ice or GCC, respectively.
Preparing to build
Begin by following the instructions under Installing OMERO from source to acquire the source code. Be sure that the git branch you are using matches the version of your server!
The location of your Ice installation should be automatically detected
if installed into a standard location. If this is not the case, set
the location of your Ice installation using the ICE_HOME
environment variable or the cmake -DIce_HOME
or
cmake -DIce_SLICE_DIR
cmake options for your Ice
installation (see below). Some possible locations for the 3.6.5
version of Ice follow. Note these are just examples; you need to
adjust them for the Ice installation path and version in use on your
system.
Ice built from source and installed into
/opt
:export ICE_HOME=/opt/Ice-3.6.5
Ice installed on Linux using RPM packages:
export ICE_HOME=/usr/share/Ice-3.6.5
MacOS X with homebrew:
export ICE_HOME=/usr/local/Cellar/ice/3.6.5
Windows using Visual Studio:
set ICE_HOME=C:\Program Files (x86)\ZeroC\Ice-3.6.5
Note
If the Ice headers and libraries are not automatically discovered, these will need to be specified using appropriate cmake options (see below).
Building the library
The shared library and examples are always built by default. The unit and integration tests are built if Google test (gtest) is detected.
On Linux, Unix or MacOS X with make:
export GTEST_ROOT=/path/to/gtest
mkdir omero-build
cd omero-build
cmake [-Dtest=(TRUE|FALSE)] [cmake options] /path/to/openmicroscopy
make
For example:
cmake "-DCMAKE_CXX_FLAGS=$CMAKE_CXX_FLAGS" \
"-DCMAKE_EXE_LINKER_FLAGS=$CMAKE_LD_FLAGS" \
"-DCMAKE_MODULE_LINKER_FLAGS=$CMAKE_LD_FLAGS" \
"-DCMAKE_SHARED_LINKER_FLAGS=$CMAKE_LD_FLAGS" \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON /path/to/openmicroscopy
make -j8
If you would like to build the C++ tests, run the above with the
GTEST_ROOT
environment variable set.
Note
When cmake is run, it will run ./build.py
build-default
in the openmicroscopy source tree to generate some
of the C++ and Ice sources. If you have previously done a build by
running ./build.py
, this step will be skipped. However, if you
have recently switched branches without cleaning the source
tree, please run ./build.py clean
in the source tree to clean
up all the generated files prior to running cmake.
If the build fails with errors such as
/usr/include/Ice/ProxyHandle.h:176:13: error: ‘upCast’ was not declared in this scope,
and no declarations were found by argument-dependent lookup at the point of
instantiation
this is caused by the Ice headers being buggy, and newer versions of
GCC rejecting the invalid code. To compile in this situation, add
-fpermissive
to CXXFLAGS
to allow the invalid code to be
accepted, but do note that this may also mask other problems so should
not be used unless strictly needed.
cmake build configuration
cmake supports configuration of the build using many different environment variables and options; for a full list, see the cmake reference documentation. The following environment variables are commonly needed:
CMAKE_INCLUDE_PATH
Directories to be searched for include files, for example
/opt/Ice-3.6.5/include
A
:
or;
separator character is used to separate directories, depending on the platform. Note these are used only for feature tests, not for passing to the compiler when building, for whichCMAKE_CXX_FLAGS
is needed.CMAKE_LIBRARY_PATH
Directories to be searched for libraries, for example
/opt/Ice-3.6.5/lib
Directories are separated by
:
or;
as withCMAKE_INCLUDE_PATH
. Note these are used only for feature tests and finding libraries, not for passing to the linker when building, for whichCMAKE_*_LINKER_FLAGS
is needed.CXX
C++ compiler executable. Useful with ccache.
CXXFLAGS
C++ compiler flags. Use of
CMAKE_CXX_FLAGS
is preferred.ICE_HOME
The location of the Ice installation. If this is not sufficient to discover the correct binary and library directories, they may otherwise be manually specified with the options below. Likewise for the
include
andslice
directories. This may also be set as a cmake cache variable (see below).VERBOSE
If set to 1, show the actual build commands rather than the pretty “Compiling XYZ…” statements.
In addition, cmake options may be defined directly when running cmake. Commonly needed options include:
- -DCMAKE_PREFIX_PATH
Search this location when searching for programs, headers and libraries. Use to search
/usr/local
or/opt/Ice
, for example. More specific search locations may be specified usingcmake -DCMAKE_INCLUDE_PATH
,cmake -DCMAKE_LIBRARY_PATH
andcmake -DCMAKE_PROGRAM_PATH
separately, if required.
- -DCMAKE_INCLUDE_PATH
Search this location when searching for headers. Use to include
/usr/local/include
or/opt/Ice/include
, for example.
- -DCMAKE_LIBRARY_PATH
Search this location when searching for libraries. Use to include
/usr/local/lib
or/opt/Ice/lib
, for example.
- -DCMAKE_PROGRAM_PATH
Search this location when searching for programs. Use to include
/usr/local/bin
or/opt/Ice/bin
, for example.
- -DCMAKE_CXX_FLAGS
C++ compiler flags. Use to set any additional linker flags desired.
- -DCMAKE_EXE_LINKER_FLAGS
Executable linker flags. Use to set any additional linker flags desired.
- -DCMAKE_MODULE_LINKER_FLAGS
Loadable module linker flags. Use to set any additional linker flags desired.
- -DCMAKE_SHARED_LINKER_FLAGS
Shared library linker flags. Use to set any additional linker flags desired.
- -DCMAKE_VERBOSE_MAKEFILE
Default to printing all commands executed by make. This may be overridden with the make
VERBOSE
variable.
- -DIce_HOME
The location of the Ice installation. If this is not sufficient to discover the correct binary and library directories, they may otherwise be manually specified with the options below. Likewise for the
include
andslice
directories.
- -DIce_SLICE2XXX_EXECUTABLE
Specific location of individual Ice
slice2xxx
programs, e.g.Ice_SLICE2CPP_EXECUTABLE
for slice2cpp orIce_SLICE2JAVA_EXECUTABLE
for slice2java. These are typically found in${ICE_HOME}/bin
or on the defaultPATH
. These will not normally require setting.
- -DIce_INCLUDE_DIR
Location of Ice headers. This is typically
${ICE_HOME}/include
or on the default include search path. This will not normally require setting.
- -DIce_SLICE_DIR
Location of Ice slice interface definitions. This is typically
${ICE_HOME}/slice
. Use for installations wherecmake -DIce_HOME
does not containslice
or situations where you wish to build without settingcmake -DIce_HOME
. Note that when building using build.py, rather than building directly with cmake, theSLICEPATH
environment variable should be used instead (the ant build can’t use the cmake variables since it only runs cmake after a full build of the Java server).
- -DIce_<C>_LIBRARIES
Specific libraries for Ice component
<C>
, where<C>
is the uppercased name of the Ice component, e.g.ICE
for theIce
component,ICEUTIL
for theIceUtil
component orGLACIER2
for theGlacier2
component. These libraries are typically found in${ICE_HOME}/lib
or on the default library search path. These will not normally require setting.
- -DIce_DEBUG
Set to ON to print detailed diagnostics about the detected Ice installation. Use if there are any problems finding Ice.
cmake offers many additional options. Please refer to the documentation for further details, in particular to the variables which change the behavior of the build.
Visual Studio configuration
Warning
OMERO.cpp will not currently build on Windows due to exceeding DLL symbol limits on this platform, leading to a failure when linking the DLL. It is hoped that this platform limitation can be worked around in a future OMERO release.
cmake has full support for Visual Studio. Use
the cmake -G
option to set the generator for your
Visual Studio version, with a Win64
suffix for an x64 build. The
correct Ice programs and libraries for your Ice installation should be
automatically discovered.
cmake -G "Visual Studio 11 Win64" [cmake options] /path/to/openmicroscopy
This is for a 64-bit Visual Studio 2012 build. Modify appropriately for other versions and compilers. Running
cmake --help
will list the available generators for your platform (without the
Win64
suffix).
Once cmake has finished running, the generated project and solution files may be then opened in Visual Studio, or built directly using the msbuild command-line tool (make sure that the Visual Studio command prompt matches the generator chosen) or by running:
cmake --build .
As for the Unix build, above, it is also possible to build on Windows using build.py or ant, providing that you configure the generator appropriately using the correct cmake options. However, this will not work for all generators reliably, and the Windows shell quoting makes passing nested quotes to ant quite tricky, so running cmake by hand is recommended.
Note
It may be necessary to specify /Zm1000
as an additional
compiler setting.
Installing the library
If using make, run:
make [DESTDIR=/path/to/staging/directory] install
If using another build system, please invoke the equivalent install target for that system.
Using the library
To use OMERO C++ language bindings it is necessary to point your compiler and linker at
the mentioned directories above. A simple GNU make
Makefile
might look like this:
1#
2# MAKEFILE:
3#
4# Where the OMERO distribution was installed
5OMERO_DIST ?= /opt/omero
6
7# Where the Ice lib/ and include/ directories are to be found
8ICE_HOME ?= /usr/share/Ice
9
10INCLUDES=-I$(OMERO_DIST)/include -I$(ICE_HOME)/include
11
12LIBS = -L$(OMERO_DIST)/lib -L$(ICE_HOME)/lib -L$(ICE_HOME)/lib64 \
13 -lIce -lIceUtil -lGlacier2 -lomero-client
14
15LIBPATH = $(LD_LIBRARY_PATH):$(ICE_HOME)/lib:$(ICE_HOME)/lib64:$(OMERO_DIST)/lib
16
17.PHONY: clean run
18
19yourcode.o: yourcode.cpp
20 $(CXX) $(CXXFLAGS) -c -o $@ $< $(INCLUDES)
21
22yourcode: yourcode.o
23 $(CXX) -o $@ $^ $(LIBS)
24
25run: yourcode
26 LD_LIBRARY_PATH="$(LIBPATH)" ./yourcode --Ice.Config=../etc/ice.config
27
28clean:
29 rm -f yourcode *.o *~ core
A trivial example: yourcode.cpp
A simple example might look something like the following:
1//
2// yourcode.cpp:
3//
4
5// Domain
6#include <omero/client.h>
7#include <omero/api/IAdmin.h>
8// Std
9#include <iostream>
10#include <cassert>
11#include <vector>
12#include <time.h>
13#include <map>
14
15using namespace std;
16
17/*
18 * Pass "--Ice.Config=your_config_file" to the executable, or
19 * set the ICE_CONFIG environment variable.
20 */
21int main(int argc, char* argv[])
22{
23 omero::client_ptr omero = new omero::client(argc, argv);
24 omero::api::ServiceFactoryPrx sf = omero->createSession();
25 sf->closeOnDestroy();
26
27 // IAdmin is responsible for all user/group creation, password changing, etc.
28 omero::api::IAdminPrx admin = sf->getAdminService();
29
30 // Who you are logged in as.
31 cout << admin->getEventContext()->userName << endl;
32
33 // These two services are used for database access
34 omero::api::IQueryPrx query = sf->getQueryService();
35 omero::api::IUpdatePrx update = sf->getUpdateService();
36
37 return 0;
38}
This code does not do much. It creates a server session, loads a few services, and prints the user’s name. For serious examples, see Working with OMERO.
Compiling and running your code
To compile and run yourcode, download the two files above
(Makefile
and yourcode.cpp
) and then in a shell:
make OMERO_DIST=dist yourcode
LD_LIBRARY_PATH=dist/lib ./yourcode --Ice.Config=dist/etc/ice.config
where you have edited dist/etc/ice.config
to contain the
values:
omero.host=localhost
omero.user=your_name
omero.pass=your_password
Alternatively, you can pass these on the command-line:
LD_LIBRARY_PATH=dist/lib ./yourcode omero.host=localhost --omero.user=foo --omero.pass=bar
Note
This example explains how to run on Linux only. For doing the
same on MacOS X, change all instances of
LD_LIBRARY_PATH
to DYLD_LIBRARY_PATH
.
Further information
For the details behind writing, configuring, and executing a client, please see Working with OMERO.
See also
Ice, OMERO.grid, OMERO Application Programming Interface, Build System, #1596 which added 64-bit support