bpo-28015: Support LTO build with clang (GH-9908)

.o generated by clang in LTO mode actually are LLVM bitcode files, which
leads to a few errors during configure/build step:

- add lto flags to the BASECFLAGS instead of CFLAGS, as CFLAGS are used
  to build autoconf test case, and some are not compatible with clang LTO
  (they assume binary in the .o, not bitcode)
- force llvm-ar instead of ar, as ar is not aware of .o files generated
  by clang -flto
This commit is contained in:
serge-sans-paille 2018-10-25 01:54:22 +02:00 committed by Victor Stinner
parent 890423f796
commit 5ad36f9b21
4 changed files with 235 additions and 83 deletions

View File

@ -0,0 +1 @@
Have --with-lto works correctly with clang.

4
aclocal.m4 vendored
View File

@ -13,7 +13,7 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1) dnl serial 11 (pkg-config-0.29)
dnl dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@ -55,7 +55,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1]) [m4_define([PKG_MACROS_VERSION], [0.29])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ

246
configure vendored
View File

@ -671,16 +671,18 @@ BASECFLAGS
CFLAGS_ALIASING CFLAGS_ALIASING
OPT OPT
LLVM_PROF_FOUND LLVM_PROF_FOUND
target_os
target_vendor
target_cpu
target
LLVM_PROFDATA LLVM_PROFDATA
LLVM_PROF_ERR LLVM_PROF_ERR
LLVM_PROF_FILE LLVM_PROF_FILE
LLVM_PROF_MERGER LLVM_PROF_MERGER
PGO_PROF_USE_FLAG PGO_PROF_USE_FLAG
PGO_PROF_GEN_FLAG PGO_PROF_GEN_FLAG
LLVM_AR_FOUND
target_os
target_vendor
target_cpu
target
LLVM_AR
DEF_MAKE_RULE DEF_MAKE_RULE
DEF_MAKE_ALL_RULE DEF_MAKE_ALL_RULE
ABIFLAGS ABIFLAGS
@ -6388,6 +6390,26 @@ else
DEF_MAKE_RULE="all" DEF_MAKE_RULE="all"
fi fi
# Make llvm-relatec checks work on systems where llvm tools are not installed with their
# normal names in the default $PATH (ie: Ubuntu). They exist under the
# non-suffixed name in their versioned llvm directory.
llvm_bin_dir=''
llvm_path="${PATH}"
if test "${CC}" = "clang"
then
clang_bin=`which clang`
# Some systems install clang elsewhere as a symlink to the real path
# which is where the related llvm tools are located.
if test -L "${clang_bin}"
then
clang_dir=`dirname "${clang_bin}"`
clang_bin=`readlink "${clang_bin}"`
llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"`
llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}"
fi
fi
# Enable LTO flags # Enable LTO flags
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5
$as_echo_n "checking for --with-lto... " >&6; } $as_echo_n "checking for --with-lto... " >&6; }
@ -6413,65 +6435,8 @@ fi
if test "$Py_LTO" = 'true' ; then if test "$Py_LTO" = 'true' ; then
case $CC in case $CC in
*clang*) *clang*)
case $ac_sys_system in
Darwin*)
# Any changes made here should be reflected in the GCC+Darwin case below
LTOFLAGS="-flto -Wl,-export_dynamic"
;;
*)
LTOFLAGS="-flto"
;;
esac
;;
*gcc*)
case $ac_sys_system in
Darwin*)
LTOFLAGS="-flto -Wl,-export_dynamic"
;;
*)
LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none"
;;
esac
;;
esac
if test "$ac_cv_prog_cc_g" = "yes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
then
# bpo-30345: Add -g to LDFLAGS when compiling with LTO
# to get debug symbols.
LTOFLAGS="$LTOFLAGS -g"
fi
CFLAGS="$CFLAGS $LTOFLAGS"
LDFLAGS="$LDFLAGS $LTOFLAGS"
fi
# Enable PGO flags.
# Make this work on systems where llvm tools are not installed with their
# normal names in the default $PATH (ie: Ubuntu). They exist under the
# non-suffixed name in their versioned llvm directory.
llvm_bin_dir=''
llvm_path="${PATH}"
if test "${CC}" = "clang"
then
clang_bin=`which clang`
# Some systems install clang elsewhere as a symlink to the real path
# which is where the related llvm tools are located.
if test -L "${clang_bin}"
then
clang_dir=`dirname "${clang_bin}"`
clang_bin=`readlink "${clang_bin}"`
llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"`
llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}"
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
$as_echo_n "checking target system type... " >&6; } $as_echo_n "checking target system type... " >&6; }
if ${ac_cv_target+:} false; then : if ${ac_cv_target+:} false; then :
$as_echo_n "(cached) " >&6 $as_echo_n "(cached) " >&6
@ -6510,6 +6475,163 @@ test -n "$target_alias" &&
test "$program_prefix$program_suffix$program_transform_name" = \ test "$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, && NONENONEs,x,x, &&
program_prefix=${target_alias}- program_prefix=${target_alias}-
# Extract the first word of "$target_alias-llvm-ar", so it can be a program name with args.
set dummy $target_alias-llvm-ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_LLVM_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $LLVM_AR in
[\\/]* | ?:[\\/]*)
ac_cv_path_LLVM_AR="$LLVM_AR" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in ${llvm_path}
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_LLVM_AR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
LLVM_AR=$ac_cv_path_LLVM_AR
if test -n "$LLVM_AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_AR" >&5
$as_echo "$LLVM_AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test -z "$ac_cv_path_LLVM_AR"; then
if test "$build" = "$target"; then
ac_pt_LLVM_AR=$LLVM_AR
# Extract the first word of "llvm-ar", so it can be a program name with args.
set dummy llvm-ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_LLVM_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_LLVM_AR in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_LLVM_AR="$ac_pt_LLVM_AR" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in ${llvm_path}
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_LLVM_AR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_path_ac_pt_LLVM_AR" && ac_cv_path_ac_pt_LLVM_AR="''"
;;
esac
fi
ac_pt_LLVM_AR=$ac_cv_path_ac_pt_LLVM_AR
if test -n "$ac_pt_LLVM_AR"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_AR" >&5
$as_echo "$ac_pt_LLVM_AR" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
LLVM_AR=$ac_pt_LLVM_AR
else
LLVM_AR="''"
fi
else
LLVM_AR="$ac_cv_path_LLVM_AR"
fi
if test -n "${LLVM_AR}" -a -x "${LLVM_AR}"
then
LLVM_AR_FOUND="found"
else
LLVM_AR_FOUND="not-found"
fi
if test "$ac_sys_system" = "Darwin" -a "${LLVM_AR_FOUND}" = "not-found"
then
found_llvm_ar=`/usr/bin/xcrun -find llvm-ar 2>/dev/null`
if test -n "${found_llvm_ar}"
then
LLVM_AR='/usr/bin/xcrun llvm-ar'
LLVM_AR_FOUND=found
{ $as_echo "$as_me:${as_lineno-$LINENO}: llvm-ar found via xcrun: ${LLVM_AR}" >&5
$as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;}
fi
fi
if test $LLVM_AR_FOUND = not-found
then
LLVM_PROFR_ERR=yes
as_fn_error $? "llvm-ar is required for a --with-lto build with clang but could not be found." "$LINENO" 5
else
LLVM_AR_ERR=no
fi
AR="${LLVM_AR}"
case $ac_sys_system in
Darwin*)
# Any changes made here should be reflected in the GCC+Darwin case below
LTOFLAGS="-flto -Wl,-export_dynamic"
;;
*)
LTOFLAGS="-flto"
;;
esac
;;
*gcc*)
case $ac_sys_system in
Darwin*)
LTOFLAGS="-flto -Wl,-export_dynamic"
;;
*)
LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none"
;;
esac
;;
esac
if test "$ac_cv_prog_cc_g" = "yes"
then
# bpo-30345: Add -g to LDFLAGS when compiling with LTO
# to get debug symbols.
LTOFLAGS="$LTOFLAGS -g"
fi
BASECFLAGS="$BASECFLAGS $LTOFLAGS"
LDFLAGS="$LDFLAGS $LTOFLAGS"
fi
# Enable PGO flags.
# Extract the first word of "$target_alias-llvm-profdata", so it can be a program name with args. # Extract the first word of "$target_alias-llvm-profdata", so it can be a program name with args.
set dummy $target_alias-llvm-profdata; ac_word=$2 set dummy $target_alias-llvm-profdata; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

View File

@ -1265,6 +1265,26 @@ else
DEF_MAKE_RULE="all" DEF_MAKE_RULE="all"
fi fi
# Make llvm-relatec checks work on systems where llvm tools are not installed with their
# normal names in the default $PATH (ie: Ubuntu). They exist under the
# non-suffixed name in their versioned llvm directory.
llvm_bin_dir=''
llvm_path="${PATH}"
if test "${CC}" = "clang"
then
clang_bin=`which clang`
# Some systems install clang elsewhere as a symlink to the real path
# which is where the related llvm tools are located.
if test -L "${clang_bin}"
then
clang_dir=`dirname "${clang_bin}"`
clang_bin=`readlink "${clang_bin}"`
llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"`
llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}"
fi
fi
# Enable LTO flags # Enable LTO flags
AC_MSG_CHECKING(for --with-lto) AC_MSG_CHECKING(for --with-lto)
AC_ARG_WITH(lto, AS_HELP_STRING([--with-lto], [Enable Link Time Optimization in any build. Disabled by default.]), AC_ARG_WITH(lto, AS_HELP_STRING([--with-lto], [Enable Link Time Optimization in any build. Disabled by default.]),
@ -1281,6 +1301,33 @@ fi],
if test "$Py_LTO" = 'true' ; then if test "$Py_LTO" = 'true' ; then
case $CC in case $CC in
*clang*) *clang*)
AC_SUBST(LLVM_AR)
AC_PATH_TARGET_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path})
AC_SUBST(LLVM_AR_FOUND)
if test -n "${LLVM_AR}" -a -x "${LLVM_AR}"
then
LLVM_AR_FOUND="found"
else
LLVM_AR_FOUND="not-found"
fi
if test "$ac_sys_system" = "Darwin" -a "${LLVM_AR_FOUND}" = "not-found"
then
found_llvm_ar=`/usr/bin/xcrun -find llvm-ar 2>/dev/null`
if test -n "${found_llvm_ar}"
then
LLVM_AR='/usr/bin/xcrun llvm-ar'
LLVM_AR_FOUND=found
AC_MSG_NOTICE([llvm-ar found via xcrun: ${LLVM_AR}])
fi
fi
if test $LLVM_AR_FOUND = not-found
then
LLVM_PROFR_ERR=yes
AC_MSG_ERROR([llvm-ar is required for a --with-lto build with clang but could not be found.])
else
LLVM_AR_ERR=no
fi
AR="${LLVM_AR}"
case $ac_sys_system in case $ac_sys_system in
Darwin*) Darwin*)
# Any changes made here should be reflected in the GCC+Darwin case below # Any changes made here should be reflected in the GCC+Darwin case below
@ -1310,7 +1357,7 @@ if test "$Py_LTO" = 'true' ; then
LTOFLAGS="$LTOFLAGS -g" LTOFLAGS="$LTOFLAGS -g"
fi fi
CFLAGS="$CFLAGS $LTOFLAGS" BASECFLAGS="$BASECFLAGS $LTOFLAGS"
LDFLAGS="$LDFLAGS $LTOFLAGS" LDFLAGS="$LDFLAGS $LTOFLAGS"
fi fi
@ -1320,24 +1367,6 @@ AC_SUBST(PGO_PROF_USE_FLAG)
AC_SUBST(LLVM_PROF_MERGER) AC_SUBST(LLVM_PROF_MERGER)
AC_SUBST(LLVM_PROF_FILE) AC_SUBST(LLVM_PROF_FILE)
AC_SUBST(LLVM_PROF_ERR) AC_SUBST(LLVM_PROF_ERR)
# Make this work on systems where llvm tools are not installed with their
# normal names in the default $PATH (ie: Ubuntu). They exist under the
# non-suffixed name in their versioned llvm directory.
llvm_bin_dir=''
llvm_path="${PATH}"
if test "${CC}" = "clang"
then
clang_bin=`which clang`
# Some systems install clang elsewhere as a symlink to the real path
# which is where the related llvm tools are located.
if test -L "${clang_bin}"
then
clang_dir=`dirname "${clang_bin}"`
clang_bin=`readlink "${clang_bin}"`
llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"`
llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}"
fi
fi
AC_SUBST(LLVM_PROFDATA) AC_SUBST(LLVM_PROFDATA)
AC_PATH_TARGET_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path}) AC_PATH_TARGET_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path})
AC_SUBST(LLVM_PROF_FOUND) AC_SUBST(LLVM_PROF_FOUND)