# BinaryBuilderBase.jl Documentation

This is the reference documentation of BinaryBuilderBase.jl.

## Types

BinaryBuilderBase.AbstractDependencyType

An AbstractDependency is a binary dependency of the JLL package. Dependencies are installed to ${prefix} in the build environment. Concrete subtypes of AbstractDependency are • Dependency: a JLL package that is necessary for to build the package and to load the generated JLL package. • BuildDependency: a JLL package that is necessary only to build the package. This will not be a dependency of the generated JLL package. • HostBuildDependency: similar to BuildDependency, but it will install the artifact for the host platform, instead of that for the target platform. source BinaryBuilderBase.AbstractSourceType An AbstractSource is something used as source to build the package. Sources are installed to ${WORKSPACE}/srcdir in the build environment.

Concrete subtypes of AbstractSource are:

source
BinaryBuilderBase.ArchiveSourceType
ArchiveSource(url::String, hash::String; unpack_target::String = "")

Specify a remote archive in one of the supported archive formats (e.g., TAR or ZIP balls) to be downloaded from the Internet from url. hash is the 64-character SHA256 checksum of the file.

In the builder environment, the archive will be automatically unpacked to ${WORKSPACE}/srcdir, or in its subdirectory pointed to by the optional keyword unpack_target, if provided. source BinaryBuilderBase.BuildDependencyType BuildDependency(dep::Union{PackageSpec,String}) Define a binary dependency that is necessary only to build the package. The argument can be either a string with the name of the JLL package or a Pkg.PackageSpec. source BinaryBuilderBase.DependencyType Dependency(dep::Union{PackageSpec,String}) Define a binary dependency that is necessary to build the package and load the generated JLL package. The argument can be either a string with the name of the JLL package or a Pkg.PackageSpec. source BinaryBuilderBase.DirectorySourceType DirectorySource(path::String; target::String = basename(path), follow_symlinks=false) Specify a local directory to mount from path. The content of the directory will be mounted in ${WORKSPACE}/srcdir, or in its subdirectory pointed to by the optional keyword target, if provided. Symbolic links are replaced by a copy of the target when follow_symlinks is true.

source
BinaryBuilderBase.ExecutableProductType

An ExecutableProduct is a Product that represents an executable file.

On all platforms, an ExecutableProduct checks for existence of the file. On non-Windows platforms, it will check for the executable bit being set. On Windows platforms, it will check that the file ends with ".exe", (adding it on automatically, if it is not already present).

ExecutableProduct(binname, varname::Symbol, dir_path="bin")

Declares an ExecutableProduct that points to an executable located within the prefix. binname specifies the basename of the executable, varname is the name of the variable in the JLL package that can be used to call into the library. By default, the library is searched in the bindir, but you can specify a different directory within the prefix with the dir_path argument.

source
BinaryBuilderBase.FileSourceType
FileSource(url::String, hash::String; filename::String = basename(url))

Specify a remote file to be downloaded from the Internet from url. hash is the 64-character SHA256 checksum of the file.

In the builder environment, the file will be saved under ${WORKSPACE}/srcdir with the same name as the basename of the originating URL, unless the the keyword argument filename is specified. source BinaryBuilderBase.FrameworkProductType A FrameworkProduct is a Product that encapsulates a macOS Framework. It behaves mostly as a LibraryProduct for now, but is a distinct type. This implies that for cross-platform builds where a library is provided as a Framework on macOS and as a normal library on other platforms, two calls to BinaryBuilder's build_tarballs are needed: one with the LibraryProduct and all non-macOS platforms, and one with the FrameworkProduct and the MacOS platforms. FrameworkProduct(fwnames, varname::Symbol) Declares a macOS FrameworkProduct that points to a framework located within the prefix, with a name containing fwname appended with .framework. As an example, given that fwname is equal to QtCore, this would be satisfied by the following path: lib/QtCore.framework source BinaryBuilderBase.GitSourceType GitSource(url::String, hash::String; unpack_target::String = "") Specify a remote Git repository to clone form url. hash is the 40-character SHA1 revision to checkout after cloning. The repository will be cloned in ${WORKSPACE}/srcdir, or in its subdirectory pointed to by the optional keyword unpack_target, if provided.

source
BinaryBuilderBase.HostBuildDependencyType
HostBuildDependency(dep::Union{PackageSpec,String})

Define a binary dependency that is necessary only to build the package. Different from the BuildDependency, the artifact for the host platform will be installed, instead of that for the target platform.

The argument can be either a string with the name of the JLL package or a Pkg.PackageSpec.

source
BinaryBuilderBase.LibraryProductType

A LibraryProduct is a special kind of Product that not only needs to exist, but needs to be dlopen()'able. You must know which directory the library will be installed to, and its name, e.g. to build a LibraryProduct that refers to "/lib/libnettle.so", the "directory" would be "/lib", and the "libname" would be "libnettle". Note that a LibraryProduct can support multiple libnames, as some software projects change the libname based on the build configuration.

LibraryProduct(libname, varname::Symbol; dir_paths=String[],
dont_dlopen=false,
dlopen_flags=Symbol[])

Declares a LibraryProduct that points to a library located within the prefix. libname specifies the basename of the library, varname is the name of the variable in the JLL package that can be used to call into the library. By default, the library is searched in the libdir, but you can add other directories within the prefix to the dir_paths keyword argument. You can specify the flags to pass to dlopen as a vector of Symbols with the dlopen_flags keyword argument. If the library should not be dlopen'ed automatically by the JLL package, set dont_dlopen=true.

For example, if the libname is libnettle, this would be satisfied by the following paths:

• lib/libnettle.so or lib/libnettle.so.6 on Linux and FreeBSD;
• lib/libnettle.6.dylib on macOS;
• lib/libnettle-6.dll on Windows.

Libraries matching the search pattern are rejected if they are not dlopen()'able.

If you are unsure what value to use for libname, you can use Base.BinaryPlatforms.parse_dl_name_version:

julia> using Base.BinaryPlatforms

julia> parse_dl_name_version("sfml-audio-2.dll", "windows")[1]
"sfml-audio"

If the library would have different basenames on different operating systems (e.g., libz.so on Linux and FreeBSD, libz.dylib on macOS, and zlib.dll on Windows), libname can be also a vector of Strings with the different alternatives:

LibraryProduct(["libz", "zlib"], :libz)
source
BinaryBuilderBase.ProductType

A Product is an expected result after building or installation of a package.

Examples of Products include LibraryProduct, FrameworkProduct, ExecutableProduct and FileProduct. All Product types must define the following minimum set of functionality:

• locate(::Product): given a Product, locate it within the wrapped Prefix returning its location as a string

• satisfied(::Product): given a Product, determine whether it has been successfully satisfied (e.g. it is locateable and it passes all callbacks)

• variable_name(::Product): return the variable name assigned to a Product

• repr(::Product): Return a representation of this Product, useful for auto-generating source code that constructs Products, if that's your thing.

source
BinaryBuilderBase.UserNSRunnerType
UserNSRunner

A UserNSRunner represents an "execution context", an object that bundles all necessary information to run commands within the container that contains our crossbuild environment. Use run() to actually run commands within the UserNSRunner, and runshell() as a quick way to get an interactive shell within the crossbuild environment.

source

## Functions

BinaryBuilderBase.choose_shardsMethod
choose_shards(p::AbstractPlatform; rootfs_build, ps_build, GCC_builds,
LLVM_builds, archive_type)

This method chooses, given a Platform, which shards to download, extract and mount, returning a list of CompilerShard objects. At the moment, this always consists of four shards, but that may not always be the case.

source
BinaryBuilderBase.compress_dirMethod
compress_dir(dir::AbstractString;
compressor_stream = GzipCompressorStream,
level::Int = 9,
extension::AbstractString = ".gz",
verbose::Bool = false)

Compress all files in dir using the specified compressor_stream with compression level equal to level, appending extension to the filenames. Remove the original uncompressed files at the end.

source
BinaryBuilderBase.download_sourceFunction
download_source(source::AbstractSource; verbose::Bool = false)

Download the given source. All downloads are cached within the BinaryBuilder downloads storage directory.

source
BinaryBuilderBase.expand_cxxstring_abisMethod
expand_cxxstring_abis(p::AbstractPlatform; skip=Sys.isbsd)

Given a Platform, returns an array of Platforms with a spread of identical entries with the exception of the cxxstring_abi tag within the Platform object. This is used to take, for example, a list of supported platforms and expand them to include multiple GCC versions for the purposes of ABI matching.

If the given Platform already specifies a cxxstring_abi (as opposed to nothing) only that Platform is returned. If skip is a function for which skip(platform) evaluates to true, the given platform is not expanded. By default FreeBSD and macOS platforms are skipped, due to their lack of a dependence on libstdc++ and not needing this compatibility shim.

source
BinaryBuilderBase.expand_gfortran_versionsMethod
expand_gfortran_versions(p::AbstractPlatform)

Given a Platform, returns an array of Platforms with a spread of identical entries with the exception of the libgfortran_version tag within the Platform. This is used to take, for example, a list of supported platforms and expand them to include multiple GCC versions for the purposes of ABI matching. If the given Platform already specifies a libgfortran_version (as opposed to nothing) only that Platform is returned.

source
BinaryBuilderBase.expand_microarchitecturesMethod
expand_microarchitectures(p::AbstractPlatform)

Given a Platform, returns a vector of Platforms with differing march attributes as specified by the ARCHITECTURE_FLAGS mapping. If the given Platform alread has a march tag specified, only that platform is returned.

julia> using BinaryBuilderBase

julia> expand_microarchitectures(Platform("x86_64", "freebsd"))
4-element Vector{Platform}:
FreeBSD x86_64 {march=x86_64}
FreeBSD x86_64 {march=avx}
FreeBSD x86_64 {march=avx2}
FreeBSD x86_64 {march=avx512}

julia> expand_microarchitectures(Platform("armv7l", "linux"))
2-element Vector{Platform}:
Linux armv7l {call_abi=eabihf, libc=glibc, march=armv7l}
Linux armv7l {call_abi=eabihf, libc=glibc, march=neonvfpv4}

julia> expand_microarchitectures(Platform("aarch64", "linux"))
4-element Vector{Platform}:
Linux aarch64 {libc=glibc, march=armv8_0}
Linux aarch64 {libc=glibc, march=armv8_4_crypto_sve}
Linux aarch64 {libc=glibc, march=armv8_2_crypto}
Linux aarch64 {libc=glibc, march=armv8_1}

julia> expand_microarchitectures(Platform("i686", "windows"))
2-element Vector{Platform}:
Windows i686 {march=pentium4}
Windows i686 {march=prescott}
source
BinaryBuilderBase.expand_microarchitecturesMethod
expand_microarchitectures(ps::Vector{<:Platform})

Expand all platforms in the given vector with the supported microarchitectures.

julia> using BinaryBuilderBase

julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glibc", supported_platforms()))
13-element Vector{Platform}:
Linux i686 {libc=glibc, march=pentium4}
Linux i686 {libc=glibc, march=prescott}
Linux x86_64 {libc=glibc, march=x86_64}
Linux x86_64 {libc=glibc, march=avx}
Linux x86_64 {libc=glibc, march=avx2}
Linux x86_64 {libc=glibc, march=avx512}
Linux aarch64 {libc=glibc, march=armv8_0}
Linux aarch64 {libc=glibc, march=armv8_4_crypto_sve}
Linux aarch64 {libc=glibc, march=armv8_2_crypto}
Linux aarch64 {libc=glibc, march=armv8_1}
Linux armv7l {call_abi=eabihf, libc=glibc, march=armv7l}
Linux armv7l {call_abi=eabihf, libc=glibc, march=neonvfpv4}
Linux powerpc64le {libc=glibc, march=power8}
source
BinaryBuilderBase.gcc_versionMethod
gcc_version(p::AbstractPlatform, , GCC_builds::Vector{GCCBuild})

Returns the closest matching GCC version number for the given particular platform, from the given set of options. The compiler ABI and the microarchitecture of the platform will be taken into account. If no match is found, returns an empty list.

This method assumes that the compiler ABI of the platform represents a platform that binaries will be run on, and thus versions are always rounded down; e.g. if the platform supports a libstdc++ version that corresponds to GCC 5.1.0, but the only GCC versions available to be picked from are 4.8.5 and 5.2.0, it will return 4.8.5, as binaries compiled with that version will run on this platform, whereas binaries compiled with 5.2.0 may not.

source
BinaryBuilderBase.generate_compiler_wrappers!Method
generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::AbstractString,
host_platform::AbstractPlatform = Platform("x86_64", "linux"; libc = "musl", cxxstring_abi = "cxx11"),
compilers::Vector{Symbol} = [:c],
allow_unsafe_flags::Bool = false,
lock_microarchitecture::Bool = true)

We generate a set of compiler wrapper scripts within our build environment to force all build systems to honor the necessary sets of compiler flags to build for our systems. Note that while platform_envs() sets many environment variables, those values are intended to be optional/overridable. These values, while still overridable by directly invoking a compiler binary directly (e.g. /opt/{target}/bin/{target}-gcc), are much more difficult to override, as the flags embedded in these wrappers are absolutely necessary, and even simple programs will not compile without them.

source
BinaryBuilderBase.libdirsFunction
libdirs(prefix::Prefix, platform = HostPlatform())

Returns the library directories for the given prefix (note that this differs between unix systems and windows systems, and between 32- and 64-bit systems).

source
BinaryBuilderBase.locateMethod
locate(ep::ExecutableProduct, prefix::Prefix;
platform::AbstractPlatform = HostPlatform(),
verbose::Bool = false,
isolate::Bool = false)

If the given executable file exists and is executable, return its path.

On all platforms, an ExecutableProduct checks for existence of the file. On non-Windows platforms, it will check for the executable bit being set. On Windows platforms, it will check that the file ends with ".exe", (adding it on automatically, if it is not already present).

source
BinaryBuilderBase.locateMethod
locate(fp::FileProduct, prefix::Prefix;
platform::AbstractPlatform = HostPlatform(),
verbose::Bool = false,
isolate::Bool = false)

If the given file exists, return its path. The platform and isolate arguments are is ignored here, but included for uniformity. For ease of use, we support a limited number of custom variable expansions such as ${target}, and ${nbits}, so that the detection of files within target-specific folders named things like /lib32/i686-linux-musl is simpler.

source
BinaryBuilderBase.locateMethod
locate(lp::LibraryProduct, prefix::Prefix;
verbose::Bool = false,
platform::AbstractPlatform = HostPlatform())

If the given library exists (under any reasonable name) and is dlopen()able, (assuming it was built for the current platform) return its location. Note that the dlopen() test is only run if the current platform matches the given platform keyword argument, as cross-compiled libraries cannot be dlopen()ed on foreign platforms.

source
BinaryBuilderBase.packageMethod
package(prefix::Prefix, output_base::AbstractString,
version::VersionNumber;
platform::AbstractPlatform = HostPlatform(),
verbose::Bool = false, force::Bool = false)

Build a tarball of the prefix, storing the tarball at output_base, appending a version number, a platform-dependent suffix and a file extension. If no platform is given, defaults to current platform. Returns the full path to, the SHA256 hash and the git tree SHA1 of the generated tarball.

source
BinaryBuilderBase.preferred_cxxstring_abiMethod
preferred_cxxstring_abi(platform::AbstractPlatform, shard::CompilerShard;
gcc_builds::Vector{GCCBuild} = available_gcc_builds)

Return the C++ string ABI preferred by the given platform or GCCBootstrap shard.

source
BinaryBuilderBase.satisfiedMethod
satisfied(p::Product;
platform::AbstractPlatform = HostPlatform(),
verbose::Bool = false,
isolate::Bool = false)

Given a Product, return true if that Product is satisfied, e.g. whether a file exists that matches all criteria setup for that Product. If isolate is set to true, will isolate all checks from the main Julia process in the event that dlopen()'ing a library might cause issues.

source
BinaryBuilderBase.setup_dependenciesMethod
setup_dependencies(prefix::Prefix, dependencies::Vector{PackageSpec}, platform::AbstractPlatform; verbose::Bool = false)

Given a list of JLL package specifiers, install their artifacts into the build prefix. The artifacts are installed into the global artifact store, then copied into a temporary location, then finally symlinked into the build prefix. This allows us to (a) save download bandwidth by not downloading the same artifacts over and over again, (b) maintain separation in the event of catastrophic containment failure, avoiding hosing the main system if a build script decides to try to modify the dependent artifact files, and (c) keeping a record of what files are a part of dependencies as opposed to the package being built, in the form of symlinks to a specific artifacts directory.

source
BinaryBuilderBase.setup_workspaceFunction
setup_workspace(build_path::String, sources::Vector{SetupSource};
verbose::Bool = false)

Sets up a workspace within build_path, creating the directory structure needed by further steps, unpacking the source within build_path, and defining the environment variables that will be defined within the sandbox environment.

This method returns the Prefix to install things into, and the runner that can be used to launch commands within this workspace.

source
BinaryBuilderBase.supported_platformsMethod
supported_platforms(;exclude::Union{Vector{<:Platform},Function}=x->false)

Return the list of supported platforms as an array of Platforms. These are the platforms we officially support building for, if you see a mapping in get_shard_hash() that isn't represented here, it's probably because that platform is still considered "in beta".

Platforms can be excluded from the list by specifying an array of platforms to exclude i.e. supported_platforms(exclude=[Platform("i686", "windows"), Platform("x86_64", "windows")]) or a function that returns true for exclusions i.e.

supported_platforms(exclude=Sys.islinux)
source
BinaryBuilderBase.temp_prefixMethod
temp_prefix(func::Function)

Create a temporary prefix, passing the prefix into the user-defined function so that build/packaging operations can occur within the temporary prefix, which is then cleaned up after all operations are finished. If the path provided exists already, it will be deleted.

Usage example:

out_path = abspath("./libfoo")
temp_prefix() do p
# <insert build steps here>

# tarball up the built package
tarball_path, tarball_hash = package(p, out_path)
end
source
BinaryBuilderBase.accept_apple_sdkMethod
accept_apple_sdk(ins::IO, outs::IO) -> Bool

Ask the user whether they accept the terms of the macOS SDK, and return a boolean with their choice. Write messages to outs, read input from ins.

source
BinaryBuilderBase.chown_cleanupMethod
chown_cleanup(dr::DockerRunner)

On Linux, the user id inside of the docker container doesn't correspond to ours on the outside, so permissions get all kinds of screwed up. To fix this, we have to chown -R $(id -u):$(id -g) \$prefix, which really sucks, but is still better than nothing. This is why we prefer the UserNSRunner on Linux.

source
BinaryBuilderBase.collect_jllsMethod
collect_jlls(manifest::Dict, dependencies::Vector{<:AbstractString})

Return a Set of all JLL packages in the manifest with dependencies being the list of direct dependencies of the environment.

source
BinaryBuilderBase.download_all_artifactsMethod
download_all_artifacts(; verbose::Bool=false)

Helper function to download all shards/helper binaries so that no matter what happens, you don't need an internet connection to build your precious, precious binaries.

source
BinaryBuilderBase.enable_apple_fileMethod
enable_apple_file()

Return the path to file that, if exists, indicates that the user accepts to download macOS SDK. The file is automatically created when the package is loaded if the environment variable BINARYBUILDER_AUTOMATIC_APPLE is set to "true".

source
BinaryBuilderBase.generate_per_uid_squashfsFunction
generate_per_uid_squashfs(cs, new_uid = getuid())

In order for the sandbox to work well, we need to have the uids of the squashfs images match the uid of the current unprivileged user. Unfortunately there is no mount-time option to do this for us. Fortunately, squashfs is simple enough that if the ID table is uncompressed, we can just manually patch the uids to be what we need. This function performs this operation, by rewriting all UIDs and GIDs to the given new_uid (which defaults to the current user's UID).

source
BinaryBuilderBase.import_docker_imageMethod
import_docker_image(rootfs::CompilerShard; verbose::Bool = false)

Checks to see if the given rootfs has been imported into docker yet; if it hasn't, then do so so that we can run things like:

docker run -ti binarybuilder_rootfs:v2018.08.27 /bin/bash

Which, after all, is the foundation upon which this whole doodad is built.

source
BinaryBuilderBase.is_ecryptfsMethod
is_ecryptfs(path::AbstractString; verbose::Bool=false)

Checks to see if the given path (or any parent directory) is placed upon an ecryptfs mount. This is known not to work on current kernels, see this bug for more details: https://bugzilla.kernel.org/show_bug.cgi?id=197603

This method returns whether it is encrypted or not, and what mountpoint it used to make that decision.

source
BinaryBuilderBase.is_mountedMethod
is_mounted(cs::CompilerShard, build_prefix::String)

Return true if the given shard is mounted. Uses run() so will error out if something goes awry.

source
BinaryBuilderBase.map_targetMethod
map_target(cs::CompilerShard)

Return the location this compiler shard should be mounted at. We basically analyze the name and platform of this shard and return a path based on that.

source
BinaryBuilderBase.mountMethod
mount(cs::CompilerShard, build_prefix::String)

Mount a compiler shard, if possible. Uses run() so will error out if something goes awry. Note that this function only does something when using a .squashfs shard, with a UserNS or Docker runner, on Linux. All other combinations of shard archive type, runner and platform result in a no-op from this function.

source
BinaryBuilderBase.platform_envsMethod
platform_envs(platform::AbstractPlatform)

Given a platform, generate a Dict mapping representing all the environment variables to be set within the build environment to force compiles toward the defined target architecture. Examples of things set are PATH, CC, RANLIB, as well as nonstandard things like target.

source
BinaryBuilderBase.runshellFunction
runshell(platform::AbstractPlatform = HostPlatform())

Launch an interactive shell session within the user namespace, with environment setup to target the given platform.

source
BinaryBuilderBase.shard_pathMethod
shard_path(cs::CompilerShard)

Return the path to this shard on-disk; for unpacked shards, this is a directory. For squashfs shards, this is a file. This will not cause a shard to be downloaded.

source
BinaryBuilderBase.unmountMethod
unmount(cs::CompilerShard, build_prefix::String)

Unmount a compiler shard from a given build prefix, if possible. Uses run() so will error out if something goes awry. Note that this function only does something when using a squashfs shard on Linux. All other combinations of shard archive type and platform result in a no-op.

source