ci: Produce static release executables on Linux (#978)

We never produced static release executables on Linux before, but the dynamic libraries they depended on were universal enough that nobody noticed. Now that we have released v2.5 and switched to GitHub Actions for CI builds, the Linux executables depend on libatomic, which is causing issues for some users.

Although we can't create fully-static executables on macOS or Windows, we can at least do so on Linux.

This adds a GYP variable static_link_binaries which can be set to request full-static binaries on Linux. This also exposes the Chromium build variable disable_fatal_linker_warnings, which is necessary when static linking on Linux due to static-link-related warnings generated by libcurl for its use of getaddrinfo. Finally, this enforces the definition of __UCLIBC__ with static linking on Linux, which is the only way to disable malloc hooks in Chromium base. Those hooks cause linker failures when linking statically on Linux.

A new check has been added to the release workflow to ensure that the builds we create are statically linked on Linux.

Closes #965
This commit is contained in:
Joey Parrish 2021-08-12 20:14:43 -07:00 committed by GitHub
parent 507a731a9a
commit b411af7ed9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 4 deletions

View File

@ -63,6 +63,11 @@ runs:
shell: bash shell: bash
run: | run: |
echo "::group::Sync gclient" echo "::group::Sync gclient"
BUILD_CONFIG="${{ inputs.build_type }}-${{ inputs.lib_type }}"
if [[ "$BUILD_CONFIG" == "Release-static" && "${{ runner.os }}" == "Linux" ]]; then
# For static release builds, set these two additional flags for fully static binaries.
export GYP_DEFINES="$GYP_DEFINES disable_fatal_linker_warnings=1 static_link_binaries=1"
fi
gclient sync gclient sync
echo "::endgroup::" echo "::endgroup::"
@ -81,11 +86,32 @@ runs:
echo "Skipping artifacts for $BUILD_CONFIG." echo "Skipping artifacts for $BUILD_CONFIG."
exit 0 exit 0
fi fi
if [[ "${{ runner.os }}" == "Linux" ]]; then
echo "::group::Check for static executables"
(
cd src/out/Release${{ inputs.build_type_suffix }}
# Prove that we built static executables on Linux. First, check that
# the executables exist, and fail if they do not. Then check "ldd",
# which will fail if the executable is not dynamically linked. If
# "ldd" succeeds, we fail the workflow. Finally, we call "true" so
# that the last executed statement will be a success, and the step
# won't be failed if we get that far.
ls packager mpd_generator >/dev/null || exit 1
ldd packager 2>&1 && exit 1
ldd mpd_generator 2>&1 && exit 1
true
)
echo "::endgroup::"
fi
echo "::group::Prepare artifacts folder" echo "::group::Prepare artifacts folder"
mkdir artifacts mkdir artifacts
ARTIFACTS="$GITHUB_WORKSPACE/artifacts" ARTIFACTS="$GITHUB_WORKSPACE/artifacts"
cd src/out/Release${{ inputs.build_type_suffix }} cd src/out/Release${{ inputs.build_type_suffix }}
echo "::endgroup::" echo "::endgroup::"
echo "::group::Strip executables"
strip packager${{ inputs.exe_ext }}
strip mpd_generator${{ inputs.exe_ext }}
echo "::endgroup::"
echo "::group::Copy packager" echo "::group::Copy packager"
cp packager${{ inputs.exe_ext }} \ cp packager${{ inputs.exe_ext }} \
$ARTIFACTS/packager-${{ inputs.os_name }}${{ inputs.exe_ext }} $ARTIFACTS/packager-${{ inputs.os_name }}${{ inputs.exe_ext }}

View File

@ -12,12 +12,18 @@
'shaka_code%': 0, 'shaka_code%': 0,
# musl is a lightweight C standard library used in Alpine Linux. # musl is a lightweight C standard library used in Alpine Linux.
'musl%': 0, 'musl%': 0,
# This is a flag from build/common.gypi to allow linker warnings.
# This may be necessary with static_link_binaries=1.
'disable_fatal_linker_warnings%': '0',
'libpackager_type%': 'static_library', 'libpackager_type%': 'static_library',
'static_link_binaries%': '0',
}, },
'shaka_code%': '<(shaka_code)', 'shaka_code%': '<(shaka_code)',
'musl%': '<(musl)', 'musl%': '<(musl)',
'disable_fatal_linker_warnings%': '<(disable_fatal_linker_warnings)',
'libpackager_type%': '<(libpackager_type)', 'libpackager_type%': '<(libpackager_type)',
'static_link_binaries%': '<(static_link_binaries)',
'conditions': [ 'conditions': [
['shaka_code==1', { ['shaka_code==1', {
@ -41,11 +47,11 @@
], ],
}, },
'target_defaults': { 'target_defaults': {
# These defines make the contents of base/mac/foundation_util.h compile
# against the standard OSX SDK, by renaming Chrome's opaque type and using
# the real OSX type. This was not necessary before we switched away from
# using hermetic copies of clang and the sysroot to build.
'defines': [ 'defines': [
# These defines make the contents of base/mac/foundation_util.h compile
# against the standard OSX SDK, by renaming Chrome's opaque type and
# using the real OSX type. This was not necessary before we switched
# away from using hermetic copies of clang and the sysroot to build.
'OpaqueSecTrustRef=__SecACL', 'OpaqueSecTrustRef=__SecACL',
'OpaqueSecTrustedApplicationRef=__SecTrustedApplication', 'OpaqueSecTrustedApplicationRef=__SecTrustedApplication',
], ],
@ -122,6 +128,22 @@
'-Werror', '-Werror',
], ],
}], }],
['static_link_binaries==1', {
'conditions': [
['OS=="linux"', {
'defines': [
# Even when we are not using musl or uClibc, pretending to use
# uClibc on Linux is the only way to disable certain Chromium
# base features, such as hooking into malloc. Hooking into
# malloc, in turn, fails when we are linking statically.
'__UCLIBC__',
],
}],
],
'ldflags': [
'-static',
],
}],
], ],
}, },
} }