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