2014-07-22 12:05:51 +12:00
# ZeroMQ on z/OS UNIX System Services
ZeroMQ has been successfully built on z/OS, using [z/OS UNIX System
Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/),
a certified UNIX environment for the [IBM
z-series](http://www-03.ibm.com/systems/z/). The build is possible
with the shell scripts in this directory, as described below.
Tested build combinations:
* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in ILP32 mode
* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in LP64 mode
2014-07-22 16:44:56 +12:00
Other combinations are likely to work, possibly with minor changes,
but have not been tested. Both static library and DLL modes have been
tested.
2014-07-22 12:05:51 +12:00
There are some minor limitations (detailed below), but all core
functionality tests run successfully.
2014-07-22 16:44:56 +12:00
## Quickstart: building ZeroMQ on z/OS UNIX System Services
2014-07-22 12:05:51 +12:00
Assuming [z/OS UNIX System
Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/) is
installed, and the [z/OS XL C/C++
compiler suite](http://www-03.ibm.com/software/products/en/czos) is
installed, ZeroMQ can be built as follows:
* Download and extract ZeroMQ tar file
* Ensure contents of this directory are present at `builds/zos`
within that extracted diretory (eg, `zeromq-VERSION/builds/zos/` ;
copy these files in, if not already present, and make sure the
shell scripts are executable)
* (Optional) set ZCXXFLAGS for additional compile flags (see below)
2014-07-22 16:44:56 +12:00
* Build `libzmq.a` static library and `libzmq.so` dynamic
library, with:
2014-07-22 12:05:51 +12:00
cd zeromq-VERSION
builds/zos/makelibzmq
2014-07-23 13:09:28 +12:00
or to skip the `libzmq.so` dynamic library (only building `libzmq.a` ):
2014-07-22 16:44:56 +12:00
cd zeromq-VERSION
BUILD_DLL=false
export BUILD_DLL
builds/zos/makelibzmq
2014-07-23 13:09:28 +12:00
* (Optional, but recommended) build and run the core tests with:
2014-07-22 12:05:51 +12:00
2014-07-23 13:09:28 +12:00
cd zeromq-VERSION
2014-07-22 12:05:51 +12:00
builds/zos/maketests
builds/zos/runtests
* To remove built files, to start again (eg, rebuild with different
compile/link flags):
2014-07-23 13:09:28 +12:00
cd zeromq-VERSION
2014-07-22 12:05:51 +12:00
builds/zos/makeclean
2014-07-22 16:44:56 +12:00
There are details on specifying alternative compilation flags below.
## Quickstart: using ZeroMQ on z/OS UNIX System Services
### Static linking
Install `include/*.h` somewhere on your compiler include path.
Install `src/libzmq.a` somewhere on your library search path.
Compile and link application with:
c++ -Wc,xplink -Wl,xplink ... -+ -o myprog myprog.cpp -lzmq
Run with:
./myprog
2014-07-22 12:05:51 +12:00
2014-07-22 16:44:56 +12:00
### Dynamic linking
Install `include/*.h` somewhere on your compiler include path.
Install `src/libzmq.so` somewhere on your LIBPATH.
2014-07-23 13:09:28 +12:00
Install `src/libzmq.x` somewhere you can reference for import linking.
2014-07-22 16:44:56 +12:00
Compile and link application:
c++ -Wc,xplink -Wc,dll ... -+ -c -o myprog.o myprog.cpp
c++ -Wl,xplink -o myprog myprog.o /PATH/TO/libzmq.x
Run with:
2014-07-23 13:09:28 +12:00
LIBPATH=/DIR/OF/LIBZMQ.SO:/lib:/usr/lib:... # if not in default path
export LIBPATH
2014-07-22 16:44:56 +12:00
./myprog
2014-07-23 13:09:28 +12:00
## ZeroMQ on z/OS UNIX System Services: Application considerations
z/0S UNIX System Services does not provide a way to block the
[`SIGPIPE` signal being generated when a thread writes to a closed socket ](http://pic.dhe.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zos.r12.cbcpx01%2Fcbcpg1b0287.htm )
(compare with other platforms that support the `SO_NOSIGPIPE` socket
option, and/or the `MSG_NOSIGNAL` flag on `send()` ; z/OS UNIX System
Services supports neither).
As a result, applications using ZeroMQ on z/OS UNIX System Services
have to expect to encounter `SIGPIPE` at various times during the use
of the library, if sockets are unexpectedly disconnected. Normally
`SIGPIPE` will terminate the application.
A simple solution, if `SIGPIPE` is not required for normal operation
of the application (eg, it is not part of a unix pipeline, the
traditional use of `SIGPIPE` ), is to set `SIGPIPE` to be ignored
with code like:
#include < signal.h >
...
signal(SIGPIPE, SIG_IGN);
near the start of the application (eg, before initialising the ZeroMQ
library).
If `SIGPIPE` is required for normal operation it is recommended that
the application install a signal handler that flags the signal was
received, and allows the application main loop to determine if it
was received for one of its own file descriptors -- and ignores it if it
none of the applications own file descriptors seems to have changed.
Linking to the `libzmq.a` static library will pull in substantially
all of the library code, which will add about 4MB to the application
size (per executable statically linked with ZeroMQ). If this is a
significant consideration, use of the DLL version is recommended.
See also ZeroMQ test status on z/OS UNIX System Services below
for other caveats.
2014-07-22 16:44:56 +12:00
## Setting other compilation flags
### Optimisation
2014-07-22 12:05:51 +12:00
To build with optimisation:
* set `ZCXXFLAGS` to "`-O2` " before starting build process above
2014-07-22 16:44:56 +12:00
### Full debugging symbols
2014-07-22 12:05:51 +12:00
To build with debugging symbols:
* set `ZCXXFLAGS` to "`-g` " before starting build process above
2014-07-22 16:44:56 +12:00
### 64-bit mode (LP64/amode=64)
2014-07-22 12:05:51 +12:00
To build in 64-bit mode:
The default build is
[ILP32 ](http://publib.boulder.ibm.com/infocenter/zvm/v6r1/index.jsp?topic=/com.ibm.zos.r9.cbcux01/lp64cop.htm ),
the default for the IBM XL C/C++ compiler. To build in LP64 mode
(64-bit):
* set `ZCXXFLAGS` to "`-Wc,lp64 -Wl,lp64` " before starting build
(64-bit mode can be combined with optimisation or debug symbols.)
2014-07-22 16:44:56 +12:00
### Combining compilation flags
2014-07-22 12:05:51 +12:00
Other build flags can be used in `ZXCCFLAGS` if desired. Beware that
they are passed through (Bourne) shell expansion, and passed to both
the compile and link stages; some experimentation of argument quoting
may be required (and arguments requiring parenthesis are particularly
complicated).
## ZeroMQ test status on z/OS UNIX System Services
As of 2014-07-22, 41 of the 43 tests in the core ZeroMQ test suite
pass. There are two tests that are expected to fail:
0. `test_abstract_ipc` : tests Linux-specific IPC functions, and is
expected to fail on non-Linux platforms.
0. `test_fork` : tests ability to use ZeroMQ both before *and* after
fork (and before exec()); this relies on the ability to use
pthreads both before *and* after fork. On z/OS (and some other
UNIX compliant platforms) functions like `pthreads_create` (used
by ZeroMQ) cannot be used after fork and before exec; on z/OS the
2014-07-23 13:09:28 +12:00
call after fork fails with `ELEMULTITHREADFORK` (errno=257) if
ZeroMQ was also used before fork. (On z/OS it appears possible
to use z/OS *after* fork, *providing* it has not been used before
fork -- the problem is the two separate initialisations of the
threading library, before and after fork, attempting to mix
together.) In practice this is unlikely to affect many real-world
programs -- most programs use threads or fork without exec, but
not both.
2014-07-22 12:05:51 +12:00
These two "expected to fail" tests are listed as XFAIL_TESTS, and
`runtests` will still consider the test run successful when they fail
as expected.
2014-07-23 13:09:28 +12:00
In addition `test_security_curve` does not do any meaningful testing,
as a result of the CURVE support not being compiled in; it requires
[`libsodium` ](http://doc.libsodium.org/ ), which has not been
ported to z/OS UNIX System Services yet.
2014-07-22 12:05:51 +12:00
2014-07-23 13:09:28 +12:00
Multicast (via `libpgm` ) is also not ported or compiled in.
2014-07-22 12:05:51 +12:00
2014-07-23 13:09:28 +12:00
## ZeroMQ on z/OS UNIX System Services: Library portability notes
2014-07-22 12:05:51 +12:00
### *.cpp
The source code in ZeroMQ is a combination of a C++ core library
(in `*.cpp` and `*.hpp` files), and a C wrapper (also in `*.cpp`
files). It is all compiled with the C++ compiler. The IBM XL C/C++
complier (at least the version used for initial porting) insists
that C++ source be in `*.C` files (note capital C). To work around
this issue the compile flag `-+` is used (specified in the `zc++`
compiler wrapper), which tells the compiler the file should be
considered C++ despite the file extension.
### XPLINK
The library (and tests) are built in
[XPLINK ](http://www.redbooks.ibm.com/abstracts/sg245991.html ) mode
with the flags `-Wc,xplink -Wl,xplink` (specified in the `zc++`
compiler wrapper). This is [recommended by IBM for C++
code](http://publib.boulder.ibm.com/infocenter/zvm/v5r4/index.jsp?topic=/com.ibm.zos.r9.ceea200/xplrunt.htm)
due to the small functions. (Amongst other things, using XPLINK
enables function calls with some arguments passed in registers.)
### long long
ZeroMQ makes use of `uint64_t` (which is `unsigned long long` in ILP32
mode). To enable this the compile flag `-Wc,lang(longlong)` is passed
to enable `long long` . This is passed from the `zc++` compiler wrapper
in order to be able to specifically quote the argument to protect the
parentheses from shell expansion.
### BSD-style sockets, with IPv6 support
ZeroMQ uses BSD-style socket handling, with extensions to support IPv6.
BSD-style sockets were merged into SysV-derived UNIX at least a decade
ago, and are required as part of the X/Open Portability Guide at least
as of XPG 4.2. To access this functionality two feature macros are
defined:
2014-07-23 13:09:28 +12:00
_XOPEN_SOURCE_EXTENDED=1
2014-07-22 12:05:51 +12:00
2014-07-23 13:09:28 +12:00
_OPEN_SYS_SOCK_IPV6
2014-07-22 12:05:51 +12:00
The first enables the XPG 4.2 features (including functionality like
`getsockname()` ), and the latter exposes IPv6 specific functionality
like `sa_family_t` . These flags are defined in the `cxxall` script.
(The traditional BSD-sockets API, exposed with `_OE_SOCKETS` cannot
be used because it does not support functions like `getsockname()` ,
nor does it support IPv6 -- and the API definitions prevent compiling
in LP64 mode due to assumptions about long being 32 bits. Using
`_XOPEN_SOURCE_EXTENDED=1` avoids all these problems.)
### pthreads
ZeroMQ uses the pthreads library to create additional threads to handle
background communication without blocking the main application. This
functionaity is enabled on z/OS UNIX System Services by defining:
2014-07-23 13:09:28 +12:00
_OPEN_THREADS=3
2014-07-22 12:05:51 +12:00
which is done in the `cxxall` script. (The "3" value exposes later
pthreads functionality like `pthread_atfork` , although ZeroMQ does not
currently use all these features.)
## `platform.hpp` on z/OS UNIX System Services
The build (described above) on z/OS UNIX System Services uses a static
pre-built `platform.hpp` file. (By default `src/platform.hpp` is
dynamically generated as a result of running the `./configure` script.)
The master version of this is in `builds/zos/platform.hpp` .
The pre-built file is used because z/OS does not have the GNU auto tools
(`automake` , `autoconf` , `libtool` , etc) installed, and particularly the
libtool replacement does not work properly with the IBM XL C/C++
compiler.
The `./configure` script (only supplied in the tarballs); built with
`automake` and `autoconf` on another platform), with one small edit,
was used to generate the z/OS `platform.hpp` and then two small changes
(described below) were made by hand to the generated `platform.hpp` .
To be able to run the ./configure script to completion (in tcsh
syntax):
* Edit `./configure` and add:
openedition)
;;
immediately before the line:
as_fn_error $? "unsupported system: ${host_os}." "$LINENO" 5
(somewhere around 17637). This avoids the configure script giving
up early because `openedition` is not recognised.
* set `CXX` to point that the full path to the `builds/zos/zc++` wrapper, eg
setenv CXX "/u/0mq/zeromq-4.0.4/builds/zos/zc++"
* set `CPPFLAGS` to for the feature macros required, eg:
setenv CPPFLAGS "-D_XOPEN_SOURCE_EXTENDED=1 -D_OPEN_THREADS=3 -D_OPEN_SYS_SOCK_IPV6"
* set `CXXFLAGS` to enable XPLINK:
setenv CXXFLAGS "-Wc,xplink -Wl,xplink -+"
* run configure script with `--disable-eventfd` (`sys/eventfd.h` does
not exist, but the test for its existance has a false positive on
z/OS UNIX System Services, apparently due to the way the `c++`
compiler wrapper passes errors back from the IBM XL C/C++ compiler), viz:
./configure --disable-eventfd
All going well several Makefiles, and `src/platform.hpp` should be
produced. Two additional changes are required to `src/platform.hpp`
which can be appended to the end:
/* ---- Special case for z/OS Unix Services: openedition ---- */
#include < pthread.h >
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
(many includes require pthreads-related methods or data structures to
be defined, but not all of them include `pthread.h` , and the value
`NI_MAXHOST` is not defined on z/OS UNIX System Services -- the 1025
value is the conventional value on other platforms).
Having done this the Makefiles can be used to compile individual files
if desired, eg:
cd src
make zmq.o
but note:
* IBM Make will warn of duplicate prerequisites on *every* run of
`make` , and both the generated `src/Makefile` and `tests/Makefile`
have several duplicates. (For `src/Makefile` edit
`libzmq_la_SOURCES` to remove the duplicates.)
* IBM Make does not understand the `@` prefix (eg, `@echo` ) as a way
to avoid echoing the command, resulting in an error and the command
being echoed anyway.
* Many of the make targets result in GNU auto tools (`aclocal` , etc)
being invoked, which are likely to fail, and most of the
library-related targets will invoke `libtool` which will cause
compile failures (due to differences in expected arguments).
However running `./configure` to regenerate `src/platform.hpp` may
be useful for later versions of ZeroMQ which add more feature tests.
2014-07-24 10:42:30 +12:00
## Transferring from GitHub to z/OS UNIX System Services
The process of transferring files from GitHub to z/OS UNIX System
Services is somewhat convoluted because:
* There is not a port of git for z/OS UNIX System Services; and
* z/OS uses the EBCDIC (IBM-1047) character set rather than the
ASCII/ISO-8859-1 character set used by the ZeroMQ source code
on GitHub
A workable transfer process is:
* On an ASCII/ISO-8859-1/UTF-8 system with `git` (eg, a Linux system):
git clone https://github.com/zeromq/libzmq.git
git archive --prefix=libzmq-git/ -o /var/tmp/libzmq-git.tar master
* On a ASCII/ISO-8859-1/UTF-8 system with `tar` , and `pax` , and
optionally the GNU auto tools (eg, the same Linux system):
mkdir /var/tmp/zos
cd /var/tmp/zos
tar -xpf /var/tmp/libzmq-git.tar
cd libzmq-git
./autogen.sh # Optional: to be able to run ./configure
cd ..
pax -wf /var/tmp/libzmq-git.pax libzmq-git
compress libzmq-git.pax # If available, reduce transfer size
* Transfer the resulting file (`libzmq-git.pax` or `libzmq-git.pax.Z` )
to the z/OS UNIX System Services system. If using FTP be sure to
transfer the file in `bin` (binary/Image) mode to avoid corruption.
* On the z/OS UNIX System Services system, unpack the `pax` file and
convert all the files to EBCDIC with:
pax -o from=iso8859-1 -pp -rvf libzmq-git-2014-07-23.pax
or if the file was compressed:
pax -o from=iso8859-1 -pp -rvzf libzmq-git-2014-07-23.pax.Z
The result should be a `libzmq-git` directory with the source in
EBCDIC format, on the z/OS UNIX System Services system ready to start
building.
See also the [`pax` man
page](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa500%2Fr4paxsh.htm),
some [`pax` conversion
examples](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa400%2Fbpxza4c0291.htm),
and [IBM's advice on ASCII to EBCDIC conversion
options](http://www-03.ibm.com/systems/z/os/zos/features/unix/bpxa1p03.html)