README.md
1# ZeroMQ on z/OS UNIX System Services
2
3ZeroMQ has been successfully built on z/OS, using [z/OS UNIX System
4Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/),
5a certified UNIX environment for the [IBM
6z-series](http://www-03.ibm.com/systems/z/). The build is possible
7with the shell scripts in this directory, as described below.
8
9Tested build combinations:
10
11* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in ILP32 mode
12
13* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in LP64 mode
14
15* ZeroMQ 4.1-git, using IBM XL C/C++ compiler, as XPLINK in ILP32 mode
16
17Other combinations are likely to work, possibly with minor changes,
18but have not been tested. Both static library and DLL modes have been
19tested.
20
21There are some minor limitations (detailed below), but all core
22functionality tests run successfully.
23
24
25## Quickstart: building ZeroMQ on z/OS UNIX System Services
26
27Assuming [z/OS UNIX System
28Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/) is
29installed, and the [z/OS XL C/C++
30compiler suite](http://www-03.ibm.com/software/products/en/czos) is
31installed, ZeroMQ can be built as follows:
32
33* Download and extract ZeroMQ tar file
34
35* Ensure contents of this directory are present at `builds/zos`
36 within that extracted diretory (eg, `zeromq-VERSION/builds/zos/`;
37 copy these files in, if not already present, and make sure the
38 shell scripts are executable)
39
40* (Optional) set ZCXXFLAGS for additional compile flags (see below)
41
42* Build `libzmq.a` static library and `libzmq.so` dynamic
43 library, with:
44
45 cd zeromq-VERSION
46 builds/zos/makelibzmq
47
48 or to skip the `libzmq.so` dynamic library (only building `libzmq.a`):
49
50 cd zeromq-VERSION
51 BUILD_DLL=false
52 export BUILD_DLL
53 builds/zos/makelibzmq
54
55* (Optional, but recommended) build and run the core tests with:
56
57 cd zeromq-VERSION
58 builds/zos/maketests
59 builds/zos/runtests
60
61* To remove built files, to start again (eg, rebuild with different
62 compile/link flags):
63
64 cd zeromq-VERSION
65 builds/zos/makeclean
66
67There are details on specifying alternative compilation flags below.
68
69
70## Quickstart: using ZeroMQ on z/OS UNIX System Services
71
72### Static linking
73
74Install `include/*.h` somewhere on your compiler include path.
75
76Install `src/libzmq.a` somewhere on your library search path.
77
78Compile and link application with:
79
80 c++ -Wc,xplink -Wl,xplink ... -+ -o myprog myprog.cpp -lzmq
81
82Run with:
83
84 ./myprog
85
86
87### Dynamic linking
88
89Install `include/*.h` somewhere on your compiler include path.
90
91Install `src/libzmq.so` somewhere on your LIBPATH.
92
93Install `src/libzmq.x` somewhere you can reference for import linking.
94
95Compile and link application:
96
97 c++ -Wc,xplink -Wc,dll ... -+ -c -o myprog.o myprog.cpp
98 c++ -Wl,xplink -o myprog myprog.o /PATH/TO/libzmq.x
99
100Run with:
101
102 LIBPATH=/DIR/OF/LIBZMQ.SO:/lib:/usr/lib:... # if not in default path
103 export LIBPATH
104 ./myprog
105
106
107## ZeroMQ on z/OS UNIX System Services: Application considerations
108
109z/0S UNIX System Services does not provide a way to block the
110[`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)
111(compare with other platforms that support the `SO_NOSIGPIPE` socket
112option, and/or the `MSG_NOSIGNAL` flag on `send()`; z/OS UNIX System
113Services supports neither).
114
115As a result, applications using ZeroMQ on z/OS UNIX System Services
116have to expect to encounter `SIGPIPE` at various times during the use
117of the library, if sockets are unexpectedly disconnected. Normally
118`SIGPIPE` will terminate the application.
119
120A simple solution, if `SIGPIPE` is not required for normal operation
121of the application (eg, it is not part of a unix pipeline, the
122traditional use of `SIGPIPE`), is to set `SIGPIPE` to be ignored
123with code like:
124
125 #include <signal.h>
126 ...
127 signal(SIGPIPE, SIG_IGN);
128
129near the start of the application (eg, before initialising the ZeroMQ
130library).
131
132If `SIGPIPE` is required for normal operation it is recommended that
133the application install a signal handler that flags the signal was
134received, and allows the application main loop to determine if it
135was received for one of its own file descriptors -- and ignores it if it
136none of the applications own file descriptors seems to have changed.
137
138Linking to the `libzmq.a` static library will pull in substantially
139all of the library code, which will add about 4MB to the application
140size (per executable statically linked with ZeroMQ). If this is a
141significant consideration, use of the DLL version is recommended.
142
143See also ZeroMQ test status on z/OS UNIX System Services below
144for other caveats.
145
146
147## Setting other compilation flags
148
149### Optimisation
150
151To build with optimisation:
152
153* set `ZCXXFLAGS` to "`-O2`" before starting build process above
154
155
156### Full debugging symbols
157
158To build with debugging symbols:
159
160* set `ZCXXFLAGS` to "`-g`" before starting build process above
161
162### 64-bit mode (LP64/amode=64)
163
164To build in 64-bit mode:
165
166The default build is
167[ILP32](http://publib.boulder.ibm.com/infocenter/zvm/v6r1/index.jsp?topic=/com.ibm.zos.r9.cbcux01/lp64cop.htm),
168the default for the IBM XL C/C++ compiler. To build in LP64 mode
169(64-bit):
170
171* set `ZCXXFLAGS` to "`-Wc,lp64 -Wl,lp64`" before starting build
172
173(64-bit mode can be combined with optimisation or debug symbols.)
174
175### Combining compilation flags
176
177Other build flags can be used in `ZXCCFLAGS` if desired. Beware that
178they are passed through (Bourne) shell expansion, and passed to both
179the compile and link stages; some experimentation of argument quoting
180may be required (and arguments requiring parenthesis are particularly
181complicated).
182
183
184## ZeroMQ test status on z/OS UNIX System Services
185
186As of 2014-07-22, 41 of the 43 tests in the core ZeroMQ test suite
187pass. There are two tests that are expected to fail:
188
1890. `test_abstract_ipc`: tests Linux-specific IPC functions, and is
190 expected to fail on non-Linux platforms.
191
1920. `test_fork`: tests ability to use ZeroMQ both before *and* after
193 fork (and before exec()); this relies on the ability to use
194 pthreads both before *and* after fork. On z/OS (and some other
195 UNIX compliant platforms) functions like `pthreads_create` (used
196 by ZeroMQ) cannot be used after fork and before exec; on z/OS the
197 call after fork fails with `ELEMULTITHREADFORK` (errno=257) if
198 ZeroMQ was also used before fork. (On z/OS it appears possible
199 to use z/OS *after* fork, *providing* it has not been used before
200 fork -- the problem is the two separate initialisations of the
201 threading library, before and after fork, attempting to mix
202 together.) In practice this is unlikely to affect many real-world
203 programs -- most programs use threads or fork without exec, but
204 not both.
205
2060. `test_diffserv`: tests ability to set IP_TOS ([IP Type of
207 Service](http://en.wikipedia.org/wiki/Type_of_service), or
208 [DiffServ](http://en.wikipedia.org/wiki/Differentiated_Services_Code_Point))
209 values on sockets. While z/OS UNIX System Services has the
210 preprocessor defines required, it appears not to support the
211 required functionality (call fails with "EDC8109I Protocol not
212 available.")
213
214These three "expected to fail" tests are listed as XFAIL_TESTS, and
215`runtests` will still consider the test run successful when they fail
216as expected. (`builds/zos/runtests` will automatically skip these
217"expected to fail" tests if running "all" tests.)
218
219In addition `test_security_curve` does not do any meaningful testing,
220as a result of the CURVE support not being compiled in; it requires
221[`libsodium`](http://doc.libsodium.org/), which has not been
222ported to z/OS UNIX System Services yet.
223
224Multicast (via `libpgm`) is also not ported or compiled in.
225
226[TIPC](http://hintjens.com/blog:70), a cluster IPC protocol,
227is only supported on Linux, so it is not compiled into the z/OS
228UNIX System Services port -- and the tests are automatically skipped
229if running "all" tests. (However they are not listed in XFAIL_TESTS
230because without the TIPC support there is no point in even running
231them, and it would be non-trivial to track them by hand.)
232
233
234## ZeroMQ on z/OS UNIX System Services: Library portability notes
235
236### *.cpp
237
238The source code in ZeroMQ is a combination of a C++ core library
239(in `*.cpp` and `*.hpp` files), and a C wrapper (also in `*.cpp`
240files). It is all compiled with the C++ compiler. The IBM XL C/C++
241complier (at least the version used for initial porting) insists
242that C++ source be in `*.C` files (note capital C). To work around
243this issue the compile flag `-+` is used (specified in the `zc++`
244compiler wrapper), which tells the compiler the file should be
245considered C++ despite the file extension.
246
247### XPLINK
248
249The library (and tests) are built in
250[XPLINK](http://www.redbooks.ibm.com/abstracts/sg245991.html) mode
251with the flags `-Wc,xplink -Wl,xplink` (specified in the `zc++`
252compiler wrapper). This is [recommended by IBM for C++
253code](http://publib.boulder.ibm.com/infocenter/zvm/v5r4/index.jsp?topic=/com.ibm.zos.r9.ceea200/xplrunt.htm)
254due to the small functions. (Amongst other things, using XPLINK
255enables function calls with some arguments passed in registers.)
256
257### long long
258
259ZeroMQ makes use of `uint64_t` (which is `unsigned long long` in ILP32
260mode). To enable this the compile flag `-Wc,lang(longlong)` is passed
261to enable `long long`. This is passed from the `zc++` compiler wrapper
262in order to be able to specifically quote the argument to protect the
263parentheses from shell expansion.
264
265### BSD-style sockets, with IPv6 support
266
267ZeroMQ uses BSD-style socket handling, with extensions to support IPv6.
268BSD-style sockets were merged into SysV-derived UNIX at least a decade
269ago, and are required as part of the X/Open Portability Guide at least
270as of XPG 4.2. To access this functionality two feature macros are
271defined:
272
273 _XOPEN_SOURCE_EXTENDED=1
274
275 _OPEN_SYS_SOCK_IPV6
276
277The first enables the XPG 4.2 features (including functionality like
278`getsockname()`), and the latter exposes IPv6 specific functionality
279like `sa_family_t`. These flags are defined in the `cxxall` script.
280
281(The traditional BSD-sockets API, exposed with `_OE_SOCKETS` cannot
282be used because it does not support functions like `getsockname()`,
283nor does it support IPv6 -- and the API definitions prevent compiling
284in LP64 mode due to assumptions about long being 32 bits. Using
285`_XOPEN_SOURCE_EXTENDED=1` avoids all these problems.)
286
287### pthreads
288
289ZeroMQ uses the pthreads library to create additional threads to handle
290background communication without blocking the main application. This
291functionaity is enabled on z/OS UNIX System Services by defining:
292
293 _OPEN_THREADS=3
294
295which is done in the `cxxall` script. (The "3" value exposes later
296pthreads functionality like `pthread_atfork`, although ZeroMQ does not
297currently use all these features.)
298
299If compiling on a *recent* version of z/OS UNIX System Services it
300may be worth compiling with:
301
302 _UNIX03_THREADS=1
303
304which enables a later version of the threading support, potentially
305including `pthread_getschedparam` and pthread_setschedparam`; at
306present in the z/OS UNIX System Services port these functions are
307hidden and never called. (See [IBM z/OS pthread.h
308documentation](http://pic.dhe.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.bpxbd00/pthrdh.htm)
309for details on the differences.)
310
311
312## `platform.hpp` on z/OS UNIX System Services
313
314The build (described above) on z/OS UNIX System Services uses a static
315pre-built `platform.hpp` file. (By default `src/platform.hpp` is
316dynamically generated as a result of running the `./configure` script.)
317The master version of this is in `builds/zos/platform.hpp`.
318
319Beware that this file contains the version number for libzmq (usually
320included during the configure phase). If taking the `platform.hpp` from
321an older version to use on a newer libzmq be sure to update the version
322information near the top of the file.
323
324The pre-built file is used because z/OS does not have the GNU auto tools
325(`automake`, `autoconf`, `libtool`, etc) installed, and particularly the
326libtool replacement does not work properly with the IBM XL C/C++
327compiler.
328
329The `./configure` script (only supplied in the tarballs); built with
330`automake` and `autoconf` on another platform), with one small edit,
331was used to generate the z/OS `platform.hpp` and then two small changes
332(described below) were made by hand to the generated `platform.hpp`.
333
334To be able to run the ./configure script to completion (in tcsh
335syntax):
336
337* Edit `./configure` and add:
338
339 openedition)
340 ;;
341
342 immediately before the line:
343
344 as_fn_error $? "unsupported system: ${host_os}." "$LINENO" 5
345
346 (somewhere around 17637). This avoids the configure script giving
347 up early because `openedition` is not recognised.
348
349* set `CXX` to point that the full path to the `builds/zos/zc++` wrapper, eg
350
351 setenv CXX "/u/0mq/zeromq-4.0.4/builds/zos/zc++"
352
353* set `CPPFLAGS` to for the feature macros required, eg:
354
355 setenv CPPFLAGS "-D_XOPEN_SOURCE_EXTENDED=1 -D_OPEN_THREADS=3 -D_OPEN_SYS_SOCK_IPV6 -DZMQ_HAVE_ZOS"
356
357* set `CXXFLAGS` to enable XPLINK:
358
359 setenv CXXFLAGS "-Wc,xplink -Wl,xplink -+"
360
361* run configure script with `--disable-eventfd` (`sys/eventfd.h` does
362 not exist, but the test for its existance has a false positive on
363 z/OS UNIX System Services, apparently due to the way the `c++`
364 compiler wrapper passes errors back from the IBM XL C/C++ compiler),
365 and with `--with-poller=poll` because `poll` is the most advanced
366 of the file descriptor status tests available on z/OS. That is:
367
368 ./configure --disable-eventfd --with-poller=poll
369
370All going well several Makefiles, and `src/platform.hpp` should be
371produced. Two additional changes are required to `src/platform.hpp`
372which can be appended to the end:
373
374 /* ---- Special case for z/OS Unix Services: openedition ---- */
375 #include <pthread.h>
376 #ifndef NI_MAXHOST
377 #define NI_MAXHOST 1025
378 #endif
379
380(many includes require pthreads-related methods or data structures to
381be defined, but not all of them include `pthread.h`, and the value
382`NI_MAXHOST` is not defined on z/OS UNIX System Services -- the 1025
383value is the conventional value on other platforms).
384
385Having done this the Makefiles can be used to compile individual files
386if desired, eg:
387
388 cd src
389 make zmq.o
390
391but note:
392
393* IBM Make will warn of duplicate prerequisites on *every* run of
394 `make`, and both the generated `src/Makefile` and `tests/Makefile`
395 have several duplicates. (For `src/Makefile` edit
396 `libzmq_la_SOURCES` to remove the duplicates.)
397
398* IBM Make does not understand the `@` prefix (eg, `@echo`) as a way
399 to avoid echoing the command, resulting in an error and the command
400 being echoed anyway.
401
402* Many of the make targets result in GNU auto tools (`aclocal`, etc)
403 being invoked, which are likely to fail, and most of the
404 library-related targets will invoke `libtool` which will cause
405 compile failures (due to differences in expected arguments).
406
407However running `./configure` to regenerate `src/platform.hpp` may
408be useful for later versions of ZeroMQ which add more feature tests.
409
410
411## Transferring from GitHub to z/OS UNIX System Services
412
413The process of transferring files from GitHub to z/OS UNIX System
414Services is somewhat convoluted because:
415
416* There is not a port of git for z/OS UNIX System Services; and
417
418* z/OS uses the EBCDIC (IBM-1047) character set rather than the
419 ASCII/ISO-8859-1 character set used by the ZeroMQ source code
420 on GitHub
421
422A workable transfer process is:
423
424* On an ASCII/ISO-8859-1/UTF-8 system with `git` (eg, a Linux system):
425
426 git clone https://github.com/zeromq/libzmq.git
427 git archive --prefix=libzmq-git/ -o /var/tmp/libzmq-git.tar master
428
429* On a ASCII/ISO-8859-1/UTF-8 system with `tar`, and `pax`, and
430 optionally the GNU auto tools (eg, the same Linux system):
431
432 mkdir /var/tmp/zos
433 cd /var/tmp/zos
434 tar -xpf /var/tmp/libzmq-git.tar
435 cd libzmq-git
436 ./autogen.sh # Optional: to be able to run ./configure
437 cd ..
438 pax -wf /var/tmp/libzmq-git.pax libzmq-git
439 compress libzmq-git.pax # If available, reduce transfer size
440
441* Transfer the resulting file (`libzmq-git.pax` or `libzmq-git.pax.Z`)
442 to the z/OS UNIX System Services system. If using FTP be sure to
443 transfer the file in `bin` (binary/Image) mode to avoid corruption.
444
445* On the z/OS UNIX System Services system, unpack the `pax` file and
446 convert all the files to EBCDIC with:
447
448 pax -o from=iso8859-1 -pp -rvf libzmq-git-2014-07-23.pax
449
450 or if the file was compressed:
451
452 pax -o from=iso8859-1 -pp -rvzf libzmq-git-2014-07-23.pax.Z
453
454The result should be a `libzmq-git` directory with the source in
455EBCDIC format, on the z/OS UNIX System Services system ready to start
456building.
457
458See also the [`pax` man
459page](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa500%2Fr4paxsh.htm),
460some [`pax` conversion
461examples](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa400%2Fbpxza4c0291.htm),
462and [IBM's advice on ASCII to EBCDIC conversion
463options](http://www-03.ibm.com/systems/z/os/zos/features/unix/bpxa1p03.html)
464