Skip to content

Releases

CC/370 v1.6.3

Choose a tag to compare

@github-actions github-actions released this 14 Oct 18:22
802dde1

CC/370 (cc370) 1.6.3 is a patch release of the host-native MVS 3.8j toolchain. It fixes how as370 assembles and dasm370 disassembles MVCK, MVCP and MVCS. The compiler, the linker and the other tools are unchanged from 1.6.2 apart from the version they report. It is a drop-in for 1.6.2; the requirements are unchanged (LIBC/370 >= 2.3.0, maclib370 >= 1.0.0).

Read this first: what a caller can see

  • Who needs it: anyone who writes MVCK, MVCP or MVCS in assembler source, typically cross-memory or key-switching code in an SVC. These three carry two registers in their second byte, R1 (the true length) and R3 (the key), written D1(R1,B1),D2(B2),R3. as370 1.6.2 and earlier treated R1 as a length, stored it minus one across the whole byte and ignored R3. The machine then read the length and the key from the wrong registers -- in MVCK 16(4,10),32(11),7 the byte became 03, length from register 0 instead of 4 and key from register 3 instead of 7 -- and the assembly still ended with rc 0.
  • What 1.6.3 does: R1 and R3 are assembled as the Principles of Operation define them. The IBM assembler of MVS 3.8j (Assembler XF) does not know these three instructions, so there is no IBM object to compare against; the encoding follows the architecture.
  • New errors: a missing R3 now stops with severity 12; an R1 or R3 outside 0-15, or an omitted R1, with severity 8. Before, they assembled silently.
  • Reassemble any module that uses these instructions. Code that wrote them as DC X'D9..' to work around the defect can now use the mnemonics.
  • dasm370 shows the two registers as well: D943 2000 5000 now reads MVCK 0(4,2),0(5),3 instead of MVCK 0(68,2),0(5). A disassembly reassembles to the same bytes in both versions.
  • TPROT was never affected.

Fixed: before and now

source 1.6.2 1.6.3
MVCK 0(4,2),0(5),3 D903 2000 5000, rc 0 D943 2000 5000
MVCK 16(4,10),32(11),7 D903 A010 B020, rc 0 D947 A010 B020
MVCP 0(4,2),0(5),3 DA03 2000 5000, rc 0 DA43 2000 5000
MVCS 0(4,2),0(5),3 DB03 2000 5000, rc 0 DB43 2000 5000
MVCK 0(4,2),0(5) (no R3) D903 2000 5000, rc 0 severity 12

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependencies, libc370 and maclib370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.6.3-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.6.3_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0) and maclib370 (>= 1.0.0)
cc370-1.6.3.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel and maclib370 the same way
install.sh the installer above
ml01-0001-0.pdf, ml01-0002-0.pdf CC/370 User's Guide and Command Reference, Draft edition, for 1.6.3

Full changelog

Fixed

  • as370/dasm370: MVCK, MVCP and MVCS encode their two registers
    (#947). These three carry R1 and R3 in the second byte, written
    D1(R1,B1),D2(B2),R3. as370 took the R1 subscript for a length, wrote it
    minus one across the whole byte and never read R3: MVCK 0(4,2),0(5),3
    came out D903 2000 5000 where the machine needs D943 2000 5000, at
    rc 0. A missing R3 now fails at severity 12, and an R1 or R3 outside 0-15
    at severity 8. dasm370 decoded the same byte as a length, so a disassembly
    now reads MVCK 0(4,2),0(5),3 instead of MVCK 0(68,2),0(5); the bytes
    reassemble unchanged either way. Assembler XF does not know these three
    instructions, so their encoding follows the Principles of Operation.
    TPROT was not affected.

CC/370 v1.6.2

Choose a tag to compare

@github-actions github-actions released this 13 Oct 18:53
7b7506e

CC/370 (cc370) 1.6.2 is a patch release of the host-native MVS 3.8j toolchain. It fixes ld370 for a common area (COM) that has the name of a control section (CSECT). The compiler, the assembler and the other tools are unchanged from 1.6.1 apart from the version they report. It is a drop-in for 1.6.1; the requirements are unchanged (LIBC/370 >= 2.3.0, maclib370 >= 1.0.0).

Read this first: what a caller can see

  • Who needs it: anyone who links objects in which one name is a CSECT in one object and a COM in another, for example separately compiled routines sharing an external variable that one of them initialises. When an object with the COM came after the one with the CSECT, ld370 1.6.1 and earlier turned the CSECT into an empty common area. Its data, an initial value such as DC F'100', was gone, and the link still ended with rc 0.
  • What 1.6.2 does: the CSECT keeps its place and its data however the objects are ordered, as the IBM linkage editor does. For the orders that link, measured against it, the module text is byte-identical.
  • A new error: a COM longer than the CSECT of its name now stops the link, with rc 1, both lengths named and no module written. The IBM linkage editor reports the same case as an error (IEW0552).
  • Relink a module built with an earlier ld370 from such objects.

Fixed: before and now

objects, in link order 1.6.1 1.6.2
COUNT COM, COUNT CSECT with DC F'100' SD with 100 SD with 100
COUNT CSECT with DC F'100', then COUNT COM empty common area, rc 0 SD with 100
COUNT COM, COUNT CSECT, COUNT COM empty common area, rc 0 SD with 100
COUNT CSECT (4 bytes), COUNT COM (8 bytes) common area of 8, data lost rc 1, IEW0552, no module

The README and the User's Guide also tell Linux users what to do when brew install stops with "Broken pipe" (a Homebrew issue): set HOMEBREW_GITHUB_API_TOKEN, or run it again.

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependencies, libc370 and maclib370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.6.2-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.6.2_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0) and maclib370 (>= 1.0.0)
cc370-1.6.2.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel and maclib370 the same way
install.sh the installer above
ml01-0001-0.pdf, ml01-0002-0.pdf CC/370 User's Guide and Command Reference, Draft edition, for 1.6.2

Full changelog

Fixed

  • ld370: a common area of the name of a control section binds to the
    control section, in either order
    (#941). When an object with NAME COM
    came after one with NAME CSECT, ld370 turned the CSECT into a common area:
    its text was dropped -- an initial value such as DC F'100' was gone -- and
    every reference went to an empty area, rc 0. A common before the CSECT was
    already right. Now the CSECT keeps its place and its data however the
    objects are ordered, as the IBM linkage editor does (measured: identical
    text). A common longer than the control section of its name is an error,
    as there (IEW0552): ld370 names both lengths, ends with rc 1 and writes no
    module.

Documentation

  • Homebrew on Linux: "Broken pipe". Homebrew 7 looks for macOS keychain
    credentials on Linux too, and that lookup sometimes ends brew install
    with "Broken pipe". The README and the User's Guide say what helps: set
    HOMEBREW_GITHUB_API_TOKEN to any GitHub token with read access, or run
    the command again.

CC/370 v1.6.1

Choose a tag to compare

@github-actions github-actions released this 11 Oct 20:06
469e6f7

CC/370 (cc370) 1.6.1 is a patch release of the host-native MVS 3.8j toolchain. It fixes install.sh for an upgrade to LIBC/370 (libc370) 2.8. The compiler, the assembler, the linkage editor and the tools are unchanged from 1.6.0 apart from the version they report. It is a drop-in for 1.6.0; the requirements are unchanged (LIBC/370 >= 2.3.0, maclib370 >= 1.0.0), and install.sh picks LIBC/370 2.8.1 today.

Read this first: what a caller can see

  • Who needs it: anyone who installs or upgrades with install.sh, or by unpacking the tarballs by hand. LIBC/370 2.8 no longer carries its own copies of 118 system macros; maclib370 provides them. install.sh 1.6.0 copied the new LIBC/370 over the old one and removed nothing, so the old copies stayed in cc370/macros and were found before maclib370's members of the same name, without a message.
  • What 1.6.1 does: before it copies LIBC/370 in, install.sh deletes the files the new LIBC/370 lists as no longer shipped (share/libc370/sysmac-removed.txt, from LIBC/370 2.8.1) and says how many. Only names on that list are touched; files of your own stay.
  • Not affected: Homebrew and the .deb/.rpm packages; their package managers remove an old version's files.
  • Already upgraded with 1.6.0's install.sh? Run the 1.6.1 installer once more, or delete from cc370/macros the files named in share/libc370/sysmac-removed.txt.

Fixed: before and now

1.6.0 1.6.1
install.sh over a LIBC/370 2.7 install 118 old system macros stay in cc370/macros and shadow maclib370 removed before the copy, "removed N macro files ..."
unpacking the LIBC/370 tarball by hand not documented README and User's Guide: delete the listed files first

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependencies, libc370 and maclib370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.6.1-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.6.1_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0) and maclib370 (>= 1.0.0)
cc370-1.6.1.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel and maclib370 the same way
install.sh the installer above
ml01-0001-0.pdf, ml01-0002-0.pdf CC/370 User's Guide and Command Reference, Draft edition, for 1.6.1

Full changelog

Fixed

  • install.sh removes the macro files a newer LIBC/370 no longer ships
    (#933). It copied the new sysroot over the old one and removed nothing,
    so after an upgrade to LIBC/370 2.8 the 118 system macros it used to
    carry stayed in cc370/macros and were found before maclib370's members
    of the same name, without a message. From LIBC/370 2.8.1 the release
    lists them (share/libc370/sysmac-removed.txt), and install.sh deletes
    those files before it copies the new sysroot in, naming how many. Only
    names on the list are touched. Homebrew and the .deb/.rpm packages
    were not affected.

CC/370 v1.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 18:51
9093664

CC/370 (cc370) 1.6.0 is a minor release of the host-native MVS 3.8j toolchain. The system macros of MVS 3.8j -- all of SYS1.MACLIB and SYS1.AMODGEN -- now come with the toolchain as the package maclib370, and as370 finds them with no -I. The release also fixes a wrong address in one form of address constant and a wrong search byte in one compiler fold. It is a drop-in for 1.5.x. One thing is new: every way of installing CC/370 now also installs maclib370 (>= 1.0.0). The LIBC/370 (libc370) requirement is unchanged (>= 2.3.0); install.sh picks the newest release that fits, 2.7.0 today.

Read this first: what a caller can see

  • A second dependency: maclib370. The .deb depends on maclib370 (>= 1.0.0), the .rpm requires it, Homebrew installs mvslovers/tap/maclib370 with CC/370, and install.sh puts it into $PREFIX/cc370/maclib370. With .deb/.rpm files, install it in the same command: apt install ./cc370_1.6.0_amd64.deb ./libc370-dev_2.7.0_all.deb ./maclib370_1.0.0_all.deb.
  • System macros without -I. as370 searches <exedir>/../maclib370/macros after its own and LIBC/370's macros. A program that uses TIME, SPIE or any other system macro assembles as it is. A copy of SYS1.MACLIB that you name with -I or AS370_MACLIB is still searched first, and the macros of the C library and the prologue macros still win over an IBM original of the same name.
  • Rebuild code that uses strstr(s, "x") or strpbrk(s, "x") with a one-character literal. Up to 1.5.0, at -O1, such a call searched for the ASCII value of the character, not its EBCDIC one (see the table).
  • Reassemble modules where one name is both a V() target and a label of the same assembly, and also appears in an A(). Up to 1.5.0 the A() linked to twice the label's offset (see the table).
  • More than 16 macro libraries is an error. -I and AS370_MACLIB together take at most 16 directories. One more is named on stderr, the run ends with rc 16 and writes no object.

Fixed: before and now

1.5.0 1.6.0
strstr(s, "}") / strpbrk(s, "}") at -O1 searches for X'7D' (a quote in CP037) searches for X'D0', }
DC A(NAME) where NAME is a label here and also V(NAME) relocated against the external reference: linked to twice the offset (X'1404' for X'0A02', measured with IEWL on MVS) relocated against the section that holds the label, as the IBM assembler does
a 17th -I read as a second source file; rc 16 with a message about the wrong thing rc 16, names the directory and the limit
a 17th AS370_MACLIB entry dropped without a word; its macros undefined rc 16, names the directory
16 -I directories the toolchain's own macro libraries pushed out of the path always searched
TIME DEC with no -I Undefined operation code, rc 8 assembles

Measured for 1.6.0: 184 generated programs with the address-constant form all match the IBM assembler's object decks now (7 differed before); 5,528 modules of the MVS 3.8j source tree and 1,294 objects of twelve C and assembler projects are unchanged by the assembler fix.

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependencies, libc370 and maclib370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.6.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host; unpack LIBC/370's sysroot tarball into its cc370/ and maclib370's tarball into cc370/maclib370/
cc370_1.6.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0) and maclib370 (>= 1.0.0)
cc370-1.6.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel and maclib370 the same way
install.sh the installer above (NO_MACLIB370=1 leaves maclib370 out)
ml01-0001-0.pdf CC/370 User's Guide, Draft edition, for 1.6.0
ml01-0002-0.pdf CC/370 Command Reference, Draft edition, for 1.6.0

maclib370 is released at https://github.com/mvslovers/maclib370/releases. The manuals are built from the tagged sources; the Draft edition still lacks the figures whose output is captured on MVS.

Full changelog

Added

  • as370 searches <exedir>/../maclib370/macros, after
    <exedir>/../macros and <exedir>/../libc370/macros. That is where the
    SYS1.MACLIB and SYS1.AMODGEN of MVS 3.8j go when they are installed as a
    package of their own, so an installed as370 then assembles a program using
    any system macro with no -I. The directory comes last, so a macro of
    the C library and the prologue macros win over an IBM original of the same
    name; when it is absent, nothing changes. It has a reserved place in the
    search path like the other two.
  • maclib370 is installed with CC/370. The .deb depends on
    maclib370 (>= 1.0.0) and the .rpm requires it; the Homebrew formula
    depends on mvslovers/tap/maclib370 and links it in as
    cc370/maclib370; install.sh installs its latest release into
    $PREFIX/cc370/maclib370 (MACLIB370_VERSION= names one, NO_MACLIB370=1
    leaves it out). maclib370 depends on nothing. A program using a system
    macro such as TIME now assembles with no -I.

Fixed

  • cc370: strstr and strpbrk with a one-character literal search for
    the right byte
    (#916). At -O1 the compiler turns strstr(s, "}") and
    strpbrk(s, "}") into strchr(s, c), and took c as the host (ASCII)
    value of the character instead of its EBCDIC one: "}" searched for
    X'7D', a quote in CP037, instead of X'D0'. Every one-character needle
    whose ASCII and EBCDIC codes differ was searched for wrongly, without a
    diagnostic. The byte now goes through the same translation as every other
    character constant. Code built with an earlier release that uses this
    pattern needs a rebuild.
  • as370: A(name) relocates against the section that holds name, even
    when V(name) also made it an external reference
    (#919). A name both
    called through V(name) and defined in the same assembly (typically as an
    ENTRY in a second CSECT) kept the external reference's ESD id, in either
    order, and an A(name) was relocated against it. The constant already
    holds the label's address, so the linkage editor added that address a
    second time: measured with IEWL on MVS, X'1404' where IFOX00's deck gives
    X'0A02', and ld370 links the same. The text was byte-identical and the
    return code 0. A V(name) still relocates against the external
    reference. Measured on 184 generated programs: 7 had such a constant, and
    all 184 decks now match IFOX00's. Across the 5,528 modules of the MVS 3.8j
    tree no deck changed.
  • as370: a macro library beyond the limit is an error, and the
    toolchain's own libraries are always searched
    (#918). -I and
    AS370_MACLIB together name at most 16 directories. A further
    AS370_MACLIB entry was dropped without a word, so its macros were
    undefined; a 17th -I left its directory to be read as a second source
    file, rc 16 under a message about the wrong thing; and 16 entries pushed
    <exedir>/../macros and <exedir>/../libc370/macros out of the path.
    Now the directory beyond the limit is named, the run ends with rc 16 and
    writes no object, and the two built-in libraries keep places of their own.

CC/370 v1.5.0

Choose a tag to compare

@github-actions github-actions released this 07 Oct 16:02
6512eef

CC/370 (cc370) 1.5.0 is a minor release of the host-native MVS 3.8j toolchain. It adds -mrent, which makes the compiler report every writable variable a reentrant module would keep in itself, fixes file-scope compound literals, and tightens three corners of ld370. It is a drop-in for 1.4.x: the LIBC/370 (libc370) requirement is unchanged (>= 2.3.0; install.sh picks the newest that fits, 2.6.2 today), and code compiled without the new option is byte-identical to 1.4.0 apart from the version in the eyecatcher and the compound-literal fix below (measured over 824 sources at -O1 and 602 at -Os). The manuals now come with the release as PDFs.

Read this first: what a caller can see

  • ld370 --pack refuses what it used to drop. An input file named before --pack (a member as well as an object or archive), -l or -L anywhere on the command, and a --pack naming no member now end with rc 2, naming the operand. Before, the operand was left out of the library without a word and the command ended rc 0. Put --pack first: ld370 --pack A.iebcopy B.iebcopy -o lib -xmit.
  • The member name from -o is the one that is checked. It is the base name up to the first period: -o app.v1.lm now gives member APP instead of being refused as APP.V1. A name that is not a valid member name is still refused (rc 2) when a transport file or a load map needs it, never cut.
  • -mrent is new and off by default. Pass it to every source of a module you link with --rent; each non-const definition then warns with -Wwritable-data (an error under -Werror, -Wno-writable-data turns it off).

New: -mrent and -Wwritable-data

A reentrant load module is one copy shared by every task that runs it, and CC/370 keeps a C static or global in the module itself. Under -mrent the compiler warns for each such definition that is not const:

prog.c:3: warning: 'count' is writable data in a reentrant module [-Wwritable-data]
prog.c:5: warning: a compound literal is writable data in a reentrant module [-Wwritable-data]

const char *p is writable (the pointer is), char *const p is not; extern declarations and string literals are not reported, and __stklen is exempt. The check covers the sources compiled with the option; code taken from a library by automatic library call is not checked.

Fixed: before and now

1.4.0 1.5.0
static int *p = (int[]){1, 2}; DC A(@V2) with no @V2; the assembler stops with rc 8 the literal is emitted
ld370 X.iebcopy --pack Y.iebcopy -o lib -xmit rc 0, library holds Y only rc 2, names X.iebcopy
ld370 -o MAIN main.o -xmit --pack links MAIN instead of packing rc 2
ld370 -o app.v1.lm … -xmit rc 2, "'APP.V1' is not a valid member name" member APP
ld370 --help on a bare member "packs at entry 0" --entry NAME, else @@CRT0, from its CESD

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.5.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.5.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0)
cc370-1.5.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above
ml01-0001-0.pdf CC/370 User's Guide, Draft edition, for 1.5.0
ml01-0002-0.pdf CC/370 Command Reference, Draft edition, for 1.5.0

The manuals are built from the tagged sources. The Draft edition still lacks the figures whose output is captured on MVS, and some captured examples still show the version strings of 1.4.0.

Full changelog

Added

  • -mrent and -Wwritable-data: writable data in a reentrant module is
    reported by the compiler
    (#885). A reentrant load module is one copy
    shared by every task that LINKs it, and CC/370 keeps a C static or a
    non-const global in the module itself, so such a definition is shared,
    unsynchronised state. Under -mrent every definition that is not const
    warns -- globals, static at file scope and inside functions, and
    const volatile objects; extern declarations and string literals do
    not, and -fwritable-strings warns once. const char *p is writable (the
    pointer is), char *const p is not. __stklen is exempt: the startup
    reads it as the stack size. The warning is on by default under -mrent,
    an error under -Werror, and -Wno-writable-data switches it off.
    -mrent changes no generated code. A build tool that marks a module
    RENT passes -mrent to every translation unit of it; code that automatic
    library call pulls from a library was compiled without it and is not
    checked.
  • The manuals are attached to the release. ML01-0001 (User's Guide)
    and ML01-0002 (Command Reference), Draft edition, are built from the
    tagged sources and attached as ml01-0001-0.pdf and ml01-0002-0.pdf,
    listed in SHA256SUMS (#893).

Fixed

  • A compound literal at file scope is emitted (#890). static int *p = (int[]){1, 2}; compiled to DC A(@V2) with no @V2, and as370 stopped
    with rc 8, at every optimization level. The literal is a deferred static
    that is written only when a reference marks its name, and the back end
    renamed static variables to @Vn without moving the name the reference
    is checked against. It now does; the same mechanism had also dropped a
    static table referenced only from a global pointer under
    -funit-at-a-time. Under -mrent a writable compound literal warns as
    "a compound literal", and a const one, such as (const int[]){1, 2},
    does not. Nothing else in the generated code changes: 824 sources across
    the ecosystem compile to identical output.
  • ld370 --help no longer says a bare member packs at entry 0 (#896).
    Since 1.3.0 (#850) a bare member's entry is --entry NAME, else @@CRT0,
    looked up in its CESD; the manual page already said so.
  • ld370 checks the member name it writes (#895). The name from -o
    is the base name up to the first period (-o upcase.lm is UPCASE), but
    the validity check cut at the last one: -o app.v1.lm -xmit was refused
    as APP.V1 although APP would have been written. Both now use the same
    name. A name longer than eight characters is still refused, not cut.
  • ld370 --pack refuses a link input instead of dropping it (#894). An
    object deck or archive named before --pack went into the link list,
    which a pack ignores: ld370 A.iebcopy --pack B.iebcopy -o lib -xmit
    ended with rc 0 and a library holding B alone. --pack with no member
    linked the other operands instead, and -l/-L were searched for
    nothing. Every operand after --pack is a member; any input file named
    before --pack (a member to pack included), -l or -L on a --pack
    command, and a --pack naming no member, are now refused with rc 2,
    naming the operand, and nothing is written.
  • install.sh names a failed GitHub API call instead of reporting "no
    LIBC/370 release fits"
    (#879). When the API's rate limit (60 requests an
    hour per address) was used up, the release list came back empty and the
    script said that no LIBC/370 fitted, installed CC/370 alone and ended with
    rc 0. Since 1.4.0 a link needs LIBC/370, so the result was a compiler that
    could not link, with a message pointing at the wrong problem. Every API
    call is now checked: a rate limit is named with the minutes until it
    resets, any other HTTP status and a failed connection likewise, and the
    script ends with rc 1. "No release fits" is kept for a list that was read
    and had no match. GITHUB_TOKEN is sent to the API when set, and a
    release list on one line is read whole. Run by zsh (| zsh), the script
    skipped LIBC/370 with the same message, because zsh does not split words;
    it now turns that on. The 1.4.0 release's install.sh asset was replaced
    with this version on 2026-10-05 (and its SHA256SUMS line with it); the
    toolchain archives and packages were not changed.

CC/370 v1.4.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 11:54
2821ebb

CC/370 (cc370) 1.4.0 is a minor release of the host-native MVS 3.8j toolchain. The driver no longer links a separate crt0.o: the C startup @@CRT0 now comes from libc.a by automatic library call. This needs LIBC/370 (libc370) >= 2.3.0, which is where the startup moved into the archive. Compiling, assembling and every other command line behave as in 1.3.1. With LIBC/370 2.3.0 or later it is a drop-in; install.sh picks the newest LIBC/370 that accepts this CC/370 (2.3.1 today).

Read this first: what a caller can see

  • A link through the driver (cc370 foo.c -o foo) needs LIBC/370 >= 2.3.0. Against an older LIBC/370, main fails to link because @@CRT0 is unresolved. The packages enforce the floor: the .deb has Depends/Breaks and the .rpm has Requires/Conflicts on LIBC/370 2.3.0. To upgrade an existing install, run install.sh again or brew upgrade; either brings in the matching libc370.
  • @@CRT0 no longer has to sit at offset 0 of the load module. The directory entry points to it wherever it lands (0x80 for a plain hello world), and ld370 --pack reads a bare member's entry from its CESD.
  • A link that calls ld370 directly with its own object list is unaffected.

Changed: before and now

1.3.1 1.4.0
startup on a driver link crt0.o named on the link line, first in the module @@CRT0 pulled from libc.a by autocall, entry set in the directory
LIBC/370 required >= 2.1.0 >= 2.3.0

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

install.sh asks the GitHub API for the release lists, which allows 60 requests an hour per address. When that is used up, it says so, names the minutes until the reset and stops with rc 1. Retry later, set GITHUB_TOKEN, or name the releases with CC370_VERSION= and LIBC370_VERSION=. (The install.sh first attached to this release reported that case as "no LIBC/370 release fits" and installed CC/370 alone; it was replaced on 2026-10-05.)

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.4.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.4.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.3.0)
cc370-1.4.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above
ml01-0001-0.pdf CC/370 User's Guide, Draft edition
ml01-0002-0.pdf CC/370 Command Reference, Draft edition

The two manuals were added to this release on 2026-10-07, together with their lines in SHA256SUMS; the lines of the other files are unchanged. They describe CC/370 1.4; what is marked "From CC/370 1.5.0 on" (-mrent) is not in this release. The Draft edition still lacks the figures whose output is captured on MVS.

Full changelog

Changed

  • The link no longer names crt0.o; it needs LIBC/370 >= 2.3.0
    (libc370#159). Since LIBC/370 2.3.0 the startup @@CRT0 is a member of
    libc.a, and main's stub refers to it, so the automatic library call
    pulls it like any other routine. The driver's startfile is empty, and the
    packages require LIBC/370 2.3.0 (.deb Depends/Breaks, .rpm
    Requires/Conflicts). With an older LIBC/370 a main would not link.
    @@CRT0 no longer has to sit at offset 0: the directory's entry points to
    it, and ld370 --pack takes a bare member's entry from its CESD (#850).

CC/370 v1.3.1

Choose a tag to compare

@github-actions github-actions released this 05 Oct 11:00
2c1485e

CC/370 (cc370) 1.3.1 is a patch release of the host-native MVS 3.8j toolchain. It fixes the weak definitions that 1.3.0 introduced. Nothing else changes: compiling, linking and every command line behave as in 1.3.0, so it is a drop-in. It works with LIBC/370 (libc370) >= 2.1.0 (install.sh picks the newest LIBC/370 that accepts this CC/370).

Read this first: what a caller can see

  • Only code that uses __attribute__((weak)) is affected. A weak definition is now exported, and a weak name may be used before it is defined in the same file.
  • A weak reference's WXTRN now appears at the end of the generated assembler rather than ahead of the first use. The object deck has the same WX entry; IFOX00 gives the same entry for either placement.

Fixed: before and now

1.3.0 1.3.1
a weak definition (int f(void) __attribute__((weak)); int f(void) {...}, or a weak initialized variable) compiled but not exported (no LD), so nothing could link to it exported like an ordinary definition; still warns -Wweak-definition
a weak name used, then defined in the same file rc 8 (IFO196, symbol previously defined) rc 0, exported

Install

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.3.1-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.3.1_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.1.0)
cc370-1.3.1.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above

Full changelog

Fixed

  • cc370: weak definitions are exported, and a weak name may be defined
    after it is used
    (#872). Both were broken in 1.3.0.
    • A weak definition was compiled but not exported (ENTRY=NO, no LD), so
      nothing could link to it. It is now exported like the ordinary
      definition it is.
    • A name declared weak, used and then defined in the same file got its
      WXTRN at the first use, and the definition then failed with IFO196,
      rc 8. The WXTRN is now written at the end of the assembly and only for
      a weak name that stayed undefined; measured on IFOX00, a WXTRN after
      the V-cons gives the same WX entry.

CC/370 v1.3.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 09:38
1c8181e

CC/370 (cc370) 1.3.0 is the host-native MVS 3.8j toolchain -- C compiler, assembler, linker and the transport tools -- with weak references in C, the last missing Assembler XF statements in as370 (COM, DXD, CXD, Q-type constants), and common sections linked the way IEWL links them. Most of the release fixes cases where a tool produced a wrong result without saying so. Source that compiled and linked with 1.2.0 still does. A few command-line behaviours changed, though, and every load module's first eight bytes differ (see below). It works with LIBC/370 (libc370) >= 2.1.0 (the .deb/.rpm say so; install.sh picks the newest LIBC/370 that accepts this CC/370).

Read this first: what a caller can see

  • -v is verbose and -V is the version, in every tool (#811). as370 -v and dasm370 -v used to print the version; they now print verbose output on stderr. Use --version or -V. Every tool, the cc370 driver included, takes -V/--version and -h/--help. cc370 --version is now the single line cc370 1.3.0 (<commit>), based on GCC 3.4.6.
  • as370 writes no object on a wrong command line (#822). An invalid option, a second source file or an unwritable -a=FILE ends with rc 16, as before, but no longer leaves an object behind. The assembly still runs and reports.
  • The eyecatcher in front of main names CC/370 (#813). It is DC C'CC370',AL1(1,3,0) where it was DC C'GCCMVS!!'. It has the same length and @@MAIN stays at offset 8, but every main module differs from a 1.2.0 build in those bytes, so a comparison against an older baseline shows them.
  • Trigraphs are on under every -std (#832). They used to be switched off by -std=gnu89/gnu99, so "x??!y" had two values. Write ?\?! for a literal ??!.
  • The cc370 driver (#808, #833):
    • An as370 warning (rc 4) no longer fails a compile.
    • -c/-S with several sources and one -o is refused.
    • -b/-V<version> are refused.
    • -pipe is accepted and ignored.
    • -mpickax is gone.
    • #pragma map/linkage warn that they have no effect.
  • ld370 return codes follow one rule (#821, #807): rc 2 when the command line is wrong whatever the files hold (nothing is written then), rc 1 when a file or the link fails. A few cases moved from rc 1 to rc 2: a name used twice in one library, more than 32 archives, and a --pack input that is not a load module.
  • ld370 --pack of a bare member takes the entry point from its CESD (#850): --entry NAME, else @@CRT0. Before, it packed at entry 0 and ignored --entry.
  • dasm370 without arguments, or given a file that is no deck or module, now ends rc 2 / rc 16 respectively (#809).

New

  • Weak references in C (#866): extern void f(void) __attribute__((weak)); becomes a WXTRN. Unresolved it is 0 (if (f) f();), and automatic library call does not pull a definer for it. There is no weak definition on MVS: one compiles as an ordinary definition and warns (-Wweak-definition; -Wno-weak-definition switches it off). __CC370_WEAK__ is predefined.
  • as370: COM, DXD, CXD and Q-type constants (#810, #229, #840), byte-identical to IFOX00, listings included.
  • ld370: common sections (#837): one area per name, as long as the longest contribution, after the objects -- IEWL's layout.
  • as370: IFO203 and IFO204, two of IFOX00's diagnostics for address and fixed-point constants that do not fit their field (#776, #840).

Fixed: before and now

before now
A(-SECT), A(-EXT), A(EXT-SECT) in as370 (#824) positive or no relocation -- wrong addresses at rc 0 one relocation per term, in its own direction
a common section in ld370 (#837) placed over the first section, outside the module length after the objects, longest wins
A(BLK), =A(BLK) on a COM name; =Q(PR) literal (#840) no relocation relocated as IFOX00 does
relocatable AL1/AL2/YL1 (#840) relocated with that length at rc 0 IFO204, value 0, as IFOX00
ld370 --pack of a bare member (#850) entry 0 the entry from its CESD
ar370 (#805) objects past 2048 dropped, names over 15 characters cut, at rc 0 no limits; long names in a GNU // table
ld370 inputs (#807) a non-deck file, an unknown option, a bad value accepted refused with rc 1 or 2
xmit370 (#804) member names cut to 8, values unchecked, a non-XMIT input not reported names refused or upper-cased, values checked, a non-XMIT input named
file370 (#806) source libraries read as load libraries, transmissions cut at 4 MB the library's RECFM decides; no size limit
floating-point constants in as370 (#761, #782, #783) modifiers and range limits wrong as IFOX00
a macro's LCLx in as370 (#786) overwrote a global of the same name a local of its own
cmplmd370 on a C module (#809) private code never paired, not even against itself paired by entry point
idrdump370 (#809) linkage-editor and translator records unreadable decoded

Install

The installer -- it installs CC/370 and the newest LIBC/370 that accepts it:

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.3.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.3.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.1.0)
cc370-1.3.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above

Full changelog

Added

  • cc370: weak references (__attribute__((weak)) on a declaration).
    • A weak reference becomes a WXTRN (ESD type WX), written ahead of the
      first reference. Unresolved it is 0 (if (f) f();), and automatic
      library call does not pull a definer for it -- IEWL's rule, which ld370
      already followed.
    • An unreferenced weak declaration produces nothing.
    • MVS has no weak definition: one is compiled as an ordinary definition and
      warns with -Wweak-definition (on by default, so an -Werror build
      stops; -Wno-weak-definition switches it off).
    • __CC370_WEAK__ is predefined, so a library can test for the feature
      rather than for a version.
  • as370: COM, DXD, CXD and Q-type constants (#810, #229). They were
    the last Assembler XF statements and constant types it lacked: COM and
    DXD were undefined operation codes, CXD and DC Q(...) "not
    implemented".
    • COM opens a common section (ESD type CM): its own counter from zero, can
      be resumed, holds no text, and its symbols relocate against it.
    • DXD defines an external dummy section (XD) with the length and alignment
      of its operands.
    • CXD reserves a fullword that is not punched, with an RLD entry of type 3.
    • Q(name) gives an RLD entry of type 2 against the DXD or DSECT it names;
      a DSECT named this way becomes an XD. IFO231 is reported for a name not yet
      defined and IFO207 for one that is neither.
    • Decks and listings were measured on IFOX00 and are byte-identical up to the
      END card.
    • ld370 does not handle pseudo registers yet: they stay unresolved (#76).
      Common sections are allocated since #837.
  • as370: IFO203 (#776), severity 4, for a fixed-point or Y-type constant
    that does not fit its field: F'2147483648', H'65535', FL1'128',
    Y(32768). The signed range of the field decides, A-type is never flagged,
    and the bytes stay the low-order ones as before. Measured on IFOX00: as370
    flags the same 27 values in as370/tests/ifo203.s (FE9'3' since the
    exponent modifier, #782).

Changed

  • cc370: trigraphs under every -std (#832). They were on by default
    and off under -std=gnu89/gnu99, so "x??!y" was x|y in one build and
    x??!y in another. They are now always on (the library spells || as
    ??!??!); write ?\?! for a literal ??!.
  • cc370: -mpickax is gone (#834). It set a flag nothing read.
  • cc370: -pipe is accepted and ignored (#831). As370 reads a file, so
    -pipe failed rc 2 with no object; the output is the same without it.
  • cc370: #pragma map and #pragma linkage warn that they have no effect
    (#830). Both were dropped silently, so the external name stayed cc370's
    own; use __asm__("NAME").
  • -v is verbose and -V the version, in every tool (#811). Read this
    first:
    as370 -v and dasm370 -v used to print the version and now turn
    on verbose output. Use --version or -V instead.
    • as370 -v: the macro search path, each macro with the file it came from,
      and the summary line even on a clean assembly, all on stderr; the deck is
      unchanged.
    • dasm370 -v: the section read, with its origin, length, RLD and LD entries.
      dasm370 now asks as370 for its version with --version.
    • ar370: a trailing v (rcv) names each member written, as GNU ar does.
    • -V is new in as370, dasm370 and cmplmd370, and -h in as370 and dasm370,
      so every tool takes --version/-V and --help/-h.
    • The cc370 driver as well: -V prints the version and -h the usage. Its
      -v stays GCC's verbose mode. --version is now the one line
      cc370 <version> (<commit>), based on GCC 3.4.6, without GCC's copyright
      and warranty lines. GPLv2 asks for that announcement only from a program
      that reads commands interactively; the licence is in COPYING.
    • The driver refuses -b and -V<version> (#833). In GCC they start another
      installed driver: cc370 -bogus tried to run ogus-gcc-1.2.0.
  • The eyecatcher in front of main names CC/370 (#813). A program's
    main module carried DC C'GCCMVS!!', after the c...
Read more

CC/370 v1.2.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 12:49
b17cd14

CC/370 (cc370) 1.2.0 is the host-native MVS 3.8j toolchain -- C compiler, assembler, linker and the transport tools -- with ld370 now linking the way IEWL does. Compiling needs no change from 1.1.x; as370 reports a few more of IFOX00's diagnostics, and linking is not quite a drop-in: modules no longer come out RENT and REUS unless you ask for it (see below). It works with LIBC/370 (libc370) >= 2.1.0 (the .deb/.rpm say so; install.sh picks the newest LIBC/370 that accepts this CC/370).

Read this first: what a caller can see

  • ld370 no longer marks every module RENT and REUS (#100). IEWL marks neither unless told (a plain IEWL link lists ATTR 03F2), and ld370 now does the same. A module that declares no attributes is linked with neither -- declare them with --rent, --reus and --refr, which are independent: IEWL's RENT is --rent --reus. --norent/--noreus are still accepted and change nothing on their own. A --pack of a pre-built -iebcopy keeps that member's own attributes. Why it matters: a server that loads a module once may share one copy of a RENT module between concurrent requests, and CC/370 keeps writable statics in the CSECT -- so a module that is not really reentrant must not claim to be.
  • A duplicate CSECT keeps its first definition (#102), as IEWL does. The later copy is dropped with its text, space, relocations and entries. Until now the last copy won and every copy's text stayed in the module.
  • Two explicit objects defining the same entry now draw a warning (#478), as IEWL's IEW0241; the first definition is kept, as before.
  • as370 raises eight more of IFOX00's diagnostics -- IFO025, IFO043, IFO085, IFO123/IFO124, IFO168, IFO211, IFO254 -- exactly where IFOX00 raises them. Source that IFOX00 flags and as370 used to pass may now end with a higher return code, as it would on MVS.
  • Homebrew links LIBC/370 in with one symlink (#726, #732): a file a later LIBC/370 adds is seen at once, without brew reinstall cc370.

Fixed: before and now

before now
a nested function reading its parent's variables (#686) read through the page-table register -- silently wrong values static chain in R0, correct
its trampoline (#686) clobbered R14, 9-character label, copied with a routine LIBC/370 lacks R15-based, @@LTR0, copied with memcpy
default attributes of a linked module (#100) RENT + REUS neither, as IEWL (03F2)
two CSECTs of one name (#102) last copy won, all text kept first kept, the rest dropped
xmit370 create with a --blocksize below 268 (#118) declared a BLKSIZE smaller than its own directory records -- refused by RECEIVE at least 296; a RECFM=F, BLKSIZE 80 library is received
INMR02 #2 INMRECFM in an xmit370 transmission (#117) differed from every real transmission 4802, as they carry
as370 with more than 128 diagnostics of one kind (#86) the rest dropped silently, and the return code with them every one counted
BRXH / BRXLE in as370 (#56) assembled undefined operation codes, as in IFOX00
TPROT / IPTE in as370 (#56) not known IFOX00's formats: SSE and S

Install

The installer -- it installs CC/370 and the newest LIBC/370 that accepts it:

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.2.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.2.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.1.0)
cc370-1.2.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above

Full changelog

Added

  • A second sysroot (#726): besides its own cc370/{include,lib,macros},
    CC/370 searches cc370/libc370/{include,lib,macros} -- headers in cc1,
    crt0.o and -lc through the driver, macros in as370 -- after the tree's
    own. A LIBC/370 kept in its own tree can be linked in with one symlink;
    the Homebrew formula moves to that with this release, so a file a later
    LIBC/370 adds no longer needs brew reinstall cc370. make test-sysroot
    (part of make test-cc370) checks all four with a stand-in libc370.
  • Homebrew (#699): brew trust mvslovers/tap, then
    brew install mvslovers/tap/cc370 from the tap mvslovers/homebrew-tap,
    on macOS and Linux (Homebrew 7 refuses a dependency from an untrusted
    tap); it depends on
    mvslovers/tap/libc370 and links LIBC/370's sysroot into its own tree.
    release.yml renders the formula (packaging/homebrew/) and pushes it to
    the tap with a deploy key held in the release environment (v* tags
    only); homebrew.yml then installs it from the tap on all four hosts. A
    file a later LIBC/370 adds is seen after brew reinstall cc370 until CC/370
    searches a second sysroot (#726).
    With this release the formula links LIBC/370 with one symlink, and that
    restriction is gone (#732).
  • as370: TPROT and IPTE, in the formats IFOX00 gives them (#56,
    measured against IFOX00): TPROT is SSE D1(B1),D2(B2), IPTE the
    S-format D2(B2) -- not RRE.
  • as370: S' and I' are evaluated in conditional assembly (#258); every
    value confirmed against IFOX00.
  • ld370: --entry seeds automatic library call (#107), so the CRT can live
    inside an archive: an entry still undefined after the fixpoint is pulled by
    name.
  • New as370 diagnostics, as IFOX00 raises them: IFO025 for an
    out-of-sequence card under ISEQ (#128), IFO043 for a macro prototype named
    after an operation (#297), IFO254 for an ill-formed second operand of END
    (#441), IFO085 for a library member without a MACRO header (#427), IFO168
    for an expression of more than 20 terms (#272), IFO211 for an S instruction
    with a second operand (#56), IFO123/IFO124 for S'/I' without a scale
    (#258).
  • ld370 warns when two explicit objects define the same entry (#478), as
    IEWL does (IEW0241); the first definition is kept, as before.

Changed

  • ld370 links modules neither RENT nor REUS by default (#100) -- IEWL's
    default (a plain IEWL link lists ATTR 03F2); until now every module was
    marked RENT+REUS unless told otherwise. That claim had consequences: a
    server that loads a module once shares one copy of a RENT module between
    concurrent requests (measured on MVS: use count 3), and CC/370 keeps
    writable statics in the CSECT. A module that declares no attributes is
    now linked with neither RENT nor REUS; declare them
    with --rent,
    --reus and --refr -- orthogonal, so IEWL's RENT is --rent --reus.
    --norent/--noreus are still accepted and now change nothing on their
    own. A --pack of a pre-built -iebcopy keeps that member's own
    attributes.
  • ld370 keeps the first definition of a duplicate CSECT (#102), as IEWL
    does: the later copy is dropped with its text, space, RLDs and entries, and
    the sections after it move up, as in IEWL's layouts (measured on MVS).
    Until now the last copy won and every copy's text stayed in the module.
  • dasm370 names every section of a multi-section deck on stderr (#439),
    and returns rc 4 when the section it took is empty while another is not.
  • xmit370: the unloaded form declares at least BLKSIZE 296 (#118), so a
    RECFM=F library with BLKSIZE 80 RECEIVEs (measured on MVS; 288 is refused).

Fixed

  • Nested functions (#686): the static chain was passed in R10, which every
    prologue reloads with the page table, so a nested function read its parent's
    variables through the wrong address -- silently. It is now R0; the
    trampoline no longer clobbers R14, its label fits in 8 characters, and it is
    copied with memcpy. Measured on MVS.
  • xmit370: INMR02 #2 INMRECFM is 4802 (#117), as every real transmission
    carries (a RECEIVE on MVS accepts it).
  • as370: the return code no longer depends on the 128-entry diagnostic
    lists
    (#86); MNOTE 0 counts among the flagged statements (#682);
    BRXH/BRXLE are undefined operation codes, as in IFOX00 (#56).
  • make test-corpus builds its baseline again (#744).

CC/370 v1.1.1

Choose a tag to compare

@github-actions github-actions released this 02 Oct 23:31
98d9ab0

A packaging release of CC/370 (cc370): the prebuilt toolchains are stripped. The compiler, the
runtime and the macros are unchanged, so nothing changes for LIBC/370 (libc370) or for
what compiles and links.

Changed

  • The release binaries are stripped (#718): make dist strips the
    driver, cc1 and the tools after installing the tree, so the release
    tarballs and packages carry no symbol tables or debug info; the Linux smoke
    test fails on an ELF binary that is not stripped. make install is
    unchanged and keeps them for development.