From e07a7892ee1bb2a2b697d4ad636b02bdc742fa10 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 23 Sep 2020 12:54:56 +0200 Subject: [PATCH] Configuration: Make it possible to have an argument file Some compilers / linkers allow arguments to be given in a file instead of on the command line. We make it possible to specify this by giving the compiler / linker flag for it, using the config attribute 'shared_argfileflag'. This currently only impacts the build of shared libraries, as those are potentially made up of a massive amount of object files, which has been reported to overwhelm the command line on some platforms. Fixes #12797 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/12960) --- Configurations/50-nonstop.conf | 6 +++++ Configurations/shared-info.pl | 1 + Configurations/unix-Makefile.tmpl | 39 ++++++++++++++++++++++++++----- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Configurations/50-nonstop.conf b/Configurations/50-nonstop.conf index e11bc77083..64385a809a 100644 --- a/Configurations/50-nonstop.conf +++ b/Configurations/50-nonstop.conf @@ -51,6 +51,7 @@ cflags => '-Wtarget=tns/r -Wsystype=guardian', lflags => '-Wld="-set systype guardian"', shared_ldflag => '-Wshared -Wld="-export_all -soname $(@:lib%.so=%)"', + shared_argfileflag => '-Wld_obey=', }, # Itanium + guardian: @@ -60,6 +61,7 @@ cflags => '-Wtarget=tns/e -Wsystype=guardian', lflags => '-Weld="-set systype guardian"', shared_ldflag => '-Wshared -Weld="-export_all -soname $(@:lib%.so=%)"', + shared_argfileflag => '-Weld_obey=', }, # x86 + guardian: @@ -69,6 +71,7 @@ cflags => '-Wtarget=tns/x -Wsystype=guardian', lflags => '-Wxld="-set systype guardian"', shared_ldflag => '-Wshared -Wxld="-export_all -soname $(@:lib%.so=%)"', + shared_argfileflag => '-Wxld_obey=', }, # MIPS + oss (unused but present for convenience): @@ -77,6 +80,7 @@ cflags => '-Wtarget=tns/r -Wsystype=oss', lflags => '-Wld="-set systype oss"', shared_ldflag => '-Wshared -Wld="-export_all"', + shared_argfileflag => '-Wld_obey=', }, # Itanium + oss: 'nonstop-archenv-itanium-oss' => { @@ -85,6 +89,7 @@ cflags => '-Wtarget=tns/e -Wsystype=oss', lflags => '-Weld="-set systype oss"', shared_ldflag => '-Wshared -Weld="-export_all"', + shared_argfileflag => '-Weld_obey=', }, # x86_64 + oss: 'nonstop-archenv-x86_64-oss' => { @@ -93,6 +98,7 @@ cflags => '-Wtarget=tns/x -Wsystype=oss', lflags => '-Wxld="-set systype oss"', shared_ldflag => '-Wshared -Wxld="-export_all"', + shared_argfileflag => '-Wxld_obey=', }, # Size variants diff --git a/Configurations/shared-info.pl b/Configurations/shared-info.pl index 82e828dc41..2b236b4b9b 100644 --- a/Configurations/shared-info.pl +++ b/Configurations/shared-info.pl @@ -55,6 +55,7 @@ my %shared_info; # def_flag made to empty string so it still generates # something shared_defflag => '', + shared_argfileflag => '@', }; }, 'alpha-osf1-shared' => sub { diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 44bf206d00..20fe46e337 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -1437,6 +1437,7 @@ EOF my $simple = platform->sharedlib_simple($args{lib}); my $full = platform->sharedlib($args{lib}); + my $argfile = defined $target{shared_argfileflag} ? $full.".args" : undef; my $shared_soname = ""; $shared_soname .= ' '.$target{shared_sonameflag}.basename($full) if defined $target{shared_sonameflag}; @@ -1445,10 +1446,31 @@ EOF if defined $target{shared_impflag}; my $shared_def = join("", map { ' '.$target{shared_defflag}.$_ } @defs); - my $objs = join(" \\\n\t\t", fill_lines(' ', $COLUMNS - 16, @objs)); - my $deps = join(" \\\n" . ' ' x (length($full) + 2), - fill_lines(' ', $COLUMNS - length($full) - 2, - @objs, @defs, @deps)); + # There is at least one platform where the compiler-as-linker needs to + # have one object file directly on the command line. That won't hurt + # any other platform, so we do that for everyone when there's an argfile + # to be had. This depends heavily on splice, which removes elements from + # the given array, and returns them so they can be captured. + my @argfileobjs = $argfile + ? splice(@objs, 1) + : (); + my $argfilecmds = $argfile + ? join("\n\t", map { "echo $_ >> $argfile" } @argfileobjs) + : undef; + my $argfiledeps = $argfile + ? join(" \\\n" . ' ' x (length($argfile) + 2), + fill_lines(' ', $COLUMNS - length($full) - 2, @argfileobjs)) + : undef; + my @fulldeps = (@objs, ($argfile ? $argfile : ()), @defs, @deps); + my @fullobjs = ( + @objs, + ($argfile ? $target{shared_argfileflag}.$argfile : ()) + ); + my $fulldeps = + join(" \\\n" . ' ' x (length($full) + 2), + fill_lines(' ', $COLUMNS - length($full) - 2, @fulldeps)); + my $fullobjs = + join(" \\\n\t\t", fill_lines(' ', $COLUMNS - 16, @fullobjs)); my $recipe = <<"EOF"; $simple: $full @@ -1465,10 +1487,10 @@ EOF EOF } $recipe .= <<"EOF"; -$full: $deps +$full: $fulldeps \$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\ -o $full$shared_def \\ - $objs \\ + $fullobjs \\ $linklibs \$(LIB_EX_LIBS) EOF if (windowsdll()) { @@ -1481,6 +1503,11 @@ EOF cp -p $full fuzz/ EOF } + $recipe .= <<"EOF" if defined $argfile; +$argfile: $argfiledeps + \$(RM) $argfile + $argfilecmds +EOF return $recipe; } sub obj2dso {