From ab71af34533a43e4d8d788e8ed678bf572672458 Mon Sep 17 00:00:00 2001 From: Jesse Chan Date: Fri, 21 May 2021 09:39:23 +0800 Subject: [PATCH] build: allow LTO with Clang 3.9.1+ Bug: #38568 Test: manual, - arm64-apple-darwin20.5.0 / Apple clang version 12.0.5 (clang-1205.0.22.9) - x86_64-pc-linux-gnu / Ubuntu clang version 13.0.0-++20210520052624+48780527dd68-1~exp1~20210520153429.417 Signed-off-by: Jesse Chan PR-URL: https://github.com/nodejs/node/pull/38751 Reviewed-By: Jiawen Geng Reviewed-By: Joyee Cheung --- common.gypi | 17 ++++++++++++----- configure.py | 35 ++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/common.gypi b/common.gypi index 4bc75c7c41c..ee91fb1df6d 100644 --- a/common.gypi +++ b/common.gypi @@ -164,17 +164,28 @@ 'v8_enable_handle_zapping': 0, 'pgo_generate': ' -fprofile-generate ', 'pgo_use': ' -fprofile-use -fprofile-correction ', - 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', 'conditions': [ ['node_shared != "true"', { 'MSVC_runtimeType': 0 # MultiThreaded (/MT) }, { 'MSVC_runtimeType': 2 # MultiThreadedDLL (/MD) }], + ['llvm_version=="0.0"', { + 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC + }, { + 'lto': ' -flto ', # Clang + }], ], }, 'cflags': [ '-O3' ], 'conditions': [ + ['enable_lto=="true"', { + 'cflags': ['<(lto)'], + 'ldflags': ['<(lto)'], + 'xcode_settings': { + 'LLVM_LTO': 'YES', + }, + }], ['OS=="linux"', { 'conditions': [ ['node_section_ordering_info!=""', { @@ -206,10 +217,6 @@ 'cflags': ['<(pgo_use)'], 'ldflags': ['<(pgo_use)'], },], - ['enable_lto=="true"', { - 'cflags': ['<(lto)'], - 'ldflags': ['<(lto)'], - },], ], },], ['OS == "android"', { diff --git a/configure.py b/configure.py index 895a0869cbc..05d43150524 100755 --- a/configure.py +++ b/configure.py @@ -173,7 +173,7 @@ parser.add_argument("--enable-lto", dest="enable_lto", default=None, help="Enable compiling with lto of a binary. This feature is only available " - "on linux with gcc and g++ 5.4.1 or newer.") + "with gcc 5.4.1+ or clang 3.9.1+.") parser.add_argument("--link-module", action="append", @@ -952,6 +952,7 @@ def get_gas_version(cc): # quite prepared to go that far yet. def check_compiler(o): if sys.platform == 'win32': + o['variables']['llvm_version'] = '0.0' if not options.openssl_no_asm and options.dest_cpu in ('x86', 'x64'): nasm_version = get_nasm_version('nasm') o['variables']['nasm_version'] = nasm_version @@ -1131,12 +1132,19 @@ def configure_mips(o, target_arch): host_byteorder = 'little' if target_arch in ('mipsel', 'mips64el') else 'big' o['variables']['v8_host_byteorder'] = host_byteorder +def clang_version_ge(version_checked): + for compiler in [(CC, 'c'), (CXX, 'c++')]: + ok, is_clang, clang_version, gcc_version = \ + try_check_compiler(compiler[0], compiler[1]) + if is_clang and clang_version >= version_checked: + return True + return False def gcc_version_ge(version_checked): for compiler in [(CC, 'c'), (CXX, 'c++')]: - ok, is_clang, clang_version, compiler_version = \ + ok, is_clang, clang_version, gcc_version = \ try_check_compiler(compiler[0], compiler[1]) - if is_clang or compiler_version < version_checked: + if is_clang or gcc_version < version_checked: return False return True @@ -1217,18 +1225,19 @@ def configure_node(o): o['variables']['enable_pgo_generate'] = b(options.enable_pgo_generate) o['variables']['enable_pgo_use'] = b(options.enable_pgo_use) - if flavor != 'linux' and (options.enable_lto): + if flavor == 'win' and (options.enable_lto): raise Exception( - 'The lto option is supported only on linux.') + 'Use Link Time Code Generation instead.') - if flavor == 'linux': - if options.enable_lto: - version_checked = (5, 4, 1) - if not gcc_version_ge(version_checked): - version_checked_str = ".".join(map(str, version_checked)) - raise Exception( - 'The option --enable-lto is supported for gcc and gxx %s' - ' or newer only.' % (version_checked_str)) + if options.enable_lto: + gcc_version_checked = (5, 4, 1) + clang_version_checked = (3, 9, 1) + if not gcc_version_ge(gcc_version_checked) and not clang_version_ge(clang_version_checked): + gcc_version_checked_str = ".".join(map(str, gcc_version_checked)) + clang_version_checked_str = ".".join(map(str, clang_version_checked)) + raise Exception( + 'The option --enable-lto is supported for gcc %s+' + 'or clang %s+ only.' % (gcc_version_checked_str, clang_version_checked_str)) o['variables']['enable_lto'] = b(options.enable_lto)