From d03325541ff9b138fa2763065237a25457731759 Mon Sep 17 00:00:00 2001 From: Keeley Hammond Date: Sat, 22 May 2021 11:48:38 -0700 Subject: [PATCH] test: rebuild nan tests with libc++ and libc++abi (#29281) * test: re-enable nan test: typedarrays-test.js Fixes #28414. I've confirmed this fix wfm on Linux. Pushing into a PR to get CI to run it out on Win and Mac platforms too. * chore: clarify comment * test: fix NAN test string alignment * test: (wip) add ldflags, archive file for libc++ * test: (wip) add libc++ to CircleCI * test: (wip) add llvm flags * test: (wip) change ldflag syntax * test: (wip) build libc++abi as static * fix: correct ldflags * test: add ld env * fix: do not commit this * test: add lld from src to circleci * test: add lld link to ld * chore: preserve third_party * seems legit * sam swears this works kinda sort of sometimes' : * build: add gn visibility patch * chore: update patches * build: check for flatten_relative_to = false * build: upload zip files, add to release.js validation * debug: what the hell gn * build: add libcxx gni to lint ignore Linting the file adjusted the licenses array, which only contains one value, and causes the gn check to fail later * build: also use nan-spec-runner flags on Windows * build: add linked flags for win32 only * build: build libc++ as source on win * build: clean up patch, add -fPIC for IA32 * build: delete libcxx .a files from root * build: rename libc++.zip, clean up upload per platform * build: fix gni lint * ci: add libcxx gen to circleci config * build: correct libcxx-object syntax Co-authored-by: Samuel Attard Co-authored-by: Charles Kerr Co-authored-by: clavin Co-authored-by: Samuel Attard Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Samuel Attard --- .circleci/config.yml | 20 ++ BUILD.gn | 44 ++++ build/zip.py | 15 +- build/zip_libcxx.py | 44 ++++ filenames.libcxx.gni | 194 ++++++++++++++++++ filenames.libcxxabi.gni | 6 + patches/chromium/.patches | 1 + .../build_libc_as_static_library.patch | 46 +++++ patches/nan/.patches | 1 + patches/nan/nan_string_test_alignment.patch | 22 ++ script/gen-libc++-filenames.js | 48 +++++ script/nan-spec-runner.js | 42 +++- script/release/release.js | 6 + script/release/uploaders/upload.py | 16 ++ 14 files changed, 497 insertions(+), 8 deletions(-) create mode 100644 build/zip_libcxx.py create mode 100644 filenames.libcxx.gni create mode 100644 filenames.libcxxabi.gni create mode 100644 patches/chromium/build_libc_as_static_library.patch create mode 100644 patches/nan/nan_string_test_alignment.patch create mode 100644 script/gen-libc++-filenames.js diff --git a/.circleci/config.yml b/.circleci/config.yml index af1ce1f79b..86fb72a934 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -499,6 +499,7 @@ step-gn-check: &step-gn-check gn check out/Default //electron/shell/common/api:mojo # Check the hunspell filenames node electron/script/gen-hunspell-filenames.js --check + node electron/script/gen-libc++-filenames.js --check step-electron-build: &step-electron-build run: @@ -662,6 +663,11 @@ step-persist-data-for-tests: &step-persist-data-for-tests - src/third_party/electron_node - src/third_party/nan - src/cross-arch-snapshots + - src/third_party/llvm-build + - src/build/linux + - src/buildtools/third_party/libc++ + - src/buildtools/third_party/libc++abi + - src/out/Default/obj/buildtools/third_party step-electron-dist-unzip: &step-electron-dist-unzip run: @@ -797,6 +803,17 @@ step-hunspell-build: &step-hunspell-build ninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES fi +step-maybe-generate-libcxx: &step-maybe-generate-libcxx + run: + name: maybe generate libcxx + command: | + cd src + if [ "`uname`" == "Linux" ]; then + ninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES + ninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES + ninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES + fi + step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols run: name: Generate breakpad symbols @@ -1620,6 +1637,9 @@ commands: # hunspell - *step-hunspell-build + # libcxx + - *step-maybe-generate-libcxx + # typescript defs - *step-maybe-generate-typescript-defs diff --git a/BUILD.gn b/BUILD.gn index a9e1e77c29..784c7c18bc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -25,6 +25,8 @@ import("electron_paks.gni") import("filenames.auto.gni") import("filenames.gni") import("filenames.hunspell.gni") +import("filenames.libcxx.gni") +import("filenames.libcxxabi.gni") if (is_mac) { import("//build/config/mac/rules.gni") @@ -1293,13 +1295,18 @@ template("dist_zip") { "testonly", ]) flatten = false + flatten_relative_to = false if (defined(invoker.flatten)) { flatten = invoker.flatten + if (defined(invoker.flatten_relative_to)) { + flatten_relative_to = invoker.flatten_relative_to + } } args = rebase_path(outputs + [ _runtime_deps_file ], root_build_dir) + [ target_cpu, target_os, "$flatten", + "$flatten_relative_to", ] } } @@ -1390,6 +1397,43 @@ dist_zip("hunspell_dictionaries_zip") { outputs = [ "$root_build_dir/hunspell_dictionaries.zip" ] } +copy("libcxx_headers") { + sources = libcxx_headers + libcxx_licenses + outputs = [ "$target_gen_dir/electron_libcxx_include/{{source_root_relative_dir}}/{{source_file_part}}" ] +} + +dist_zip("libcxx_headers_zip") { + data_deps = [ ":libcxx_headers" ] + flatten = true + flatten_relative_to = rebase_path( + "$target_gen_dir/electron_libcxx_include/buildtools/third_party/libc++/trunk", + "$root_out_dir") + + outputs = [ "$root_build_dir/libcxx_headers.zip" ] +} + +copy("libcxxabi_headers") { + sources = libcxxabi_headers + libcxxabi_licenses + outputs = [ "$target_gen_dir/electron_libcxxabi_include/{{source_root_relative_dir}}/{{source_file_part}}" ] +} + +dist_zip("libcxxabi_headers_zip") { + data_deps = [ ":libcxxabi_headers" ] + flatten = true + flatten_relative_to = rebase_path( + "$target_gen_dir/electron_libcxxabi_include/buildtools/third_party/libc++abi/trunk", + "$root_out_dir") + + outputs = [ "$root_build_dir/libcxxabi_headers.zip" ] +} + +action("libcxx_zip") { + deps = [ "//buildtools/third_party/libc++" ] + script = "build/zip_libcxx.py" + outputs = [ "$root_build_dir/libcxx_objects.zip" ] + args = rebase_path(outputs) +} + group("electron") { public_deps = [ ":electron_app" ] } diff --git a/build/zip.py b/build/zip.py index f4600c1b8c..285544aed0 100644 --- a/build/zip.py +++ b/build/zip.py @@ -72,7 +72,7 @@ def execute(argv): raise e def main(argv): - dist_zip, runtime_deps, target_cpu, _, flatten_val = argv + dist_zip, runtime_deps, target_cpu, _, flatten_val, flatten_relative_to = argv should_flatten = flatten_val == "true" dist_files = set() with open(runtime_deps) as f: @@ -99,11 +99,18 @@ def main(argv): if basename == 'chrome_sandbox' else dep ) + name_to_write = arcname + if should_flatten: + if flatten_relative_to: + if name_to_write.startswith(flatten_relative_to): + name_to_write = name_to_write[len(flatten_relative_to):] + else: + name_to_write = os.path.basename(arcname) + else: + name_to_write = os.path.basename(arcname) z.write( dep, - os.path.basename(arcname) - if should_flatten - else arcname, + name_to_write, ) if __name__ == '__main__': diff --git a/build/zip_libcxx.py b/build/zip_libcxx.py new file mode 100644 index 0000000000..d3474a2dac --- /dev/null +++ b/build/zip_libcxx.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +from __future__ import print_function +import os +import subprocess +import sys +import zipfile + +def execute(argv): + try: + output = subprocess.check_output(argv, stderr=subprocess.STDOUT) + return output + except subprocess.CalledProcessError as e: + print(e.output) + raise e + +def get_object_files(base_path, archive_name): + archive_file = os.path.join(base_path, archive_name) + output = execute(['nm', '-g', archive_file]).decode('ascii') + object_files = set() + lines = output.split("\n") + for line in lines: + if line.startswith(base_path): + object_file = line.split(":")[0] + object_files.add(object_file) + return list(object_files) + [archive_file] + +def main(argv): + dist_zip, = argv + out_dir = os.path.dirname(dist_zip) + base_path_libcxx = os.path.join(out_dir, 'obj/buildtools/third_party/libc++') + base_path_libcxxabi = os.path.join(out_dir, 'obj/buildtools/third_party/libc++abi') + object_files_libcxx = get_object_files(base_path_libcxx, 'libc++.a') + object_files_libcxxabi = get_object_files(base_path_libcxxabi, 'libc++abi.a') + with zipfile.ZipFile( + dist_zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True + ) as z: + object_files_libcxx.sort() + for object_file in object_files_libcxx: + z.write(object_file, os.path.relpath(object_file, base_path_libcxx)) + for object_file in object_files_libcxxabi: + z.write(object_file, os.path.relpath(object_file, base_path_libcxxabi)) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) \ No newline at end of file diff --git a/filenames.libcxx.gni b/filenames.libcxx.gni new file mode 100644 index 0000000000..1e9c6ffcbc --- /dev/null +++ b/filenames.libcxx.gni @@ -0,0 +1,194 @@ +libcxx_headers = [ + "//buildtools/third_party/libc++/trunk/include/CMakeLists.txt", + "//buildtools/third_party/libc++/trunk/include/__availability", + "//buildtools/third_party/libc++/trunk/include/__bit_reference", + "//buildtools/third_party/libc++/trunk/include/__bits", + "//buildtools/third_party/libc++/trunk/include/__bsd_locale_defaults.h", + "//buildtools/third_party/libc++/trunk/include/__bsd_locale_fallbacks.h", + "//buildtools/third_party/libc++/trunk/include/__config", + "//buildtools/third_party/libc++/trunk/include/__config_site.in", + "//buildtools/third_party/libc++/trunk/include/__debug", + "//buildtools/third_party/libc++/trunk/include/__errc", + "//buildtools/third_party/libc++/trunk/include/__functional_03", + "//buildtools/third_party/libc++/trunk/include/__functional_base", + "//buildtools/third_party/libc++/trunk/include/__functional_base_03", + "//buildtools/third_party/libc++/trunk/include/__hash_table", + "//buildtools/third_party/libc++/trunk/include/__libcpp_version", + "//buildtools/third_party/libc++/trunk/include/__locale", + "//buildtools/third_party/libc++/trunk/include/__memory/allocator_traits.h", + "//buildtools/third_party/libc++/trunk/include/__memory/base.h", + "//buildtools/third_party/libc++/trunk/include/__memory/pointer_traits.h", + "//buildtools/third_party/libc++/trunk/include/__memory/utilities.h", + "//buildtools/third_party/libc++/trunk/include/__mutex_base", + "//buildtools/third_party/libc++/trunk/include/__node_handle", + "//buildtools/third_party/libc++/trunk/include/__nullptr", + "//buildtools/third_party/libc++/trunk/include/__split_buffer", + "//buildtools/third_party/libc++/trunk/include/__sso_allocator", + "//buildtools/third_party/libc++/trunk/include/__std_stream", + "//buildtools/third_party/libc++/trunk/include/__string", + "//buildtools/third_party/libc++/trunk/include/__support/android/locale_bionic.h", + "//buildtools/third_party/libc++/trunk/include/__support/fuchsia/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/ibm/limits.h", + "//buildtools/third_party/libc++/trunk/include/__support/ibm/locale_mgmt_aix.h", + "//buildtools/third_party/libc++/trunk/include/__support/ibm/nanosleep.h", + "//buildtools/third_party/libc++/trunk/include/__support/ibm/support.h", + "//buildtools/third_party/libc++/trunk/include/__support/ibm/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/musl/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/newlib/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/nuttx/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/openbsd/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/solaris/floatingpoint.h", + "//buildtools/third_party/libc++/trunk/include/__support/solaris/wchar.h", + "//buildtools/third_party/libc++/trunk/include/__support/solaris/xlocale.h", + "//buildtools/third_party/libc++/trunk/include/__support/win32/limits_msvc_win32.h", + "//buildtools/third_party/libc++/trunk/include/__support/win32/locale_win32.h", + "//buildtools/third_party/libc++/trunk/include/__support/xlocale/__nop_locale_mgmt.h", + "//buildtools/third_party/libc++/trunk/include/__support/xlocale/__posix_l_fallback.h", + "//buildtools/third_party/libc++/trunk/include/__support/xlocale/__strtonum_fallback.h", + "//buildtools/third_party/libc++/trunk/include/__threading_support", + "//buildtools/third_party/libc++/trunk/include/__tree", + "//buildtools/third_party/libc++/trunk/include/__tuple", + "//buildtools/third_party/libc++/trunk/include/__undef_macros", + "//buildtools/third_party/libc++/trunk/include/algorithm", + "//buildtools/third_party/libc++/trunk/include/any", + "//buildtools/third_party/libc++/trunk/include/array", + "//buildtools/third_party/libc++/trunk/include/atomic", + "//buildtools/third_party/libc++/trunk/include/barrier", + "//buildtools/third_party/libc++/trunk/include/bit", + "//buildtools/third_party/libc++/trunk/include/bitset", + "//buildtools/third_party/libc++/trunk/include/cassert", + "//buildtools/third_party/libc++/trunk/include/ccomplex", + "//buildtools/third_party/libc++/trunk/include/cctype", + "//buildtools/third_party/libc++/trunk/include/cerrno", + "//buildtools/third_party/libc++/trunk/include/cfenv", + "//buildtools/third_party/libc++/trunk/include/cfloat", + "//buildtools/third_party/libc++/trunk/include/charconv", + "//buildtools/third_party/libc++/trunk/include/chrono", + "//buildtools/third_party/libc++/trunk/include/cinttypes", + "//buildtools/third_party/libc++/trunk/include/ciso646", + "//buildtools/third_party/libc++/trunk/include/climits", + "//buildtools/third_party/libc++/trunk/include/clocale", + "//buildtools/third_party/libc++/trunk/include/cmath", + "//buildtools/third_party/libc++/trunk/include/codecvt", + "//buildtools/third_party/libc++/trunk/include/compare", + "//buildtools/third_party/libc++/trunk/include/complex", + "//buildtools/third_party/libc++/trunk/include/complex.h", + "//buildtools/third_party/libc++/trunk/include/concepts", + "//buildtools/third_party/libc++/trunk/include/condition_variable", + "//buildtools/third_party/libc++/trunk/include/csetjmp", + "//buildtools/third_party/libc++/trunk/include/csignal", + "//buildtools/third_party/libc++/trunk/include/cstdarg", + "//buildtools/third_party/libc++/trunk/include/cstdbool", + "//buildtools/third_party/libc++/trunk/include/cstddef", + "//buildtools/third_party/libc++/trunk/include/cstdint", + "//buildtools/third_party/libc++/trunk/include/cstdio", + "//buildtools/third_party/libc++/trunk/include/cstdlib", + "//buildtools/third_party/libc++/trunk/include/cstring", + "//buildtools/third_party/libc++/trunk/include/ctgmath", + "//buildtools/third_party/libc++/trunk/include/ctime", + "//buildtools/third_party/libc++/trunk/include/ctype.h", + "//buildtools/third_party/libc++/trunk/include/cwchar", + "//buildtools/third_party/libc++/trunk/include/cwctype", + "//buildtools/third_party/libc++/trunk/include/deque", + "//buildtools/third_party/libc++/trunk/include/errno.h", + "//buildtools/third_party/libc++/trunk/include/exception", + "//buildtools/third_party/libc++/trunk/include/execution", + "//buildtools/third_party/libc++/trunk/include/experimental/__config", + "//buildtools/third_party/libc++/trunk/include/experimental/__memory", + "//buildtools/third_party/libc++/trunk/include/experimental/algorithm", + "//buildtools/third_party/libc++/trunk/include/experimental/coroutine", + "//buildtools/third_party/libc++/trunk/include/experimental/deque", + "//buildtools/third_party/libc++/trunk/include/experimental/filesystem", + "//buildtools/third_party/libc++/trunk/include/experimental/forward_list", + "//buildtools/third_party/libc++/trunk/include/experimental/functional", + "//buildtools/third_party/libc++/trunk/include/experimental/iterator", + "//buildtools/third_party/libc++/trunk/include/experimental/list", + "//buildtools/third_party/libc++/trunk/include/experimental/map", + "//buildtools/third_party/libc++/trunk/include/experimental/memory_resource", + "//buildtools/third_party/libc++/trunk/include/experimental/propagate_const", + "//buildtools/third_party/libc++/trunk/include/experimental/regex", + "//buildtools/third_party/libc++/trunk/include/experimental/set", + "//buildtools/third_party/libc++/trunk/include/experimental/simd", + "//buildtools/third_party/libc++/trunk/include/experimental/string", + "//buildtools/third_party/libc++/trunk/include/experimental/type_traits", + "//buildtools/third_party/libc++/trunk/include/experimental/unordered_map", + "//buildtools/third_party/libc++/trunk/include/experimental/unordered_set", + "//buildtools/third_party/libc++/trunk/include/experimental/utility", + "//buildtools/third_party/libc++/trunk/include/experimental/vector", + "//buildtools/third_party/libc++/trunk/include/ext/__hash", + "//buildtools/third_party/libc++/trunk/include/ext/hash_map", + "//buildtools/third_party/libc++/trunk/include/ext/hash_set", + "//buildtools/third_party/libc++/trunk/include/fenv.h", + "//buildtools/third_party/libc++/trunk/include/filesystem", + "//buildtools/third_party/libc++/trunk/include/float.h", + "//buildtools/third_party/libc++/trunk/include/format", + "//buildtools/third_party/libc++/trunk/include/forward_list", + "//buildtools/third_party/libc++/trunk/include/fstream", + "//buildtools/third_party/libc++/trunk/include/functional", + "//buildtools/third_party/libc++/trunk/include/future", + "//buildtools/third_party/libc++/trunk/include/initializer_list", + "//buildtools/third_party/libc++/trunk/include/inttypes.h", + "//buildtools/third_party/libc++/trunk/include/iomanip", + "//buildtools/third_party/libc++/trunk/include/ios", + "//buildtools/third_party/libc++/trunk/include/iosfwd", + "//buildtools/third_party/libc++/trunk/include/iostream", + "//buildtools/third_party/libc++/trunk/include/istream", + "//buildtools/third_party/libc++/trunk/include/iterator", + "//buildtools/third_party/libc++/trunk/include/latch", + "//buildtools/third_party/libc++/trunk/include/limits", + "//buildtools/third_party/libc++/trunk/include/limits.h", + "//buildtools/third_party/libc++/trunk/include/list", + "//buildtools/third_party/libc++/trunk/include/locale", + "//buildtools/third_party/libc++/trunk/include/locale.h", + "//buildtools/third_party/libc++/trunk/include/map", + "//buildtools/third_party/libc++/trunk/include/math.h", + "//buildtools/third_party/libc++/trunk/include/memory", + "//buildtools/third_party/libc++/trunk/include/module.modulemap", + "//buildtools/third_party/libc++/trunk/include/mutex", + "//buildtools/third_party/libc++/trunk/include/new", + "//buildtools/third_party/libc++/trunk/include/numbers", + "//buildtools/third_party/libc++/trunk/include/numeric", + "//buildtools/third_party/libc++/trunk/include/optional", + "//buildtools/third_party/libc++/trunk/include/ostream", + "//buildtools/third_party/libc++/trunk/include/queue", + "//buildtools/third_party/libc++/trunk/include/random", + "//buildtools/third_party/libc++/trunk/include/ratio", + "//buildtools/third_party/libc++/trunk/include/regex", + "//buildtools/third_party/libc++/trunk/include/scoped_allocator", + "//buildtools/third_party/libc++/trunk/include/semaphore", + "//buildtools/third_party/libc++/trunk/include/set", + "//buildtools/third_party/libc++/trunk/include/setjmp.h", + "//buildtools/third_party/libc++/trunk/include/shared_mutex", + "//buildtools/third_party/libc++/trunk/include/span", + "//buildtools/third_party/libc++/trunk/include/sstream", + "//buildtools/third_party/libc++/trunk/include/stack", + "//buildtools/third_party/libc++/trunk/include/stdbool.h", + "//buildtools/third_party/libc++/trunk/include/stddef.h", + "//buildtools/third_party/libc++/trunk/include/stdexcept", + "//buildtools/third_party/libc++/trunk/include/stdint.h", + "//buildtools/third_party/libc++/trunk/include/stdio.h", + "//buildtools/third_party/libc++/trunk/include/stdlib.h", + "//buildtools/third_party/libc++/trunk/include/streambuf", + "//buildtools/third_party/libc++/trunk/include/string", + "//buildtools/third_party/libc++/trunk/include/string.h", + "//buildtools/third_party/libc++/trunk/include/string_view", + "//buildtools/third_party/libc++/trunk/include/strstream", + "//buildtools/third_party/libc++/trunk/include/system_error", + "//buildtools/third_party/libc++/trunk/include/tgmath.h", + "//buildtools/third_party/libc++/trunk/include/thread", + "//buildtools/third_party/libc++/trunk/include/tuple", + "//buildtools/third_party/libc++/trunk/include/type_traits", + "//buildtools/third_party/libc++/trunk/include/typeindex", + "//buildtools/third_party/libc++/trunk/include/typeinfo", + "//buildtools/third_party/libc++/trunk/include/unordered_map", + "//buildtools/third_party/libc++/trunk/include/unordered_set", + "//buildtools/third_party/libc++/trunk/include/utility", + "//buildtools/third_party/libc++/trunk/include/valarray", + "//buildtools/third_party/libc++/trunk/include/variant", + "//buildtools/third_party/libc++/trunk/include/vector", + "//buildtools/third_party/libc++/trunk/include/version", + "//buildtools/third_party/libc++/trunk/include/wchar.h", + "//buildtools/third_party/libc++/trunk/include/wctype.h", +] + +libcxx_licenses = [ "//buildtools/third_party/libc++/trunk/LICENSE.TXT" ] diff --git a/filenames.libcxxabi.gni b/filenames.libcxxabi.gni new file mode 100644 index 0000000000..813f95070a --- /dev/null +++ b/filenames.libcxxabi.gni @@ -0,0 +1,6 @@ +libcxxabi_headers = [ + "//buildtools/third_party/libc++abi/trunk/include/__cxxabi_config.h", + "//buildtools/third_party/libc++abi/trunk/include/cxxabi.h", +] + +libcxxabi_licenses = [ "//buildtools/third_party/libc++abi/trunk/LICENSE.TXT" ] diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 26686c1592..c81ae91c8b 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -101,3 +101,4 @@ fix_expose_decrementcapturercount_in_web_contents_impl.patch add_setter_for_browsermainloop_result_code.patch chore_allow_overriding_of_enable_pak_file_integrity_checks.patch make_include_of_stack_trace_h_unconditional.patch +build_libc_as_static_library.patch diff --git a/patches/chromium/build_libc_as_static_library.patch b/patches/chromium/build_libc_as_static_library.patch new file mode 100644 index 0000000000..96c7be7b00 --- /dev/null +++ b/patches/chromium/build_libc_as_static_library.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: VerteDinde +Date: Wed, 12 May 2021 13:19:19 -0700 +Subject: build_libc++_as_static_library + +Build libc++ as static library to compile and pass +nan tests + +diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn +index 65f6e8585ad374ad59e7670babfedd2fbdfbaa43..0b1333bc8de626db056567f599be27808e1495e5 100644 +--- a/buildtools/third_party/libc++/BUILD.gn ++++ b/buildtools/third_party/libc++/BUILD.gn +@@ -32,7 +32,11 @@ config("winver") { + if (libcxx_is_shared) { + _libcxx_target_type = "shared_library" + } else { +- _libcxx_target_type = "source_set" ++ if (is_win) { ++ _libcxx_target_type = "source_set" ++ } else { ++ _libcxx_target_type = "static_library" ++ } + } + target(_libcxx_target_type, "libc++") { + # Most things that need to depend on libc++ should do so via the implicit +@@ -40,6 +44,7 @@ target(_libcxx_target_type, "libc++") { + # need to explicitly depend on libc++. + visibility = [ + "//build/config:common_deps", ++ "//electron:libcxx_zip", + "//third_party/catapult/devil:devil", + ] + if (is_linux && !is_chromeos) { +diff --git a/buildtools/third_party/libc++abi/BUILD.gn b/buildtools/third_party/libc++abi/BUILD.gn +index 8b1da01ce87ff6db8e67938d4c083312cfa3101f..1668eba70db1933a434709c0140fe125991249b3 100644 +--- a/buildtools/third_party/libc++abi/BUILD.gn ++++ b/buildtools/third_party/libc++abi/BUILD.gn +@@ -4,7 +4,7 @@ + + import("//build/config/c++/c++.gni") + +-source_set("libc++abi") { ++static_library("libc++abi") { + if (export_libcxxabi_from_executables) { + visibility = [ "//build/config:executable_deps" ] + } else { diff --git a/patches/nan/.patches b/patches/nan/.patches index 778dd3193d..e40404e7c5 100644 --- a/patches/nan/.patches +++ b/patches/nan/.patches @@ -1 +1,2 @@ api_simplify_scriptorigin.patch +nan_string_test_alignment.patch diff --git a/patches/nan/nan_string_test_alignment.patch b/patches/nan/nan_string_test_alignment.patch new file mode 100644 index 0000000000..c5e848ccbe --- /dev/null +++ b/patches/nan/nan_string_test_alignment.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: clavin +Date: Wed, 12 May 2021 12:43:07 -0600 +Subject: nan_string_test_alignment + +Modifies a NAN test to avoid a debug check pertaining to efficient string alignment. + +diff --git a/test/cpp/strings.cpp b/test/cpp/strings.cpp +index 95edeac91a4ec6a5f5cd80aa36dca8a55eb53f2a..0ad5cb7095490ac1eb454318582a9a683cb14be1 100644 +--- a/test/cpp/strings.cpp ++++ b/test/cpp/strings.cpp +@@ -26,7 +26,9 @@ NAN_METHOD(EncodeHex) { + } + + NAN_METHOD(EncodeUCS2) { +- info.GetReturnValue().Set(Encode("h\0e\0l\0l\0o\0", 10, UCS2)); ++ // This odd declaration is to get the string data aligned to a 2-byte boundary ++ const uint16_t str[] = {'h', 'e', 'l', 'l', 'o'}; ++ info.GetReturnValue().Set(Encode(reinterpret_cast(str), 10, UCS2)); + } + + Persistent returnUtf8String_persistent; diff --git a/script/gen-libc++-filenames.js b/script/gen-libc++-filenames.js new file mode 100644 index 0000000000..0d083c4ea2 --- /dev/null +++ b/script/gen-libc++-filenames.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); + +const check = process.argv.includes('--check'); + +function findAllHeaders (basePath) { + const allFiles = fs.readdirSync(basePath); + const toReturn = []; + for (const file of allFiles) { + const absPath = path.resolve(basePath, file); + if (fs.statSync(absPath).isDirectory()) { + toReturn.push(...findAllHeaders(absPath)); + } else { + toReturn.push(absPath); + } + } + return toReturn; +} + +for (const folder of ['libc++', 'libc++abi']) { + const prettyName = folder.replace(/\+/g, 'x'); + + const libcxxIncludeDir = path.resolve(__dirname, '..', '..', 'buildtools', 'third_party', folder, 'trunk', 'include'); + const gclientPath = `buildtools/third_party/${folder}/trunk/include`; + + const headers = findAllHeaders(libcxxIncludeDir).map(absPath => path.relative(path.resolve(__dirname, '../..', gclientPath), absPath)); + + const content = `${prettyName}_headers = [ + ${headers.map(f => `"//${path.posix.join(gclientPath, f)}"`).join(',\n ')}, +] + +${prettyName}_licenses = [ "//buildtools/third_party/${folder}/trunk/LICENSE.TXT" ] +`; + + const filenamesPath = path.resolve(__dirname, '..', `filenames.${prettyName}.gni`); + + if (check) { + const currentContent = fs.readFileSync(filenamesPath, 'utf8'); + if (currentContent !== content) { + console.log('currentContent: ', currentContent); + console.log('content: ', content); + throw new Error(`${prettyName} filenames need to be regenerated, latest generation does not match current file. Please run node gen-libc++-filenames.js`); + } + } else { + console.log(filenamesPath); + fs.writeFileSync(filenamesPath, content); + } +} diff --git a/script/nan-spec-runner.js b/script/nan-spec-runner.js index 4af65945ea..32db5fda7d 100644 --- a/script/nan-spec-runner.js +++ b/script/nan-spec-runner.js @@ -25,7 +25,43 @@ async function main () { npm_config_arch: process.env.NPM_CONFIG_ARCH, npm_config_yes: 'true' }); - const { status: buildStatus } = cp.spawnSync(NPX_CMD, ['node-gyp', 'rebuild', '--directory', 'test', '-j', 'max'], { + + const clangDir = path.resolve(BASE, 'third_party', 'llvm-build', 'Release+Asserts', 'bin'); + const cc = path.resolve(clangDir, 'clang'); + const cxx = path.resolve(clangDir, 'clang++'); + const ld = path.resolve(clangDir, 'lld'); + + // TODO(ckerr) this is cribbed from read obj/electron/electron_app.ninja. + // Maybe it would be better to have this script literally open up that + // file and pull cflags_cc from it instead of using bespoke code here? + // I think it's unlikely to work; but if it does, it would be more futureproof + const cxxflags = [ + '-std=c++14', + '-nostdinc++', + '-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS', // needed by next line + `-isystem"${path.resolve(BASE, 'buildtools', 'third_party', 'libc++', 'trunk', 'include')}"`, + `-isystem"${path.resolve(BASE, 'buildtools', 'third_party', 'libc++abi', 'trunk', 'include')}"`, + '-fPIC' + ].join(' '); + + const ldflags = [ + '-stdlib=libc++', + '-fuse-ld=lld', + `-L"${path.resolve(BASE, 'out', `${utils.getOutDir({ shouldLog: true })}`, 'obj', 'buildtools', 'third_party', 'libc++abi')}"`, + `-L"${path.resolve(BASE, 'out', `${utils.getOutDir({ shouldLog: true })}`, 'obj', 'buildtools', 'third_party', 'libc++')}"`, + '-lc++abi' + ].join(' '); + + if (process.platform !== 'win32') { + env.CC = cc; + env.CFLAGS = cxxflags; + env.CXX = cxx; + env.LD = ld; + env.CXXFLAGS = cxxflags; + env.LDFLAGS = ldflags; + } + + const { status: buildStatus } = cp.spawnSync(NPX_CMD, ['node-gyp', 'rebuild', '--verbose', '--directory', 'test', '-j', 'max'], { env, cwd: NAN_DIR, stdio: 'inherit' @@ -48,9 +84,7 @@ async function main () { const onlyTests = args.only && args.only.split(','); const DISABLED_TESTS = [ - 'nannew-test.js', - 'setcallhandler-test.js', // TODO(jkleinsc) renable once https://github.com/electron/electron/pull/29028 lands - 'typedarrays-test.js' // TODO(nornagon): https://github.com/electron/electron/issues/28414 + 'nannew-test.js' ]; const testsToRun = fs.readdirSync(path.resolve(NAN_DIR, 'test', 'js')) .filter(test => !DISABLED_TESTS.includes(test)) diff --git a/script/release/release.js b/script/release/release.js index 6185019c9e..37ed602ddf 100755 --- a/script/release/release.js +++ b/script/release/release.js @@ -139,6 +139,12 @@ function assetsForVersion (version, validatingRelease) { 'electron-api.json', 'electron.d.ts', 'hunspell_dictionaries.zip', + 'libcxx_headers.zip', + 'libcxxabi_headers.zip', + `libcxx-objects-${version}-linux-arm64.zip`, + `libcxx-objects-${version}-linux-armv7l.zip`, + `libcxx-objects-${version}-linux-ia32.zip`, + `libcxx-objects-${version}-linux-x64.zip`, `ffmpeg-${version}-darwin-x64.zip`, `ffmpeg-${version}-darwin-arm64.zip`, `ffmpeg-${version}-linux-arm64.zip`, diff --git a/script/release/uploaders/upload.py b/script/release/uploaders/upload.py index 8ad471b374..316ffc9723 100755 --- a/script/release/uploaders/upload.py +++ b/script/release/uploaders/upload.py @@ -37,6 +37,8 @@ PDB_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'pdb') DEBUG_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'debug') TOOLCHAIN_PROFILE_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'toolchain-profile') +CXX_OBJECTS_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, + 'libcxx_objects') def main(): @@ -95,6 +97,20 @@ def main(): shutil.copy2(os.path.join(OUT_DIR, 'debug.zip'), debug_zip) upload_electron(release, debug_zip, args) + # Upload libcxx_objects.zip for linux only + libcxx_objects = get_zip_name('libcxx-objects', ELECTRON_VERSION) + libcxx_objects_zip = os.path.join(OUT_DIR, libcxx_objects) + shutil.copy2(os.path.join(OUT_DIR, 'libcxx_objects.zip'), libcxx_objects_zip) + upload_electron(release, libcxx_objects_zip, args) + + # Upload headers.zip and abi_headers.zip as non-platform specific + if get_target_arch() == "x64": + cxx_headers_zip = os.path.join(OUT_DIR, 'libcxx_headers.zip') + upload_electron(release, cxx_headers_zip, args) + + abi_headers_zip = os.path.join(OUT_DIR, 'libcxxabi_headers.zip') + upload_electron(release, abi_headers_zip, args) + # Upload free version of ffmpeg. ffmpeg = get_zip_name('ffmpeg', ELECTRON_VERSION) ffmpeg_zip = os.path.join(OUT_DIR, ffmpeg)