mirror of
https://github.com/openssl/openssl.git
synced 2024-12-09 05:51:54 +08:00
22b414672d
SHARED_SOURCE is reserved for products that are expected to come in dual shared / non-shared form, i.e. the routine libraries like libcrypto and libssl, to distinguish source that should only appear in their shared form. Modules are always shared, so there's no need for them to have this type of distinction. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8623)
221 lines
8.5 KiB
Perl
221 lines
8.5 KiB
Perl
{- # -*- Mode: perl -*-
|
|
|
|
use File::Basename;
|
|
|
|
# A cache of objects for which a recipe has already been generated
|
|
my %cache;
|
|
|
|
# resolvedepends and reducedepends work in tandem to make sure
|
|
# there are no duplicate dependencies and that they are in the
|
|
# right order. This is especially used to sort the list of
|
|
# libraries that a build depends on.
|
|
sub extensionlesslib {
|
|
my @result = map { $_ =~ /(\.a)?$/; $` } @_;
|
|
return @result if wantarray;
|
|
return $result[0];
|
|
}
|
|
sub resolvedepends {
|
|
my $thing = shift;
|
|
my $extensionlessthing = extensionlesslib($thing);
|
|
my @listsofar = @_; # to check if we're looping
|
|
my @list = @{$unified_info{depends}->{$thing} //
|
|
$unified_info{depends}->{$extensionlessthing}};
|
|
my @newlist = ();
|
|
if (scalar @list) {
|
|
foreach my $item (@list) {
|
|
my $extensionlessitem = extensionlesslib($item);
|
|
# It's time to break off when the dependency list starts looping
|
|
next if grep { extensionlesslib($_) eq $extensionlessitem } @listsofar;
|
|
push @newlist, $item, resolvedepends($item, @listsofar, $item);
|
|
}
|
|
}
|
|
@newlist;
|
|
}
|
|
sub reducedepends {
|
|
my @list = @_;
|
|
my @newlist = ();
|
|
my %replace = ();
|
|
while (@list) {
|
|
my $item = shift @list;
|
|
my $extensionlessitem = extensionlesslib($item);
|
|
if (grep { $extensionlessitem eq extensionlesslib($_) } @list) {
|
|
if ($item ne $extensionlessitem) {
|
|
# If this instance of the library is explicitly static, we
|
|
# prefer that to any shared library name, since it must have
|
|
# been done on purpose.
|
|
$replace{$extensionlessitem} = $item;
|
|
}
|
|
} else {
|
|
push @newlist, $item;
|
|
}
|
|
}
|
|
map { $replace{$_} // $_; } @newlist;
|
|
}
|
|
|
|
# dogenerate is responsible for producing all the recipes that build
|
|
# generated source files. It recurses in case a dependency is also a
|
|
# generated source file.
|
|
sub dogenerate {
|
|
my $src = shift;
|
|
return "" if $cache{$src};
|
|
my $obj = shift;
|
|
my $bin = shift;
|
|
my %opts = @_;
|
|
if ($unified_info{generate}->{$src}) {
|
|
die "$src is generated by Configure, should not appear in build file\n"
|
|
if ref $unified_info{generate}->{$src} eq "";
|
|
my $script = $unified_info{generate}->{$src}->[0];
|
|
$OUT .= generatesrc(src => $src,
|
|
product => $bin,
|
|
generator => $unified_info{generate}->{$src},
|
|
generator_incs => $unified_info{includes}->{$script},
|
|
generator_deps => $unified_info{depends}->{$script},
|
|
deps => $unified_info{depends}->{$src},
|
|
incs => [ @{$unified_info{includes}->{$obj}},
|
|
@{$unified_info{includes}->{$bin}} ],
|
|
defs => [ @{$unified_info{defines}->{$obj}},
|
|
@{$unified_info{defines}->{$bin}} ],
|
|
%opts);
|
|
foreach (@{$unified_info{depends}->{$src}}) {
|
|
dogenerate($_, $obj, $bin, %opts);
|
|
}
|
|
}
|
|
$cache{$src} = 1;
|
|
}
|
|
|
|
# doobj is responsible for producing all the recipes that build
|
|
# object files as well as dependency files.
|
|
sub doobj {
|
|
my $obj = shift;
|
|
return "" if $cache{$obj};
|
|
my $bin = shift;
|
|
my %opts = @_;
|
|
if (@{$unified_info{sources}->{$obj}}) {
|
|
$OUT .= src2obj(obj => $obj,
|
|
product => $bin,
|
|
srcs => $unified_info{sources}->{$obj},
|
|
deps => $unified_info{depends}->{$obj},
|
|
incs => [ @{$unified_info{includes}->{$obj}},
|
|
@{$unified_info{includes}->{$bin}} ],
|
|
defs => [ @{$unified_info{defines}->{$obj}},
|
|
@{$unified_info{defines}->{$bin}} ],
|
|
%opts);
|
|
foreach ((@{$unified_info{sources}->{$obj}},
|
|
@{$unified_info{depends}->{$obj}})) {
|
|
dogenerate($_, $obj, $bin, %opts);
|
|
}
|
|
}
|
|
$cache{$obj} = 1;
|
|
}
|
|
|
|
# dolib is responsible for building libraries. It will call
|
|
# obj2shlib is shared libraries are produced, and obj2lib in all
|
|
# cases. It also makes sure all object files for the library are
|
|
# built.
|
|
sub dolib {
|
|
my $lib = shift;
|
|
return "" if $cache{$lib};
|
|
unless ($disabled{shared} || $lib =~ /\.a$/) {
|
|
my $obj2shlib = defined &obj2shlib ? \&obj2shlib : \&libobj2shlib;
|
|
$OUT .= $obj2shlib->(lib => $lib,
|
|
attrs => $unified_info{attributes}->{$lib},
|
|
objs => $unified_info{shared_sources}->{$lib},
|
|
deps => [ reducedepends(resolvedepends($lib)) ]);
|
|
foreach ((@{$unified_info{shared_sources}->{$lib}},
|
|
@{$unified_info{sources}->{$lib}})) {
|
|
# If this is somehow a compiled object, take care of it that way
|
|
# Otherwise, it might simply be generated
|
|
if (defined $unified_info{sources}->{$_}) {
|
|
doobj($_, $lib, intent => "shlib",
|
|
attrs => $unified_info{attributes}->{$lib});
|
|
} else {
|
|
dogenerate($_, undef, undef, intent => "lib");
|
|
}
|
|
}
|
|
}
|
|
$OUT .= obj2lib(lib => $lib,
|
|
attrs => $unified_info{attributes}->{$lib},
|
|
objs => [ @{$unified_info{sources}->{$lib}} ]);
|
|
foreach (@{$unified_info{sources}->{$lib}}) {
|
|
doobj($_, $lib, intent => "lib",
|
|
attrs => $unified_info{attributes}->{$lib});
|
|
}
|
|
$cache{$lib} = 1;
|
|
}
|
|
|
|
# domodule is responsible for building modules. It will call
|
|
# obj2dso, and also makes sure all object files for the library
|
|
# are built.
|
|
sub domodule {
|
|
my $lib = shift;
|
|
return "" if $cache{$lib};
|
|
$OUT .= obj2dso(lib => $lib,
|
|
attrs => $unified_info{attributes}->{$lib},
|
|
objs => $unified_info{sources}->{$lib},
|
|
deps => [ resolvedepends($lib) ]);
|
|
foreach (@{$unified_info{sources}->{$lib}}) {
|
|
# If this is somehow a compiled object, take care of it that way
|
|
# Otherwise, it might simply be generated
|
|
if (defined $unified_info{sources}->{$_}) {
|
|
doobj($_, $lib, intent => "dso",
|
|
attrs => $unified_info{attributes}->{$lib});
|
|
} else {
|
|
dogenerate($_, undef, $lib, intent => "dso");
|
|
}
|
|
}
|
|
$cache{$lib} = 1;
|
|
}
|
|
|
|
# dobin is responsible for building programs. It will call obj2bin,
|
|
# and also makes sure all object files for the library are built.
|
|
sub dobin {
|
|
my $bin = shift;
|
|
return "" if $cache{$bin};
|
|
my $deps = [ reducedepends(resolvedepends($bin)) ];
|
|
$OUT .= obj2bin(bin => $bin,
|
|
attrs => $unified_info{attributes}->{$bin},
|
|
objs => [ @{$unified_info{sources}->{$bin}} ],
|
|
deps => $deps);
|
|
foreach (@{$unified_info{sources}->{$bin}}) {
|
|
doobj($_, $bin, intent => "bin",
|
|
attrs => $unified_info{attributes}->{$bin});
|
|
}
|
|
$cache{$bin} = 1;
|
|
}
|
|
|
|
# dobin is responsible for building scripts from templates. It will
|
|
# call in2script.
|
|
sub doscript {
|
|
my $script = shift;
|
|
return "" if $cache{$script};
|
|
$OUT .= in2script(script => $script,
|
|
attrs => $unified_info{attributes}->{$script},
|
|
sources => $unified_info{sources}->{$script});
|
|
$cache{$script} = 1;
|
|
}
|
|
|
|
sub dodir {
|
|
my $dir = shift;
|
|
return "" if !exists(&generatedir) or $cache{$dir};
|
|
$OUT .= generatedir(dir => $dir,
|
|
deps => $unified_info{dirinfo}->{$dir}->{deps},
|
|
%{$unified_info{dirinfo}->{$_}->{products}});
|
|
$cache{$dir} = 1;
|
|
}
|
|
|
|
# Start with populating the cache with all the overrides
|
|
%cache = map { $_ => 1 } @{$unified_info{overrides}};
|
|
|
|
# Build mandatory generated headers
|
|
foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); }
|
|
|
|
# Build all known libraries, modules, programs and scripts.
|
|
# Everything else will be handled as a consequence.
|
|
foreach (@{$unified_info{libraries}}) { dolib($_); }
|
|
foreach (@{$unified_info{modules}}) { domodule($_); }
|
|
foreach (@{$unified_info{programs}}) { dobin($_); }
|
|
foreach (@{$unified_info{scripts}}) { doscript($_); }
|
|
|
|
foreach (sort keys %{$unified_info{dirinfo}}) { dodir($_); }
|
|
-}
|