ci: generate debug symbols on Linux (#18676)

This commit is contained in:
Julien Isorce 2019-11-20 17:21:44 -08:00 committed by Jeremy Apthorp
parent 41f1569c46
commit 92ff39c168
9 changed files with 192 additions and 17 deletions

View file

@ -349,9 +349,18 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run: run:
name: Strip electron binaries name: Strip electron binaries
command: | command: |
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" != "Darwin" ]; then if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
cd src cd src
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" electron/script/copy-debug-symbols.py --target-cpu="$target_cpu" --out-dir=out/Default/debug --compress
electron/script/strip-binaries.py --target-cpu="$target_cpu"
electron/script/add-debug-link.py --target-cpu="$target_cpu" --debug-dir=out/Default/debug
fi fi
step-electron-dist-build: &step-electron-dist-build step-electron-dist-build: &step-electron-dist-build

66
script/add-debug-link.py Executable file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
from __future__ import print_function
import argparse
import os
import sys
from lib.config import LINUX_BINARIES, PLATFORM
from lib.util import execute, get_objcopy_path, get_out_dir
def add_debug_link_into_binaries(directory, target_cpu, debug_dir):
for binary in LINUX_BINARIES:
binary_path = os.path.join(directory, binary)
if os.path.isfile(binary_path):
add_debug_link_into_binary(binary_path, target_cpu, debug_dir)
def add_debug_link_into_binary(binary_path, target_cpu, debug_dir):
try:
objcopy = get_objcopy_path(target_cpu)
except:
if PLATFORM == 'linux' and (target_cpu == 'x86' or target_cpu == 'arm' or
target_cpu == 'arm64'):
# Skip because no objcopy binary on the given target.
return
raise
debug_name = get_debug_name(binary_path)
# Make sure the path to the binary is not relative because of cwd param.
real_binary_path = os.path.realpath(binary_path)
cmd = [objcopy, '--add-gnu-debuglink=' + debug_name, real_binary_path]
execute(cmd, cwd=debug_dir)
def get_debug_name(binary_path):
return os.path.basename(binary_path) + '.debug'
def main():
args = parse_args()
if args.file:
add_debug_link_into_binary(args.file, args.target_cpu, args.debug_dir)
else:
add_debug_link_into_binaries(args.directory, args.target_cpu,
args.debug_dir)
def parse_args():
parser = argparse.ArgumentParser(description='Add debug link to binaries')
parser.add_argument('-d', '--directory',
help='Path to the dir that contains files to add links',
default=get_out_dir(),
required=False)
parser.add_argument('-f', '--file',
help='Path to a specific file to add debug link',
required=False)
parser.add_argument('-s', '--debug-dir',
help='Path to the dir that contain the debugs',
default=None,
required=True)
parser.add_argument('-v', '--verbose',
action='store_true',
help='Prints the output of the subprocesses')
parser.add_argument('--target-cpu',
default='',
required=False,
help='Target cpu of binaries to add debug link')
return parser.parse_args()
if __name__ == '__main__':
sys.exit(main())

75
script/copy-debug-symbols.py Executable file
View file

@ -0,0 +1,75 @@
#!/usr/bin/env python
from __future__ import print_function
import argparse
import os
import sys
from lib.config import LINUX_BINARIES, PLATFORM
from lib.util import execute, get_objcopy_path, get_out_dir, safe_mkdir
# It has to be done before stripping the binaries.
def copy_debug_from_binaries(directory, out_dir, target_cpu, compress):
for binary in LINUX_BINARIES:
binary_path = os.path.join(directory, binary)
if os.path.isfile(binary_path):
copy_debug_from_binary(binary_path, out_dir, target_cpu, compress)
def copy_debug_from_binary(binary_path, out_dir, target_cpu, compress):
try:
objcopy = get_objcopy_path(target_cpu)
except:
if PLATFORM == 'linux' and (target_cpu == 'x86' or target_cpu == 'arm' or
target_cpu == 'arm64'):
# Skip because no objcopy binary on the given target.
return
raise
debug_name = get_debug_name(binary_path)
cmd = [objcopy, '--only-keep-debug']
if compress:
cmd.extend(['--compress-debug-sections'])
cmd.extend([binary_path, os.path.join(out_dir, debug_name)])
execute(cmd)
return debug_name
def get_debug_name(binary_path):
return os.path.basename(binary_path) + '.debug'
def main():
args = parse_args()
safe_mkdir(args.out_dir)
if args.file:
copy_debug_from_binary(args.file, args.out_dir, args.target_cpu,
args.compress)
else:
copy_debug_from_binaries(args.directory, args.out_dir, args.target_cpu,
args.compress)
def parse_args():
parser = argparse.ArgumentParser(description='Copy debug from binaries')
parser.add_argument('-d', '--directory',
help='Path to the dir that contains files to copy',
default=get_out_dir(),
required=False)
parser.add_argument('-f', '--file',
help='Path to a specific file to copy debug symbols',
required=False)
parser.add_argument('-o', '--out-dir',
help='Path to the dir that will contain the debugs',
default=None,
required=True)
parser.add_argument('-v', '--verbose',
action='store_true',
help='Prints the output of the subprocesses')
parser.add_argument('--target-cpu',
default='',
required=False,
help='Target cpu of binaries to copy debug symbols')
parser.add_argument('--compress',
action='store_true',
required=False,
help='Compress the debug symbols')
return parser.parse_args()
if __name__ == '__main__':
sys.exit(main())

View file

@ -26,6 +26,18 @@ PLATFORM = {
'win32': 'win32', 'win32': 'win32',
}[sys.platform] }[sys.platform]
LINUX_BINARIES = [
'electron',
'chrome-sandbox',
'crashpad_handler',
'libffmpeg.so',
'libGLESv2.so',
'libEGL.so',
'swiftshader/libGLESv2.so',
'swiftshader/libEGL.so',
'libvk_swiftshader.so'
]
verbose_mode = False verbose_mode = False

View file

@ -123,7 +123,8 @@ def make_zip(zip_file_path, files, dirs):
files += dirs files += dirs
execute(['zip', '-r', '-y', zip_file_path] + files) execute(['zip', '-r', '-y', zip_file_path] + files)
else: else:
zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED) zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED,
allowZip64=True)
for filename in files: for filename in files:
zip_file.write(filename, filename) zip_file.write(filename, filename)
for dirname in dirs: for dirname in dirs:
@ -266,3 +267,14 @@ def get_buildtools_executable(name):
if sys.platform == 'win32': if sys.platform == 'win32':
path += '.exe' path += '.exe'
return path return path
def get_objcopy_path(target_cpu):
if PLATFORM != 'linux':
raise Exception(
"get_objcopy_path: unexpected platform '{0}'".format(PLATFORM))
if target_cpu != 'x64':
raise Exception(
"get_objcopy_path: unexpected target cpu '{0}'".format(target_cpu))
return os.path.join(SRC_DIR, 'third_party', 'binutils', 'Linux_x64',
'Release', 'bin', 'objcopy')

View file

@ -114,6 +114,7 @@ function assetsForVersion (version, validatingRelease) {
`electron-${version}-linux-armv7l.zip`, `electron-${version}-linux-armv7l.zip`,
`electron-${version}-linux-ia32-symbols.zip`, `electron-${version}-linux-ia32-symbols.zip`,
`electron-${version}-linux-ia32.zip`, `electron-${version}-linux-ia32.zip`,
`electron-${version}-linux-x64-debug.zip`,
`electron-${version}-linux-x64-symbols.zip`, `electron-${version}-linux-x64-symbols.zip`,
`electron-${version}-linux-x64.zip`, `electron-${version}-linux-x64.zip`,
`electron-${version}-mas-x64-dsym.zip`, `electron-${version}-mas-x64-dsym.zip`,

View file

@ -35,6 +35,7 @@ DIST_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION)
SYMBOLS_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'symbols') SYMBOLS_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'symbols')
DSYM_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'dsym') DSYM_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'dsym')
PDB_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'pdb') PDB_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'pdb')
DEBUG_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'debug')
def main(): def main():
@ -83,6 +84,10 @@ def main():
pdb_zip = os.path.join(OUT_DIR, PDB_NAME) pdb_zip = os.path.join(OUT_DIR, PDB_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip) shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip)
upload_electron(release, pdb_zip, args) upload_electron(release, pdb_zip, args)
elif PLATFORM == 'linux':
debug_zip = os.path.join(OUT_DIR, DEBUG_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'debug.zip'), debug_zip)
upload_electron(release, debug_zip, args)
# Upload free version of ffmpeg. # Upload free version of ffmpeg.
ffmpeg = get_zip_name('ffmpeg', ELECTRON_VERSION) ffmpeg = get_zip_name('ffmpeg', ELECTRON_VERSION)

View file

@ -4,22 +4,11 @@ import argparse
import os import os
import sys import sys
from lib.config import LINUX_BINARIES
from lib.util import execute, get_out_dir from lib.util import execute, get_out_dir
LINUX_BINARIES_TO_STRIP = [
'electron',
'chrome-sandbox',
'crashpad_handler',
'libffmpeg.so',
'libGLESv2.so',
'libEGL.so',
'swiftshader/libGLESv2.so',
'swiftshader/libEGL.so',
'libvk_swiftshader.so'
]
def strip_binaries(directory, target_cpu): def strip_binaries(directory, target_cpu):
for binary in LINUX_BINARIES_TO_STRIP: for binary in LINUX_BINARIES:
binary_path = os.path.join(directory, binary) binary_path = os.path.join(directory, binary)
if os.path.isfile(binary_path): if os.path.isfile(binary_path):
strip_binary(binary_path, target_cpu) strip_binary(binary_path, target_cpu)
@ -37,7 +26,6 @@ def strip_binary(binary_path, target_cpu):
def main(): def main():
args = parse_args() args = parse_args()
print(args)
if args.file: if args.file:
strip_binary(args.file, args.target_cpu) strip_binary(args.file, args.target_cpu)
else: else:

View file

@ -43,6 +43,13 @@ def main():
pdb_zip_file = os.path.join(args.build_dir, pdb_name) pdb_zip_file = os.path.join(args.build_dir, pdb_name)
print('Making pdb zip: ' + pdb_zip_file) print('Making pdb zip: ' + pdb_zip_file)
make_zip(pdb_zip_file, pdbs + licenses, []) make_zip(pdb_zip_file, pdbs + licenses, [])
elif PLATFORM == 'linux':
debug_name = 'debug.zip'
with scoped_cwd(args.build_dir):
dirs = ['debug']
debug_zip_file = os.path.join(args.build_dir, debug_name)
print('Making debug zip: ' + debug_zip_file)
make_zip(debug_zip_file, licenses, dirs)
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='Zip symbols') parser = argparse.ArgumentParser(description='Zip symbols')