summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Configurations/README173
-rw-r--r--Configurations/common.tmpl118
-rwxr-xr-xConfigure53
3 files changed, 331 insertions, 13 deletions
diff --git a/Configurations/README b/Configurations/README
index fb94aa723e..75907a6d5c 100644
--- a/Configurations/README
+++ b/Configurations/README
@@ -1,5 +1,5 @@
Configurations of OpenSSL target platforms
-------------------------------------------
+==========================================
Target configurations are a collection of facts that we know about
different platforms and their capabilities. We organise them in a
@@ -427,3 +427,174 @@ or:
RENAME[libcrypto]=ossl_libcrypto
RENAME[libssl]=ossl_libssl
ENDIF
+
+
+Build-file programming with the "unified" build system
+======================================================
+
+"Build files" are called "Makefile" on Unix-like operating systems,
+"descrip.mms" for MMS on VMS, "makefile" for nmake on Windows, etc.
+
+To use the "unified" build system, the target configuration needs to
+set the three items 'build_scheme', 'build_file' and 'build_command'.
+In the rest of this section, we will assume that 'build_scheme' is set
+to "unified" (see the configurations documentation above for the
+details).
+
+For any name given by 'build_file', the "unified" system expects a
+template file in Configurations/ named like the build file, with
+".tmpl" appended, or in case of possible ambiguity, a combination of
+the second 'build_scheme' list item and the 'build_file' name. For
+example, if 'build_file' is set to "Makefile", the template could be
+Configurations/Makefile.tmpl or Configurations/unix-Makefile.tmpl.
+In case both Configurations/unix-Makefile.tmpl and
+Configurations/Makefile.tmpl are present, the former takes
+precedence.
+
+The build-file template is processed with the perl module
+Text::Template, using "{-" and "-}" as delimiters that enclose the
+perl code fragments that generate configuration-dependent content.
+Those perl fragments have access to all the hash variables from
+configdata.pem.
+
+The build-file template is expected to define at least the following
+perl functions in a perl code fragment enclosed with "{-" and "-}".
+They are all expected to return a string with the lines they produce.
+
+ src2dep - function that produces build file lines to get the
+ dependencies for an object file into a dependency
+ file.
+
+ It's called like this:
+
+ src2dep(obj => "PATH/TO/objectfile",
+ srcs => [ "PATH/TO/sourcefile", ... ],
+ incs => [ "INCL/PATH", ... ]);
+
+ 'obj' has the dependent object file as well as
+ object file the dependencies are for; it's *without*
+ extension, src2dep() is expected to add that.
+ 'srcs' has the list of source files to build the
+ object file, with the first item being the source
+ file that directly corresponds to the object file.
+ 'incs' is a list of include file directories.
+
+ src2obj - function that produces build file lines to build an
+ object file from source files and associated data.
+
+ It's called like this:
+
+ src2obj(obj => "PATH/TO/objectfile",
+ srcs => [ "PATH/TO/sourcefile", ... ],
+ deps => [ "dep1", ... ],
+ incs => [ "INCL/PATH", ... ]);
+
+ 'obj' has the intended object file *without*
+ extension, src2obj() is expected to add that.
+ 'srcs' has the list of source files to build the
+ object file, with the first item being the source
+ file that directly corresponds to the object file.
+ 'deps' is a list of dependencies. 'incs' is a list
+ of include file directories.
+
+ obj2lib - function that produces build file lines to build a
+ static library file ("libfoo.a" in Unix terms) from
+ object files.
+
+ called like this:
+
+ obj2lib(lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ]);
+
+ 'lib' has the intended library file name *without*
+ extension, obj2lib is expected to add that. 'objs'
+ has the list of object files (also *without*
+ extension) to build this library.
+
+ libobj2shlib - function that produces build file lines to build a
+ shareable object library file ("libfoo.so" in Unix
+ terms) from the corresponding static library file
+ or object files.
+
+ called like this:
+
+ libobj2shlib(shlib => "PATH/TO/shlibfile",
+ lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/otherlibfile", ... ],
+ ordinals => [ "word", "/PATH/TO/ordfile" ]);
+
+ 'lib' has the intended library file name *without*
+ extension, libobj2shlib is expected to add that.
+ 'shlib' has the correcponding shared library name
+ *without* extension. 'deps' has the list of other
+ libraries (also *without* extension) this library
+ needs to be linked with. 'objs' has the list of
+ object files (also *without* extension) to build
+ this library. 'ordinals' MAY be present, and when
+ it is, its value is an array where the word is
+ "crypto" or "ssl" and the file is one of the ordinal
+ files util/libeay.num or util/ssleay.num in the
+ source directory.
+
+ This function has a choice; it can use the
+ corresponding static library as input to make the
+ shared library, or the list of object files.
+
+ obj2dynlib - function that produces build file lines to build a
+ dynamically loadable library file ("libfoo.so" on
+ Unix) from object files.
+
+ called like this:
+
+ obj2dynlib(lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/otherlibfile",
+ ... ]);
+
+ This is almost the same as libobj2shlib, but the
+ intent is to build a shareable library that can be
+ loaded in runtime (a "plugin"...). The differences
+ are subtle, one of the most visible ones is that the
+ resulting shareable library is produced from object
+ files only.
+
+ obj2bin - function that produces build file lines to build an
+ executable file from object files.
+
+ called like this:
+
+ obj2bin(bin => "PATH/TO/binfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/libfile", ... ]);
+
+ 'bin' has the intended executable file name
+ *without* extension, obj2bin is expected to add
+ that. 'objs' has the list of object files (also
+ *without* extension) to build this library. 'deps'
+ has the list of library files (also *without*
+ extension) that the programs needs to be linked
+ with.
+
+ in2script - function that produces build file lines to build a
+ script file from some input.
+
+ called like this:
+
+ in2script(script => "PATH/TO/scriptfile",
+ sources => [ "PATH/TO/infile", ... ]);
+
+ 'script' has the intended script file name.
+ 'sources' has the list of source files to build the
+ resulting script from.
+
+In all cases, file file paths are relative to the build tree top, and
+the build file actions run with the build tree top as current working
+directory.
+
+Make sure to end the section with these functions with a string that
+you thing is apropriate for the resulting build file. If nothing
+else, end it like this:
+
+ ""; # Make sure no lingering values end up in the Makefile
+ -}
diff --git a/Configurations/common.tmpl b/Configurations/common.tmpl
new file mode 100644
index 0000000000..a750e21a33
--- /dev/null
+++ b/Configurations/common.tmpl
@@ -0,0 +1,118 @@
+{- # -*- Mode: perl -*-
+
+ my $a;
+
+ # 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 resolvedepends {
+ my $thing = shift;
+ my @listsofar = @_; # to check if we're looping
+ my @list = @{$unified_info{depends}->{$thing}};
+ my @newlist = ();
+ if (scalar @list) {
+ foreach my $item (@list) {
+ # It's time to break off when the dependency list starts looping
+ next if grep { $_ eq $item } @listsofar;
+ push @newlist, $item, resolvedepends($item, @listsofar, $item);
+ }
+ }
+ @newlist;
+ }
+ sub reducedepends {
+ my @list = @_;
+ my @newlist = ();
+ while (@list) {
+ my $item = shift @list;
+ push @newlist, $item
+ unless grep { $item eq $_ } @list;
+ }
+ @newlist;
+ }
+
+ # doobj is responsible for producing all the recipes that build
+ # object files as well as dependency files.
+ sub doobj {
+ my $obj = shift;
+ (my $obj_no_o = $obj) =~ s|\.o$||;
+ my $bin = shift;
+ if (@{$unified_info{sources}->{$obj}}) {
+ $OUT .= src2obj(obj => $obj_no_o,
+ srcs => $unified_info{sources}->{$obj},
+ deps => [ reducedepends(resolvedepends($obj)) ],
+ incs => [ @{$unified_info{includes}->{$bin}},
+ @{$unified_info{includes}->{$obj}} ]);
+ $OUT .= src2dep(obj => $obj_no_o,
+ srcs => $unified_info{sources}->{$obj},
+ incs => [ @{$unified_info{includes}->{$bin}},
+ @{$unified_info{includes}->{$obj}} ]);
+ }
+ }
+
+ # dolib is responsible for building libraries. It will call
+ # libobj2shlib 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;
+ if (!$config{no_shared}) {
+ my %ordinals =
+ $unified_info{ordinals}->{$lib}
+ ? (ordinals => $unified_info{ordinals}->{$lib}) : ();
+ $OUT .= libobj2shlib(shlib => $unified_info{sharednames}->{$lib},
+ lib => $lib,
+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x }
+ @{$unified_info{sources}->{$lib}} ],
+ deps => [ reducedepends(resolvedepends($lib)) ],
+ %ordinals);
+ }
+ $OUT .= obj2lib(lib => $lib,
+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x }
+ @{$unified_info{sources}->{$lib}} ]);
+ map { doobj($_, $lib, intent => "lib") } @{$unified_info{sources}->{$lib}};
+ }
+
+ # doengine is responsible for building engines. It will call
+ # obj2dynlib, and also makes sure all object files for the library
+ # are built.
+ sub doengine {
+ my $lib = shift;
+ $OUT .= obj2dynlib(lib => $lib,
+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x }
+ @{$unified_info{sources}->{$lib}} ],
+ deps => [ resolvedepends($lib) ]);
+ map { doobj($_, $lib, intent => "lib") } @{$unified_info{sources}->{$lib}};
+ }
+
+ # 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;
+ my $deps = [ reducedepends(resolvedepends($bin)) ];
+ $OUT .= obj2bin(bin => $bin,
+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x }
+ @{$unified_info{sources}->{$bin}} ],
+ deps => $deps);
+ map { doobj($_, $bin, intent => "bin") } @{$unified_info{sources}->{$bin}};
+ }
+
+ # dobin is responsible for building scripts from templates. It will
+ # call in2script.
+ sub doscript {
+ my $script = shift;
+ $OUT .= in2script(script => $script,
+ sources => $unified_info{sources}->{$script});
+ }
+
+ # Build all known libraries, engines, programs and scripts.
+ # Everything else will be handled as a consequence.
+ map { dolib($_) } @{$unified_info{libraries}};
+ map { doengine($_) } @{$unified_info{engines}};
+ map { dobin($_) } @{$unified_info{programs}};
+ map { doscript($_) } @{$unified_info{scripts}};
+
+ # Finally, should there be any applicable BEGINRAW/ENDRAW sections,
+ # they are added here.
+ $OUT .= $_."\n" foreach(@{$unified_info{rawlines}});
+-}
diff --git a/Configure b/Configure
index 9954858f8c..c30204522a 100755
--- a/Configure
+++ b/Configure
@@ -844,6 +844,9 @@ $target{nm} = "nm";
$target{build_scheme} = [ $target{build_scheme} ]
if ref($target{build_scheme}) ne "ARRAY";
+my ($builder, $builder_platform, @builder_opts) =
+ @{$target{build_scheme}};
+
# if $config{prefix}/lib$target{multilib} is not an existing directory, then
# assume that it's not searched by linker automatically, in
# which case adding $target{multilib} suffix causes more grief than
@@ -976,7 +979,7 @@ if (!$config{no_shared})
}
}
-if ($target{build_scheme}->[0] ne "mk1mf")
+if ($builder ne "mk1mf")
{
# add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
if ($config{no_shared})
@@ -1163,7 +1166,17 @@ if ($strict_warnings)
# If we use the unified build, collect information from build.info files
my %unified_info = ();
-if ($target{build_scheme}->[0] eq "unified") {
+if ($builder eq "unified") {
+ # Store the name of the template file we will build the build file from
+ # in %config. This may be useful for the build file itself.
+ my $build_file_template =
+ catfile($srcdir, "Configurations",
+ $builder_platform."-".$target{build_file}.".tmpl");
+ $build_file_template =
+ catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
+ if (! -f $build_file_template);
+ $config{build_file_template} = $build_file_template;
+
use lib catdir(dirname(__FILE__),"util");
use with_fallback qw(Text::Template);
@@ -1323,7 +1336,7 @@ if ($target{build_scheme}->[0] eq "unified") {
next if @skip && $skip[$#skip] <= 0;
push @rawlines, $_
if ($target_kind eq $target{build_file}
- || $target_kind eq $target{build_file}."(".$target{build_scheme}->[1].")");
+ || $target_kind eq $target{build_file}."(".$builder_platform.")");
}
},
qr/^(?:#.*|\s*)$/ => sub { },
@@ -1601,7 +1614,7 @@ print OUT <<"EOF";
);
EOF
-if ($target{build_scheme}->[0] eq "unified") {
+if ($builder eq "unified") {
my $recurse;
$recurse = sub {
my $indent = shift;
@@ -1646,7 +1659,7 @@ EOF
print OUT "1;\n";
close(OUT);
-die <<"EOF" if $target{build_scheme}->[0] ne "unified" && $srcdir ne $blddir;
+die <<"EOF" if $builder ne "unified" && $srcdir ne $blddir;
***** Trying building anywhere else than in the source tree will not
***** work for target $config{target}. To make it possible, it needs
@@ -1654,7 +1667,7 @@ die <<"EOF" if $target{build_scheme}->[0] ne "unified" && $srcdir ne $blddir;
EOF
-print "IsMK1MF =", ($target{build_scheme}->[0] eq "mk1mf" ? "yes" : "no"), "\n";
+print "IsMK1MF =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
print "CC =$target{cc}\n";
print "CFLAG =$config{cflags}\n";
print "LFLAG =$config{lflags}\n";
@@ -1735,7 +1748,20 @@ sub build_Makefile {
my %builders = (
unified => sub {
- die "unified build currently does nothing";
+ run_dofile(catfile($blddir, $target{build_file}),
+ $config{build_file_template},
+ catfile($srcdir, "Configurations", "common.tmpl"));
+
+ my $make_command = "$make PERL=\'$config{perl}\'";
+ my $make_targets = "";
+ $make_targets .= " depend"
+ if $config{depflags} ne $default_depflags && $make_depend;
+ (system $make_command.$make_targets) == 0
+ or die "make $make_targets failed"
+ if $make_targets ne "";
+ if ($config{depflags} ne $default_depflags && !$make_depend) {
+ $warn_make_depend++;
+ }
},
unixmake => sub {
build_Makefile();
@@ -1745,14 +1771,18 @@ my %builders = (
my $make_command = "$make PERL=\'$config{perl}\'";
my $make_targets = "";
- $make_targets .= " depend" if $config{depflags} ne $default_depflags && $make_depend;
- (system $make_command.$make_targets) == 0 or die "make $make_targets failed"
+ $make_targets .= " depend"
+ if $config{depflags} ne $default_depflags && $make_depend;
+ (system $make_command.$make_targets) == 0
+ or die "make $make_targets failed"
if $make_targets ne "";
+
if ($config{depflags} ne $default_depflags && !$make_depend) {
$warn_make_depend++;
}
},
mk1mf => sub {
+ my $platform = shift;
# The only reason we do this is to have something to build MINFO from
build_Makefile();
@@ -1769,7 +1799,7 @@ EOF
close(OUT);
# create the ms/version32.rc file if needed
- if (! grep /^netware/, @{$target{build_scheme}}) {
+ if ($platform eq "netware") {
my ($v1, $v2, $v3, $v4);
if ($config{version_num} =~ /^0x([0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{1})L$/i) {
$v1=hex $1;
@@ -1832,8 +1862,7 @@ EOF
},
);
-my ($builder, @builder_opts) = @{$target{build_scheme}};
-$builders{$builder}->(@builder_opts);
+$builders{$builder}->($builder_platform, @builder_opts);
print <<"EOF";