libtool: Fix mishandling compiler flags with MSVC tools

With MSVC, linker flags were not properly being linked in during a
compile command. A check has been added to verify if there are linker
flags set and then use a different command when linking.

Fixes applied for bug#74175.

* build-aux/ltmain.in: Fix command parser for '-Wl' option for MSVC.
* m4/libtool.m4: Fix MSVC compile commands.
* tests/flags.at: Use '$GREP --' instead of '$FGREP' when comparing with
  stdout.
This commit is contained in:
Ileana Dumitrescu 2025-01-07 19:34:11 +02:00
parent af7df02434
commit 43068986b0
No known key found for this signature in database
GPG Key ID: 6570EA01146F7354
3 changed files with 34 additions and 12 deletions

View File

@ -5155,8 +5155,13 @@ func_mode_link ()
continue
;;
xlinker)
func_append linker_flags " $qarg"
func_append compiler_flags " $wl$qarg"
func_append linker_flags "$qarg,"
# Args in the var 'compiler_flags' causes warnings in MSVC
func_cc_basename "$CC"
case $func_cc_basename_result in
cl|cl.exe) ;;
*) func_append compiler_flags " $wl$qarg" ;;
esac
prev=
func_append compile_command " $wl$qarg"
func_append finalize_command " $wl$qarg"
@ -5530,8 +5535,13 @@ func_mode_link ()
IFS=$save_ifs
func_quote_arg pretty "$flag"
func_append arg " $wl$func_quote_arg_result"
func_append compiler_flags " $wl$func_quote_arg_result"
func_append linker_flags " $func_quote_arg_result"
# Args in the var 'compiler_flags' causes warnings in MSVC
func_cc_basename "$CC"
case $func_cc_basename_result in
cl|cl.exe) ;;
*) func_append compiler_flags " $wl$func_quote_arg_result" ;;
esac
func_append linker_flags "$func_quote_arg_result,"
done
IFS=$save_ifs
func_stripname ' ' '' "$arg"

20
m4/libtool.m4 vendored
View File

@ -5776,6 +5776,8 @@ _LT_EOF
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
# A check exists to verify if there are linker flags, which will use
# different commands when linking.
_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp "$export_symbols" "$output_objdir/$soname.def";
@ -5783,7 +5785,11 @@ _LT_EOF
else
$SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
fi~
$CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
if test -z "$linker_flags"; then
$CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib";
else
$CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,$linker_flags-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib";
fi~
linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
@ -5815,7 +5821,7 @@ _LT_EOF
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
# FIXME: Should let the user specify the lib program.
@ -6856,14 +6862,20 @@ if test yes != "$_lt_caught_CXX_error"; then
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
# A check exists to verify if there are linker flags, which will use
# different commands when linking.
_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp "$export_symbols" "$output_objdir/$soname.def";
echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
else
$SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
fi~
$CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
if test -z "$linker_flags"; then
$CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib";
else
$CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,$linker_flags-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib";
fi~
linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'

View File

@ -129,7 +129,7 @@ for flag in -Wc, -Wl, '-Xcompiler ' '-Xlinker '; do
-Wc, | -Xcompiler\ )
AT_CHECK([$LIBTOOL -n --tag=lt_tag --mode=compile $compile ]dnl
[$flag-foo -c $source], [], [stdout], [ignore])
AT_CHECK([$FGREP " -foo" stdout], [], [ignore])
AT_CHECK([$GREP -- " -foo" stdout], [], [ignore])
flag_prefix_prog=
flag_prefix_lib=
flags_in_liblink=$compiler_flags_in_liblink
@ -143,7 +143,7 @@ for flag in -Wc, -Wl, '-Xcompiler ' '-Xlinker '; do
AT_CHECK([$LIBTOOL -n --tag=lt_tag --mode=link $link ]dnl
[-o program$EXEEXT a.lo $flag-foo], [], [stdout], [ignore])
AT_CHECK([$FGREP " $flag_prefix_prog-foo" stdout], [], [ignore])
AT_CHECK([$GREP -- "$flag_prefix_prog-foo" stdout], [], [ignore])
eval set x "$library_and_module"
for output
@ -152,9 +152,9 @@ for flag in -Wc, -Wl, '-Xcompiler ' '-Xlinker '; do
AT_CHECK([$LIBTOOL -n --tag=lt_tag --mode=link $link ]dnl
[-o $output a.lo -rpath /nowhere $flag-foo], [], [stdout], [ignore])
if $flags_in_liblink; then
AT_CHECK([$FGREP " $flag_prefix_lib-foo" stdout], [], [ignore])
AT_CHECK([$GREP -- "$flag_prefix_lib-foo" stdout], [], [ignore])
else
AT_CHECK([$FGREP " $flag_prefix_lib-foo" stdout], [1])
AT_CHECK([$GREP -- " $flag_prefix_lib-foo" stdout], [1])
fi
done
done