Commit bec2db18 authored by Richard Levitte's avatar Richard Levitte
Browse files

Configure: Name object files according to the product they are part of



This will allow to have different object files for different products,
even if they share the same source code, and possibly different builds
for those different object files.

For example, one can have something like this:

    SOURCES[libfoo]=cookie.c
    INCLUDES[libfoo]=include/foo
    SOURCES[libbar]=cookie.c
    INCLUDES[libbar]=include/bar

This would mean that the object files and libraries would be build
somewhat like this:

    $(CC) -Iinclude/foo -o libfoo-lib-cookie.o cookie.c
    $(AR) $(ARFLAGS) libfoo.a libfoo-lib-cookie.o
    $(CC) -Iinclude/bar -o libbar-lib-cookie.o cookie.c
    $(AR) $(ARFLAGS) libbar.a libbar-lib-cookie.o

Reviewed-by: default avatarPaul Dale <paul.dale@oracle.com>
Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7159)
parent 609e4be8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@
     http://web.cs.ucdavis.edu/%7Erogaway/papers/offsets.pdf
     [Paul Dale]
  *) Rename the object files, i.e. give them other names than in previous
     versions.  Their names now include the name of the final product, as
     well as its type mnemonic (bin, lib, shlib).
     [Richard Levitte]
 Changes between 1.1.0i and 1.1.1 [11 Sep 2018]
  *) Add a new ClientHello callback. Provides a callback interface that gives
+3 −6
Original line number Diff line number Diff line
@@ -125,8 +125,7 @@
     unless ($disabled{shared} || $lib =~ /\.a$/) {
         $OUT .= libobj2shlib(shlib => $unified_info{sharednames}->{$lib},
                              lib => $lib,
                              objs => [ @{$unified_info{shared_sources}->{$lib}},
                                        @{$unified_info{sources}->{$lib}} ],
                              objs => $unified_info{shared_sources}->{$lib},
                              deps => [ reducedepends(resolvedepends($lib)) ],
                              installed => is_installed($lib));
         foreach ((@{$unified_info{shared_sources}->{$lib}},
@@ -155,12 +154,10 @@
     my $lib = shift;
     return "" if $cache{$lib};
     $OUT .= obj2dso(lib => $lib,
                     objs => [ @{$unified_info{sources}->{$lib}},
                               @{$unified_info{shared_sources}->{$lib}} ],
                     objs => $unified_info{shared_sources}->{$lib},
                     deps => [ resolvedepends($lib) ],
                     installed => is_installed($lib));
     foreach ((@{$unified_info{sources}->{$lib}},
               @{$unified_info{shared_sources}->{$lib}})) {
     foreach (@{$unified_info{shared_sources}->{$lib}}) {
         doobj($_, $lib, intent => "dso", installed => is_installed($lib));
     }
     $cache{$lib} = 1;
+112 −10
Original line number Diff line number Diff line
@@ -2029,15 +2029,15 @@ EOF
                    $o =~ s/\.[csS]$/.o/; # C and assembler
                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
                    $o = cleanfile($buildd, $o, $blddir);
                    $unified_info{sources}->{$ddest}->{$o} = 1;
                    $unified_info{sources}->{$o}->{$s} = 1;
                    $unified_info{sources}->{$ddest}->{$o} = -1;
                    $unified_info{sources}->{$o}->{$s} = -1;
                } elsif ($s =~ /\.rc$/) {
                    # We also recognise resource files
                    my $o = $_;
                    $o =~ s/\.rc$/.res/; # Resource configuration
                    my $o = cleanfile($buildd, $o, $blddir);
                    $unified_info{sources}->{$ddest}->{$o} = 1;
                    $unified_info{sources}->{$o}->{$s} = 1;
                    $unified_info{sources}->{$ddest}->{$o} = -1;
                    $unified_info{sources}->{$o}->{$s} = -1;
                } else {
                    $unified_info{sources}->{$ddest}->{$s} = 1;
                }
@@ -2065,15 +2065,15 @@ EOF
                    $o =~ s/\.[csS]$/.o/; # C and assembler
                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
                    $o = cleanfile($buildd, $o, $blddir);
                    $unified_info{shared_sources}->{$ddest}->{$o} = 1;
                    $unified_info{sources}->{$o}->{$s} = 1;
                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
                    $unified_info{sources}->{$o}->{$s} = -1;
                } elsif ($s =~ /\.rc$/) {
                    # We also recognise resource files
                    my $o = $_;
                    $o =~ s/\.rc$/.res/; # Resource configuration
                    my $o = cleanfile($buildd, $o, $blddir);
                    $unified_info{shared_sources}->{$ddest}->{$o} = 1;
                    $unified_info{sources}->{$o}->{$s} = 1;
                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
                    $unified_info{sources}->{$o}->{$s} = -1;
                } elsif ($s =~ /\.(def|map|opt)$/) {
                    # We also recognise .def / .map / .opt files
                    # We know they are generated files
@@ -2189,6 +2189,101 @@ EOF
        }
    }

    # Go through all object files and change their names to something that
    # reflects what they will be built for.  Note that for some source files,
    # this leads to duplicate object files because they are used multiple times.
    # the goal is to rename all object files according to this scheme:
    #    {productname}-{midfix}-{origobjname}.[o|res]
    # the {midfix} is a keyword indicating the type of product, which is mostly
    # valuable for libraries since they come in two forms.
    #
    # This also reorganises the {sources} and {shared_sources} so that the
    # former only contains ALL object files that are supposed to end up in
    # static libraries and programs, while the latter contains ALL object files
    # that are supposed to end up in shared libraries and DSOs.
    # The main reason for having two different source structures is to allow
    # the same name to be used for the static and the shared variants of a
    # library.
    {
        # Take copies so we don't get interference from added stuff
        my %unified_copy = ();
        foreach (('sources', 'shared_sources')) {
            $unified_copy{$_} = { %{$unified_info{$_}} }
                if defined($unified_info{$_});
            delete $unified_info{$_};
        }
        foreach my $prodtype (('programs', 'libraries', 'engines', 'scripts')) {
            # $intent serves multi purposes:
            # - give a prefix for the new object files names
            # - in the case of libraries, rearrange the object files so static
            #   libraries use the 'sources' structure exclusively, while shared
            #   libraries use the 'shared_sources' structure exclusively.
            my $intent = {
                programs  => { bin    => { src => [ 'sources' ],
                                           dst => 'sources' } },
                libraries => { lib    => { src => [ 'sources' ],
                                           dst => 'sources' },
                               shlib  => { prodselect =>
                                               sub { grep !/\.a$/, @_ },
                                           src => [ 'sources',
                                                    'shared_sources' ],
                                           dst => 'shared_sources' } },
                engines   => { dso    => { src => [ 'sources',
                                                    'shared_sources' ],
                                           dst => 'shared_sources' } },
                scripts   => { script => { src => [ 'sources' ],
                                           dst => 'sources' } }
               } -> {$prodtype};
            foreach my $kind (keys %$intent) {
                my @src = @{$intent->{$kind}->{src}};
                my $dst = $intent->{$kind}->{dst};
                my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
                foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
                    # %prod_sources has all applicable objects as keys, and
                    # their corresponding sources as values
                    my %prod_sources =
                        map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
                        map { keys %{$unified_copy{$_}->{$prod}} }
                        @src;
                    foreach (keys %prod_sources) {
                        # Only affect object or resource files, the others
                        # simply get a new value (+1 instead of -1)
                        if ($_ =~ /\.(o|res)$/) {
                            (my $prodname = $prod) =~ s|\.a$||;
                            my $newobj =
                                catfile(dirname($_),
                                        basename($prodname)
                                            . '-' . $kind
                                            . '-' . basename($_));
                            $unified_info{$dst}->{$prod}->{$newobj} = 1;
                            foreach my $src (@{$prod_sources{$_}}) {
                                $unified_info{sources}->{$newobj}->{$src} = 1;
                            }
                            # Adjust dependencies
                            foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
                                $unified_info{depends}->{$_}->{$deps} = -1;
                                $unified_info{depends}->{$newobj}->{$deps} = 1;
                            }
                            # Adjust includes
                            foreach my $k (('source', 'build')) {
                                next unless
                                    defined($unified_info{includes}->{$_}->{$k});
                                my @incs = @{$unified_info{includes}->{$_}->{$k}};
                                $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
                            }
                        } else {
                            $unified_info{$dst}->{$prod}->{$_} = 1;
                        }
                    }
                }
            }
        }
    }
    # At this point, we have a number of sources with the value -1.  They
    # aren't part of the local build and are probably meant for a different
    # platform, and can therefore be cleaned away.  That happens when making
    # %unified_info more efficient below.

    ### Make unified_info a bit more efficient
    # One level structures
    foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
@@ -2197,8 +2292,15 @@ EOF
    # Two level structures
    foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
        foreach my $l2 (sort keys %{$unified_info{$l1}}) {
            $unified_info{$l1}->{$l2} =
                [ sort keys %{$unified_info{$l1}->{$l2}} ];
            my @items =
                sort
                grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
                keys %{$unified_info{$l1}->{$l2}};
            if (@items) {
                $unified_info{$l1}->{$l2} = [ @items ];
            } else {
                delete $unified_info{$l1}->{$l2};
            }
        }
    }
    # Includes