diff --git a/.circleci/config.yml b/.circleci/config.yml index 212ad2dba0..8258144b61 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -349,9 +349,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 diff --git a/script/add-debug-link.py b/script/add-debug-link.py new file mode 100755 index 0000000000..72b1d9a3b6 --- /dev/null +++ b/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()) diff --git a/script/copy-debug-symbols.py b/script/copy-debug-symbols.py new file mode 100755 index 0000000000..51d3f7498d --- /dev/null +++ b/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()) diff --git a/script/lib/config.py b/script/lib/config.py index f5b0356f80..9985183c98 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -26,6 +26,18 @@ PLATFORM = { '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 diff --git a/script/lib/util.py b/script/lib/util.py index 6de00f68a6..29bd64af47 100644 --- a/script/lib/util.py +++ b/script/lib/util.py @@ -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: @@ -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') diff --git a/script/release/release.js b/script/release/release.js index f9e102ab96..d41b721e28 100755 --- a/script/release/release.js +++ b/script/release/release.js @@ -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`, diff --git a/script/release/uploaders/upload.py b/script/release/uploaders/upload.py index 15f303db5f..23902f0b15 100755 --- a/script/release/uploaders/upload.py +++ b/script/release/uploaders/upload.py @@ -35,6 +35,7 @@ DIST_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION) 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(): @@ -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) diff --git a/script/strip-binaries.py b/script/strip-binaries.py index d457f476be..cd9344f349 100755 --- a/script/strip-binaries.py +++ b/script/strip-binaries.py @@ -4,22 +4,11 @@ import argparse 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) @@ -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: diff --git a/script/zip-symbols.py b/script/zip-symbols.py index 1407f195a4..a97c6f5ff0 100755 --- a/script/zip-symbols.py +++ b/script/zip-symbols.py @@ -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')