Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: generate debug symbols on Linux #21278

Merged
merged 2 commits into from Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions .circleci/config.yml
Expand Up @@ -357,9 +357,18 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run:
name: Strip electron binaries
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
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

step-electron-dist-build: &step-electron-dist-build
Expand Down
66 changes: 66 additions & 0 deletions script/add-debug-link.py
@@ -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 changes: 75 additions & 0 deletions script/copy-debug-symbols.py
@@ -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())
12 changes: 12 additions & 0 deletions script/lib/config.py
Expand Up @@ -26,6 +26,18 @@
'win32': 'win32',
}[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


Expand Down
14 changes: 13 additions & 1 deletion script/lib/util.py
Expand Up @@ -123,7 +123,8 @@ def make_zip(zip_file_path, files, dirs):
files += dirs
execute(['zip', '-r', '-y', zip_file_path] + files)
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:
zip_file.write(filename, filename)
for dirname in dirs:
Expand Down Expand Up @@ -266,3 +267,14 @@ def get_buildtools_executable(name):
if sys.platform == 'win32':
path += '.exe'
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')
1 change: 1 addition & 0 deletions script/release/release.js
Expand Up @@ -114,6 +114,7 @@ function assetsForVersion (version, validatingRelease) {
`electron-${version}-linux-armv7l.zip`,
`electron-${version}-linux-ia32-symbols.zip`,
`electron-${version}-linux-ia32.zip`,
`electron-${version}-linux-x64-debug.zip`,
`electron-${version}-linux-x64-symbols.zip`,
`electron-${version}-linux-x64.zip`,
`electron-${version}-mas-x64-dsym.zip`,
Expand Down
5 changes: 5 additions & 0 deletions script/release/uploaders/upload.py
Expand Up @@ -35,6 +35,7 @@
SYMBOLS_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'symbols')
DSYM_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'dsym')
PDB_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'pdb')
DEBUG_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'debug')


def main():
Expand Down Expand Up @@ -83,6 +84,10 @@ def main():
pdb_zip = os.path.join(OUT_DIR, PDB_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip)
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.
ffmpeg = get_zip_name('ffmpeg', ELECTRON_VERSION)
Expand Down
16 changes: 2 additions & 14 deletions script/strip-binaries.py
Expand Up @@ -4,22 +4,11 @@
import os
import sys

from lib.config import LINUX_BINARIES
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):
for binary in LINUX_BINARIES_TO_STRIP:
for binary in LINUX_BINARIES:
binary_path = os.path.join(directory, binary)
if os.path.isfile(binary_path):
strip_binary(binary_path, target_cpu)
Expand All @@ -37,7 +26,6 @@ def strip_binary(binary_path, target_cpu):

def main():
args = parse_args()
print(args)
if args.file:
strip_binary(args.file, args.target_cpu)
else:
Expand Down
7 changes: 7 additions & 0 deletions script/zip-symbols.py
Expand Up @@ -43,6 +43,13 @@ def main():
pdb_zip_file = os.path.join(args.build_dir, pdb_name)
print('Making pdb zip: ' + pdb_zip_file)
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():
parser = argparse.ArgumentParser(description='Zip symbols')
Expand Down