bits for users, published on CVMFS so that nothing has to be installed. The
repository builds bits itself together with its own runtime: Python with the
modules bits imports, Tcl, and Environment Modules (modulecmd). bits runs them
by path, so it changes nothing in the environment of what it builds or loads. A
small entry point, /cvmfs/bits.cern.ch/bits/bin/bits, runs it on any supported
platform. Given a community, it builds with that community's recipes and reuses
what the community has published on CVMFS:
/cvmfs/bits.cern.ch/bits/bin/bits q # plain bits (your sw/ dir)
ln -s /cvmfs/bits.cern.ch/bits/bin/bits ~/bin/bits-key4hep
cd key4hep.bits
bits-key4hep build key4hep # reuses what is on CVMFS, builds the rest in sw/
bits-key4hep enter key4hep/latest # from sw/: local builds first, then reused ones
BITS_COMMUNITY=LHCB /cvmfs/bits.cern.ch/bits/bin/bits build GaudiThe repository stands alone. It needs no other recipe repository, no compiler
package and no LCG release: defaults-release.sh holds the CVMFS layout, and the
recipes are plain shell that builds with the compiler of the build host or
builder image. Their sources come from the projects' own release downloads and
from PyPI (bits' Python modules), at versions chosen here, not by a software
stack. A compiler profile, if one is ever wanted, is another
defaults-<name>.sh here.
Without this install, nothing changes: a bits checkout or pip install has no
runtime/ and uses python3 and modulecmd from PATH as before, and the entry
point exists only on CVMFS.
bitsinstalls the runtime part of a bits checkout (the scripts withbits_helpers/,keys/andtemplates/beside them) underlibexec/bits, and copies the three packages below, which it needs only to build, intolibexec/bits/runtime, and checks that nothing in it loads a library from the host other than the C library (andlibgcc_s), or through a search path that is not$ORIGIN-relative. bits findsruntime/bin/python3andruntime/bin/modulecmdbeside itself and runs them by path, the Python with-E -sso that the PYTHON* variables of an entered environment do not reach it. Its modulefile, written by the recipe, puts only bits on PATH. The recipe builds bitsmain.bits-pythonis a static CPython with bits' modules installed into it, pinned with everything they pull in, without what bits never uses (test suite, IDLE, Tk, curses, readline, dbm, and pip, so nothing can be installed into it later). It finds its standard library from its own location, so it needs nothing on LD_LIBRARY_PATH or PYTHONPATH. Its extension modules link the libraries below statically. Its OpenSSL does not know where the host keeps its CA certificates, sossl(urllib) and certifi (requests, botocore) use the host's bundle (the EL, Debian/Ubuntu and openSUSE locations), else certifi's own: bits trusts what the host trusts, a site CA included. Forssl,SSL_CERT_FILEandSSL_CERT_DIRstill take precedence.OpenSSL(the 3.5 LTS),zlib,bzip2,xz(liblzma),sqliteandlibffiare built as static, position-independent libraries only, forbits-python(and zlib for Tcl). OpenSSL reads no configuration of the host: itsOPENSSLDIRdoes not exist.Tclbuilds only a statictclshand the Tcl script library.environment-modulesis the pure-Tclmodulecmd. Itsbin/modulecmdlocates itself and runs thetclsh8.6beside it, else the one on PATH, so it works wherever it is copied.
git clone https://github.com/bitsorg/bits.bits && cd bits.bits
bits build bits # this host
bits build --docker --architecture x86_64-el8 bits # el8, in its builder imageThe build host or image needs a C compiler with the C library headers, make,
perl with its core modules (perl-core on EL, for OpenSSL's Configure), rsync
and binutils. It needs no development packages, as every library comes from a
recipe here, and is better without them. bits-python stops if a standard
module bits needs was not built, and bits if the runtime would need a host
library. The build architecture is the platform itself (x86_64-el8,
ubuntu2404_x86-64, …).
Build once per CPU, on the oldest platform the CI builds for it: x86_64-el8
and aarch64-el9. The runtime needs nothing of the host but the C library, so
a build on the oldest glibc runs on every newer glibc Linux (not musl, e.g.
Alpine): el8 (glibc 2.28) and later on x86_64, el9 (2.34) and later on
aarch64, and current Ubuntu on both. The wheels are pinned at versions that
ship for the same glibc (manylinux_2_28 and older). If bits' wheels ever stop
shipping for glibc 2.28, bits-python fails at its pip install, and the x86_64
build moves to el9.
For CVMFS, build in the bits-console Bits community
(communities/Bits in bits-console, cvmfs_prefix: /cvmfs/bits.cern.ch/bits):
package bits, no defaults or extra arguments, the platforms ticked in the
matrix (x86_64-el8 and aarch64-el9), with Publish to CVMFS and
Create release view. The packages go to
/cvmfs/bits.cern.ch/bits/<arch>/Packages, and the merged view, which the entry
point runs from, to /cvmfs/bits.cern.ch/bits/views/current/<arch>. The view
holds bits alone, its runtime included. Every build of a new bits main
replaces the view (the community's replace_on_conflict, which the prepub
daemon must allow too); an unchanged one is skipped.
entry/bits and entry/communities are published by hand, once and whenever they
change, as /cvmfs/bits.cern.ch/bits/bin/bits (mode 755) and
/cvmfs/bits.cern.ch/bits/etc/communities. They are the only files outside the
build's layout.
The entry point does the following:
-
It picks the view for the host,
views/current/<arch>: the one for the host's CPU (x86_64,aarch64). If there are several for the CPU, one per OS, it takes the one for the host's OS (el9, say; it recognises EL hosts, fromPLATFORM_ID, and Ubuntu), and finds none on another OS. So publish one view per CPU, as above.BITS_RUNTIME_VIEW=<path of a view>runs another view, e.g. a new one before it is announced. -
It works out the community, in this order:
- the link name
bits-<community>; $BITS_COMMUNITY(or$BITS_ORGANISATION, its former name), the variable bits itself uses for the community's recipes;- the CVMFS repository the link is in, from the
repositoriescolumn ofetc/communities.
It exports the result as
BITS_COMMUNITY, in upper case. - the link name
-
For a community listed in
etc/communities, it setsBITS_REUSE_FROM=cvmfsunless the variable is already set. That is the default ofbits build --reuse-from(bits' opt-in reuse of deployed components): a build reuses what the community published on CVMFS, by exact content hash under the defaultstrictpolicy, and builds the rest. An explicit--reuse-from, also from abits useprofile, wins;BITS_REUSE_FROM=turns it off. Recipes without a CVMFS layout, or with nothing deployed for the architecture, build without reuse, with a warning. -
For such a community with a
prefixinetc/communities, it also setsBITS_CVMFS_PREFIXto it, unless the variable is already set (empty turns it off).bits q,enter,load,printenv,unloadandsetenvthen also use the modules the community published under<prefix>/<arch>/Modules/modulefiles, for the architecture (-aor the detected one), the same without its-opt/-dbg(the toolchain) and with the other one, after the local ones: local builds always come first. -
It runs bits on the user's own work directory.
bits cvmfs showandbits cvmfs summaryread the CVMFS tree itself.
The entry point sets no PATH, LD_LIBRARY_PATH or PYTHONPATH: bits uses its own runtime.
The entry point uses bash and GNU coreutils (realpath -s, readlink -f), so
Linux only. Absolute links from another repository work on clients that mount
/cvmfs/bits.cern.ch too. A container that bind-mounts only some repositories
must include it.
- bits needs three changes. The
runtime/lookup (inbits,bitsenvandbitsStore), the$BITS_REUSE_FROMdefault of--reuse-fromand the$BITS_CVMFS_PREFIXmodule trees must be in the bits release thatbits.shbuilds. - Reuse reads the community's CVMFS modules tree at the start of every build in its recipes, a cost that the opt-in flag paid only when asked for.
- The community table is written by hand, prefixes included (each the
system: prefixof the community's recipes). Reuse does not work yet foraliceandcms, nor do their CVMFS modules (no prefix): bits cannot expand the{install_dir}in alice.bits' modules template, and cms.bits declares no CVMFS layout, so their builds skip reuse with the warning. Generating the table from the bits-consoleui-config.yamlfiles would keep it in step. - No bits-providers entry yet. Without
bits.bits.shand aregistry.jsonentry in bits-providers,bits init bits.bitsandBITS_COMMUNITY=BITSdo not work. A plain clone does. version: "0.6"while the recipe buildsmain.bits --versionsays 0.6 whichever commit it was built from; set the version (andtag:) to a release once there is one.- Versions are kept up to date by hand. The C libraries, Python and the
pinned wheels (update the list with bits'
pyproject.toml) are bumped here, a security fix included; a new bits view follows. The wheels come from PyPI without hash checking.