(our $osslprefix_q = platform->osslprefix()) =~ s/\$/\\\$/;
our $sover_dirname = platform->shlib_version_as_filename();
- our $osslver = sprintf "%02d%02d", split(/\./, $config{version});
+ our $osslver = sprintf "%02d", split(/\./, $config{version});
our $sourcedir = $config{sourcedir};
our $builddir = $config{builddir};
+ sub make_unix_path {
+ # Split the native path
+ (my $vol, my $dirs, my $file) = File::Spec->splitpath($_[0]);
+ my @dirs = File::Spec->splitdir($dirs);
+
+ # Reassemble it as a Unix path
+ $vol =~ s|:$||;
+ return File::Spec::Unix->catpath(
+ '', File::Spec::Unix->catdir('', $vol ? $vol : (), @dirs), $file);
+ }
sub sourcefile {
catfile($sourcedir, @_);
}
@{$unified_info{modules}};
our @install_modules =
grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
- && !$unified_info{attributes}->{modules}->{$_}->{engine} }
+ && !$unified_info{attributes}->{modules}->{$_}->{engine}
+ && !$unified_info{attributes}->{modules}->{$_}->{fips} }
+ @{$unified_info{modules}};
+ our @install_fipsmodules =
+ grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+ && $unified_info{attributes}->{modules}->{$_}->{fips} }
@{$unified_info{modules}};
our @install_programs =
grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
@cnf_defines,
'OPENSSLDIR="""$(OPENSSLDIR_C)"""',
'ENGINESDIR="""$(ENGINESDIR_C)"""',
- 'MODULESDIR="""$(MODULESDIR_C)"""',
- #'$(DEFINES)'
+ 'MODULESDIR="""$(MODULESDIR_C)"""'
)
+ . '$(DEFINES)'
. "'extradefines'";
our $lib_asflags =
join(' ', $target{lib_asflags} || (), @{$config{lib_asflags}},
join(',', @{$target{dso_defines}}, @{$target{module_defines}},
@{$config{dso_defines}}, @{$config{module_defines}},
@cnf_defines,
- #'$(DEFINES)'
)
+ . '$(DEFINES)'
. "'extradefines'";
our $dso_asflags =
join(' ', $target{dso_asflags} || (), $target{module_asflags} || (),
join(',', @{$target{bin_defines}},
@{$config{bin_defines}},
@cnf_defines,
- #'$(DEFINES)'
)
+ . '$(DEFINES)'
. "'extradefines'";
our $bin_asflags =
join(' ', $target{bin_asflags} || (),
our $bin_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
# This is a horrible hack, but is needed because recursive inclusion of files
- # in different directories does not work well with HP C.
- my $sd = sourcedir("crypto", "async", "arch");
+ # in different directories does not work well with VMS C. We try to help by
+ # specifying extra relative directories. They must always be in Unix format,
+ # relative to the directory where the .c file is located. The logic is that
+ # any inclusion, merged with one of these relative directories, will find the
+ # requested inclusion file.
foreach (grep /\[\.crypto\.async\.arch\].*\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
- $unified_info{before}->{$obj}
- = qq(arch_include = F\$PARSE("$sd","A.;",,,"SYNTAX_ONLY") - "A.;"
- define arch 'arch_include');
- $unified_info{after}->{$obj}
- = qq(deassign arch);
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../);
+ }
+ foreach (grep /\[\.crypto\.ec\.curve448\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ push @{$unified_info{includes_extra}->{$obj}}, qw(./arch_32 ./arch64);
+ }
+ foreach (grep /\[\.crypto\.ec\.curve448.arch_(?:32|64)\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../);
+ }
+ foreach (grep /\[\.ssl\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ # Most of the files in [.ssl.record.methods] include "ssl_local.h"
+ # which includes things like "record/record.h". Adding "./" as an
+ # inclusion directory helps making this sort of header from these
+ # directories.
+ push @{$unified_info{includes_extra}->{$obj}}, qw(./);
+ }
+ foreach (grep /\[\.ssl\.(?:record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ # Most of the files in [.ssl.record] and [.ssl.statem] include
+ # "../ssl_local.h", which includes things like "record/record.h".
+ # Adding "../" as an inclusion directory helps making this sort of header
+ # from these directories.
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../);
+
+ }
+ foreach (grep /\[\.ssl\.record\.methods\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ # Most of the files in [.ssl.record.methods] include "../../ssl_local.h"
+ # which includes things like "record/record.h". Adding "../../" as an
+ # inclusion directory helps making this sort of header from these
+ # directories.
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../../);
}
- my $sd1 = sourcedir("ssl","record");
- my $sd2 = sourcedir("ssl","statem");
- my @ssl_locl_users = grep(/^\[\.(?:ssl\.(?:record|statem)|test)\].*\.o$/,
- keys %{$unified_info{sources}});
- foreach (@ssl_locl_users) {
+ foreach (grep /\[\.test\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
- $unified_info{before}->{$obj}
- = qq(record_include = F\$PARSE("$sd1","A.;",,,"SYNTAX_ONLY") - "A.;"
- define record 'record_include'
- statem_include = F\$PARSE("$sd2","A.;",,,"SYNTAX_ONLY") - "A.;"
- define statem 'statem_include');
- $unified_info{after}->{$obj}
- = qq(deassign statem
- deassign record);
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl ./helpers);
+ }
+ foreach (grep /\[\.test\.helpers\].*?\.o$/, keys %{$unified_info{sources}}) {
+ my $obj = platform->obj($_);
+ push @{$unified_info{includes_extra}->{$obj}}, qw(../../ssl);
}
# This makes sure things get built in the order they need
VERBOSE_FAILURE=$(VF)
VERSION={- "$config{full_version}" -}
+VERSION_NUMBER={- "$config{version}" -}
MAJOR={- $config{major} -}
MINOR={- $config{minor} -}
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @libs) -}
SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @shlibs) -}
-FIPSMODULENAME={- # We do some extra checking here, as there should be only one
- use File::Basename;
- my @fipsmodules =
- grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
- && $unified_info{attributes}->{modules}->{$_}->{fips} }
- @{$unified_info{modules}};
- die "More that one FIPS module" if scalar @fipsmodules > 1;
+MODULES={- join(", ", map { "-\n\t".$_.".EXE" }
+ # Drop all modules that are dependencies, they will
+ # be processed through their dependents
+ grep { my $x = $_;
+ !grep { grep { $_ eq $x } @$_ }
+ values %{$unified_info{depends}} }
+ @{$unified_info{modules}}) -}
+FIPSMODULE={- # We do some extra checking here, as there should be only one
+ use File::Basename;
+ our @fipsmodules =
+ grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+ && $unified_info{attributes}->{modules}->{$_}->{fips} }
+ @{$unified_info{modules}};
+ die "More that one FIPS module" if scalar @fipsmodules > 1;
+ join(" ", map { platform->dso($_) } @fipsmodules) -}
+FIPSMODULENAME={- die "More that one FIPS module" if scalar @fipsmodules > 1;
join(", ", map { basename(platform->dso($_)) } @fipsmodules) -}
-MODULES={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{modules}}) -}
PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{programs}}) -}
SCRIPTS={- join(", ", map { "-\n\t".$_ } @{$unified_info{scripts}}) -}
{- output_off() if $disabled{makedepend}; "" -}
INSTALL_SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @install_shlibs) -}
INSTALL_ENGINES={- join(", ", map { "-\n\t".$_.".EXE" } @install_engines) -}
INSTALL_MODULES={- join(", ", map { "-\n\t".$_.".EXE" } @install_modules) -}
+INSTALL_FIPSMODULE={- join(", ", map { "-\n\t".$_.".EXE" } @install_fipsmodules) -}
+INSTALL_FIPSMODULECONF=[.providers]fipsmodule.cnf
INSTALL_PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @install_programs) -}
BIN_SCRIPTS={- join(", ", @install_bin_scripts) -}
MISC_SCRIPTS={- join(", ", @install_misc_scripts) -}
# Where installed ENGINE modules reside, for C
ENGINESDIR_C={- platform->osslprefix() -}ENGINES{- $sover_dirname.$target{pointer_size} -}:
# Where modules reside, for C
-MODULESDIR_C={- platform->osslprefix() -}MODULES{- $sover_dirname.$target{pointer_size} -}:
+MODULESDIR_C={- platform->osslprefix() -}MODULES{- $target{pointer_size} -}:
##### User defined commands and flags ################################
CC={- $config{CC} -}
CPP={- $config{CPP} -}
DEFINES={- our $defines = join('', map { ",$_" } @{$config{CPPDEFINES}}) -}
-INCLUDES={- our $includes = join(',', @{$config{CPPINCLUDES}}) -}
+#INCLUDES={- our $includes = join(',', @{$config{CPPINCLUDES}}) -}
CPPFLAGS={- our $cppflags = join('', @{$config{CPPFLAGS}}) -}
CFLAGS={- join('', @{$config{CFLAGS}}) -}
LDFLAGS={- join('', @{$config{LFLAGS}}) -}
$x; -}
# .FIRST and .LAST are special targets with MMS and MMK.
-# The defines in there are for C. includes that look like
-# this:
-#
-# #include <openssl/foo.h>
-# #include "internal/bar.h"
-#
-# will use the logical names to find the files. Expecting
-# DECompHP C to find files in subdirectories of whatever was
-# given with /INCLUDE is a fantasy, unfortunately.
NODEBUG=@
.FIRST :
+ {- join( "\n \$(NODEBUG) ", @{ $target{setup_commands} // [] },
+ '!' ) -}
$(NODEBUG) sourcetop = F$PARSE("$(SRCDIR)","[]A.;",,,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;" + ".]"
$(NODEBUG) DEFINE ossl_sourceroot 'sourcetop'
$(NODEBUG) !
- $(NODEBUG) openssl_inc1 = F$PARSE("[.include.openssl]","A.;",,,"syntax_only") - "A.;"
- $(NODEBUG) openssl_inc2 = F$PARSE("{- catdir($config{sourcedir},"[.include.openssl]") -}","A.;",,,"SYNTAX_ONLY") - "A.;"
- $(NODEBUG) internal_inc1 = F$PARSE("[.crypto.include.internal]","A.;",,,"SYNTAX_ONLY") - "A.;"
- $(NODEBUG) internal_inc2 = F$PARSE("{- catdir($config{sourcedir},"[.include.internal]") -}","A.;",,,"SYNTAX_ONLY") - "A.;"
- $(NODEBUG) internal_inc3 = F$PARSE("{- catdir($config{sourcedir},"[.crypto.include.internal]") -}","A.;",,,"SYNTAX_ONLY") - "A.;"
- $(NODEBUG) DEFINE openssl 'openssl_inc1','openssl_inc2'
- $(NODEBUG) DEFINE internal 'internal_inc1','internal_inc2','internal_inc3'
$(NODEBUG) staging_dir = "$(DESTDIR)"
$(NODEBUG) staging_instdir = ""
$(NODEBUG) staging_datadir = ""
$(NODEBUG) DEFINE ossl_installroot 'installtop'
$(NODEBUG) DEFINE ossl_dataroot 'datatop'
$(NODEBUG) !
+ $(NODEBUG) ! Override disturbing system logicals. We can't deassign
+ $(NODEBUG) ! them, so we create it instead. This is an unfortunate
+ $(NODEBUG) ! necessity.
+ $(NODEBUG) !
+ $(NODEBUG) openssl_inc1 = F$PARSE("[.include.openssl]","A.;",,,"syntax_only") - "A.;"
+ $(NODEBUG) openssl_inc2 = F$PARSE("sourcetop:[include.openssl]","A.;",,,"SYNTAX_ONLY") - "A.;"
+ $(NODEBUG) DEFINE openssl 'openssl_inc1','openssl_inc2'
+ $(NODEBUG) !
$(NODEBUG) ! Figure out the architecture
$(NODEBUG) !
$(NODEBUG) arch = f$edit( f$getsyi( "arch_name"), "upcase")
.LAST :
$(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEASSIGN ".uc($_) } @shlibs) || "!" -}
+ $(NODEBUG) DEASSIGN openssl
$(NODEBUG) DEASSIGN ossl_dataroot
$(NODEBUG) DEASSIGN ossl_installroot
- $(NODEBUG) DEASSIGN internal
- $(NODEBUG) DEASSIGN openssl
+ $(NODEBUG) DEASSIGN ossl_sourceroot
.DEFAULT :
@ ! MMS cannot handle no actions...
# The main targets ###################################################
-{- dependmagic('build_sw'); -} : build_libs_nodep, build_modules_nodep, build_programs_nodep copy-utils
+{- dependmagic('build_sw'); -} : build_libs_nodep, build_modules_nodep, build_programs_nodep
{- dependmagic('build_libs'); -} : build_libs_nodep
{- dependmagic('build_modules'); -} : build_modules_nodep
{- dependmagic('build_programs'); -} : build_programs_nodep
all : build_sw build_docs
test : tests
-{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep copy-utils run_tests
+{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep run_tests
run_tests :
@ ! {- output_off() if $disabled{tests}; "" -}
DEFINE SRCTOP "$(SRCDIR)"
@ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options"
@ ! {- output_on() if !$disabled{tests}; "" -}
-install : install_sw install_ssldirs install_docs install_msg
+install : install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -} install_msg
install_msg :
@ WRITE SYS$OUTPUT ""
check_install :
spawn/nolog @ossl_installroot:[SYSTEST]openssl_ivp{- $osslver -}.com
-uninstall : uninstall_docs uninstall_sw
+uninstall : uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
# Because VMS wants the generation number (or *) to delete files, we can't
# use $(LIBS), $(PROGRAMS), $(GENERATED) and $(MODULES) directly.
- DELETE []vmsconfig.pm;*
distclean : clean
+ - DELETE [.include.openssl]configuration.h;*
- DELETE configdata.pm;*
- DELETE descrip.mms;*
depend : descrip.mms
-descrip.mms : FORCE
@ ! {- output_off() if $disabled{makedepend}; "" -}
@ $(PERL) {- sourcefile("util", "add-depends.pl") -} "{- $config{makedep_scheme} -}"
@ ! {- output_on() if $disabled{makedepend}; "" -}
uninstall_docs : uninstall_html_docs
-install_fips : install_sw
+{- output_off() if $disabled{fips}; "" -}
+install_fips : build_sw $(INSTALL_FIPSMODULECONF)
+ @ WRITE SYS$OUTPUT "*** Installing FIPS module"
+ - CREATE/DIR ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']
+ - CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[000000]
+ COPY/PROT=W:RE $(INSTALL_FIPSMODULES) -
+ ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']$(FIPSMODULENAME)
@ WRITE SYS$OUTPUT "*** Installing FIPS module configuration"
- @ WRITE SYS$OUTPUT "fipsinstall $(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).cnf"
- openssl fipsinstall -
- -module ossl_installroot:[MODULES{- $sover_dirname.$target{pointer_size} -}.'arch']$(FIPSMODULENAME) -
- -out ossl_installroot:[MODULES{- $sover_dirname.$target{pointer_size} -}.'arch']$(FIPSMODULENAME).cnf -
- -macopt "hexkey:$(FIPSKEY)"
+ COPY/PROT=W:RE $(INSTALL_FIPSMODULECONF) OSSL_DATAROOT:[000000]
-uninstall_fips : uninstall_sw
+uninstall_fips :
@ WRITE SYS$OUTPUT "*** Uninstalling FIPS module configuration"
- DELETE ossl_installroot:[MODULES{- $sover_dirname.$target{pointer_size} -}.'arch']$(FIPSMODULENAME).cnf;*
+ DELETE OSSL_DATAROOT:[000000]fipsmodule.cnf;*
+ @ WRITE SYS$OUTPUT "*** Uninstalling FIPS module"
+ DELETE ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']$(FIPSMODULENAME);*
+{- output_on() if $disabled{fips}; "" -}
install_ssldirs : check_INSTALLTOP
- CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[000000]
@ WRITE SYS$OUTPUT "*** Installing development files"
@ ! Install header files
- CREATE/DIR ossl_installroot:[include.openssl]
- COPY/PROT=W:R openssl:*.h ossl_installroot:[include.openssl]
+ COPY/PROT=W:R ossl_sourceroot:[include.openssl]*.h -
+ ossl_installroot:[include.openssl]
+ COPY/PROT=W:R [.include.openssl]*.h ossl_installroot:[include.openssl]
@ ! Install static (development) libraries
- CREATE/DIR ossl_installroot:[LIB.'arch']
{- join("\n ",
install_modules : check_INSTALLTOP install_runtime_libs build_modules
@ {- output_off() unless scalar @install_modules; "" -} !
@ WRITE SYS$OUTPUT "*** Installing modules"
- - CREATE/DIR ossl_installroot:[MODULES{- $sover_dirname.$target{pointer_size} -}.'arch']
+ - CREATE/DIR ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']
{- join("\n ",
- map { "COPY/PROT=W:RE $_.EXE ossl_installroot:[MODULES$sover_dirname$target{pointer_size}.'arch']" }
+ map { "COPY/PROT=W:RE $_.EXE ossl_installroot:[MODULES$target{pointer_size}.'arch']" }
@install_modules) -}
@ {- output_on() unless scalar @install_modules; "" -} !
@ IF "$(INSTALLTOP)" .EQS. "" THEN -
EXIT %x10000002
-# Helper targets #####################################################
-
-copy-utils : [.util]wrap.pl
-
-[.util]wrap.pl : configdata.pm
- @ IF "$(SRCDIR)" .NES. "$(BLDDIR)" THEN -
- CREATE/DIR/LOG [.util]
- @ IF "$(SRCDIR)" .NES. "$(BLDDIR)" THEN -
- COPY/LOG ossl_sourceroot:[util]wrap.pl [.util]
-
# Developer targets ##################################################
debug_logicals :
# Building targets ###################################################
-configdata.pm : $(SRCDIR)Configure $(SRCDIR)config.com {- join(" ", @{$config{build_file_templates}}, @{$config{build_infos}}, @{$config{conf_files}}) -}
+descrip.mms : configdata.pm {- join(" ", @{$config{build_file_templates}}) -}
+ perl configdata.pm
+ @ WRITE SYS$OUTPUT "*************************************************"
+ @ WRITE SYS$OUTPUT "*** ***"
+ @ WRITE SYS$OUTPUT "*** Please run the same mms command again ***"
+ @ WRITE SYS$OUTPUT "*** ***"
+ @ WRITE SYS$OUTPUT "*************************************************"
+ @ PIPE ( EXIT %X10000000 )
+
+configdata.pm : $(SRCDIR)Configure $(SRCDIR)config.com {- join(" ", @{$config{build_infos}}, @{$config{conf_files}}) -}
perl configdata.pm -r
@ WRITE SYS$OUTPUT "*************************************************"
@ WRITE SYS$OUTPUT "*** ***"
{-
use File::Basename;
use File::Spec::Functions qw/abs2rel rel2abs catfile catdir/;
+ use File::Spec::Unix;
+
+ # Helper function to convert dependencies in platform agnostic form to
+ # dependencies in platform form.
+ sub compute_platform_depends {
+ map { my $x = $_;
+
+ grep { $x eq $_ } @{$unified_info{programs}} and platform->bin($x)
+ or grep { $x eq $_ } @{$unified_info{modules}} and platform->dso($x)
+ or grep { $x eq $_ } @{$unified_info{libraries}} and platform->lib($x)
+ or platform->convertext($x); } @_;
+ }
# Helper function to figure out dependencies on libraries
# It takes a list of library names and outputs a list of dependencies
}
# Helper function to deal with inclusion directory specs.
- # We have to deal with two things:
- # 1. comma separation and no possibility of trailing comma
- # 2. no inclusion directories given at all
- # 3. long compiler command lines
- # To resolve 1, we need to iterate through the sources of inclusion
- # directories, and only add a comma when needed.
- # To resolve 2, we need to have a variable that will hold the whole
- # inclusion qualifier, or be the empty string if there are no inclusion
- # directories. That's the symbol 'qual_includes' that's used in CPPFLAGS
- # To resolve 3, we create a logical name TMP_INCLUDES: to hold the list
- # of inclusion directories.
+ # We're dealing with two issues:
+ # 1. A lot of include directory specs take up a lot of command line real
+ # estate, and the DCL command line is very limited (2KiB).
+ # 2. For optimal usage, include directory paths must be in Unix form,
+ # that's the only way the C compiler can merge multiple include paths
+ # in a sane way (we can stop worrying about 1.h including foo/2.h
+ # including ../3.h).
+ #
+ # To resolve 1, we need to create a file with include directory pragmas,
+ # and let the compiler use it with /FIRST_INCLUDE=.
+ # To resolve 2, we convert all include directory specs we get to Unix,
+ # with available File::Spec functions.
#
- # This function returns a list of two lists, one being the collection of
- # commands to execute before the compiler is called, and the other being
- # the collection of commands to execute after. It takes as arguments the
- # collection of strings to include as directory specs.
- sub includes {
- my @stuff = ( @_ );
- my @before = (
- 'qual_includes :=',
- );
- my @after = (
- 'DELETE/SYMBOL/LOCAL qual_includes',
- );
-
- if (scalar @stuff > 0) {
- push @before, 'tmp_includes := '.shift(@stuff);
- while (@stuff) {
- push @before, 'tmp_add := '.shift(@stuff);
- push @before, 'IF tmp_includes .NES. "" .AND. tmp_add .NES. "" THEN tmp_includes = tmp_includes + ","';
- push @before, 'tmp_includes = tmp_includes + tmp_add';
+ # We use CRC-24 from https://tools.ietf.org/html/rfc4880#section-6,
+ # reimplemented in Perl to get a workable and constant file name for each
+ # combination of include directory specs. It is assumed that the order of
+ # these directories don't matter.
+ #
+ # This function takes as input a list of include directories
+ # This function returns a list two things:
+ # 1. The file name to use with /FIRST_INCLUDE=
+ # 2. Text to insert into descrip.mms (may be the empty string)
+ sub crc24 {
+ my $input = shift;
+
+ my $init_value = 0x00B704CE;
+ my $poly_value = 0x01864CFB;
+
+ my $crc = $init_value;
+
+ foreach my $x (unpack ('C*', $input)) {
+ $crc ^= $x << 16;
+
+ for (my $i; $i < 8; $i++) {
+ $crc <<= 1;
+ if ($crc & 0x01000000) {
+ $crc ^= $poly_value;
+ }
}
- push @before, "IF tmp_includes .NES. \"\" THEN DEFINE tmp_includes 'tmp_includes'";
- push @before, 'IF tmp_includes .NES. "" THEN qual_includes := /INCLUDE=(tmp_includes:)';
- push @before, 'DELETE/SYMBOL/LOCAL tmp_includes';
- push @before, 'DELETE/SYMBOL/LOCAL tmp_add';
- push @after, 'DEASSIGN tmp_includes:'
}
- return ([ @before ], [ @after ]);
+ $crc &= 0xFFFFFF;
+
+ return $crc;
+ }
+ my %includefile_cache;
+ sub make_includefile {
+ my %dirs = map {
+ my $udir = make_unix_path(rel2abs($_));
+
+ $udir => 1;
+ } @_;
+ my @dirs = sort keys %dirs;
+ my $filename = sprintf 'incdirs_%x.h', crc24(join(',', @dirs));
+
+ if ($includefile_cache{$filename}) {
+ return ($filename, "");
+ }
+
+ my $scripture = <<"EOF";
+$filename :
+ open/write inc_output $filename
+EOF
+ foreach (@dirs) {
+ $scripture .= <<"EOF";
+ write inc_output "#pragma include_directory ""$_"""
+EOF
+ }
+ $scripture .= <<"EOF";
+ close inc_output
+EOF
+ $includefile_cache{$filename} = $scripture;
+
+ return ($filename, $scripture);
+ }
+
+ # On VMS, (some) header file directories include the files
+ # __DECC_INCLUDE_EPILOGUE.H and __DECC_INCLUDE_PROLOGUE.H.
+ # When header files are generated, and the build directory
+ # isn't the same as the source directory, these files must
+ # be copied alongside the generated header file, or their
+ # effect will be lost.
+ # We use the same include file cache as make_includefile
+ # to check if the scripture to copy these files has already
+ # been generated.
+ sub make_decc_include_files {
+ my $outd = shift;
+ my $ind = shift;
+
+ # If the build directory and the source directory are the
+ # same, there's no need to copy the prologue and epilogue
+ # files.
+ return ('') if $outd eq $ind;
+
+ my $outprologue = catfile($outd, '__DECC_INCLUDE_PROLOGUE.H');
+ my $outepilogue = catfile($outd, '__DECC_INCLUDE_EPILOGUE.H');
+ my $inprologue = catfile($ind, '__DECC_INCLUDE_PROLOGUE.H');
+ my $inepilogue = catfile($ind, '__DECC_INCLUDE_EPILOGUE.H');
+ my @filenames = ();
+ my $scripture = '';
+
+ if ($includefile_cache{$outprologue}) {
+ push @filenames, $outprologue;
+ } elsif (-f $inprologue) {
+ my $local_scripture .= <<"EOF";
+$outprologue : $inprologue
+ COPY $inprologue $outprologue
+EOF
+ $includefile_cache{$outprologue} = $local_scripture;
+
+ push @filenames, $outprologue;
+ $scripture .= $local_scripture;
+ }
+ if ($includefile_cache{$outepilogue}) {
+ push @filenames, $outepilogue;
+ } elsif (-f $inepilogue) {
+ my $local_scripture .= <<"EOF";
+$outepilogue : $inepilogue
+ COPY $inepilogue $outepilogue
+EOF
+ $includefile_cache{$outepilogue} = $local_scripture;
+
+ push @filenames, $outepilogue;
+ $scripture .= $local_scripture;
+ }
+
+ return (@filenames, $scripture);
}
sub generatetarget {
my %args = @_;
- my $deps = join(" ", @{$args{deps}});
+ my $deps = join(" ", compute_platform_depends(@{$args{deps}}));
return <<"EOF";
$args{target} : $deps
EOF
my $gen_args = join('', map { " $_" }
@{$args{generator}}[1..$#{$args{generator}}]);
my $gen_incs = join("", map { ' "-I'.$_.'"' } @{$args{generator_incs}});
- my $deps = join(", -\n\t\t", @{$args{generator_deps}}, @{$args{deps}});
+ my $deps = join(", -\n\t\t",
+ compute_platform_depends(@{$args{generator_deps}},
+ @{$args{deps}}));
if ($args{src} =~ /\.html$/) {
#
my $title = basename($args{src}, ".html");
my $pod = $gen0;
my $mkpod2html = sourcefile('util', 'mkpod2html.pl');
+ my $srcdoc = sourcedir('doc');
return <<"EOF";
$args{src} : $pod
- \$(PERL) $mkpod2html -i $pod -o \$\@ -t "$title" -r "\$(SRCDIR)/doc"
+ \$(PERL) $mkpod2html -i $pod -o \$\@ -t "$title" -r "$srcdoc"
EOF
} elsif ($args{src} =~ /\.(\d)$/) {
#
#
my $target = platform->def($args{src});
my $mkdef = sourcefile('util', 'mkdef.pl');
- my $ord_ver = $args{intent} eq 'lib' ? ' --version $(VERSION)' : '';
+ my $ord_ver = $args{intent} eq 'lib' ? ' --version $(VERSION_NUMBER)' : '';
my $ord_name =
$args{generator}->[1] || basename($args{product}, '.EXE');
my $case_insensitive =
? '' : ' --case-insensitive';
return <<"EOF";
$target : $gen0 $deps $mkdef
- \$(PERL) $mkdef$ord_ver --ordinals $gen0 --name $ord_name "--OS" "VMS"$case_insensitive > $target
+ \$(PERL) $mkdef$ord_ver --type $args{intent} --ordinals $gen0 --name $ord_name "--OS" "VMS"$case_insensitive > $target
EOF
} elsif (platform->isasm($args{src})) {
#
lib => "$lib_cflags $lib_cppflags",
dso => "$dso_cflags $dso_cppflags",
bin => "$bin_cflags $bin_cppflags" } -> {$args{intent}};
- my @incs_cmds = includes({ shlib => '$(LIB_INCLUDES)',
- lib => '$(LIB_INCLUDES)',
- dso => '$(DSO_INCLUDES)',
- bin => '$(BIN_INCLUDES)' } -> {$args{intent}},
- '$(CNF_INCLUDES)',
- '$(INCLUDES)',
- @{$args{incs}});
- my $incs_on = join("\n\t\@ ", @{$incs_cmds[0]}) || '!';
- my $incs_off = join("\n\t\@ ", @{$incs_cmds[1]}) || '!';
my $defs = join("", map { ",".$_ } @{$args{defs}});
my $target = platform->asm($args{src});
return <<"EOF";
$target : $gen0 $deps
$generator \$\@-S
- \@ $incs_on
\@ extradefines = "$defs"
PIPE \$(CPP) $cppflags \$\@-S | -
\$(PERL) -ne "/^#(\\s*line)?\\s*[0-9]+\\s+""/ or print" > \$\@-i
\@ DELETE/SYMBOL/LOCAL extradefines
- \@ $incs_off
RENAME \$\@-i \$\@
DELETE \$\@-S;
EOF
# Otherwise....
return <<"EOF";
$target : $gen0 $deps
- \@ $incs_on
\@ extradefines = "$defs"
$generator \$\@
\@ DELETE/SYMBOL/LOCAL extradefines
- \@ $incs_off
EOF
}
return <<"EOF";
$target : $gen0 $deps
- \@ $incs_on
\@ extradefines = "$defs"
- SHOW SYMBOL qual_includes
PIPE \$(CPP) $cppflags $gen0 | -
\$(PERL) "-ne" "/^#(\\s*line)?\\s*[0-9]+\\s+""/ or print" > \$\@
\@ DELETE/SYMBOL/LOCAL extradefines
- \@ $incs_off
EOF
} elsif ($gen0 =~ m|^.*\.in$|) {
#
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
rel2abs($config{builddir}));
- my @modules = ( 'configdata.pm',
- grep { $_ =~ m|\.pm$| } @{$args{deps}} );
- my %moduleincs = map { '"-I'.dirname($_).'"' => 1 } @modules;
- $deps = join(' ', $deps, @modules);
- @modules = map { '"-M'.basename($_, '.pm').'"' } @modules;
- my $modules = join(' ', '', sort keys %moduleincs, @modules);
+ my @perlmodules = ( 'configdata.pm',
+ grep { $_ =~ m|\.pm$| } @{$args{deps}} );
+ my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
+ my @decc_include_data
+ = make_decc_include_files(dirname($args{src}), dirname($gen0));
+ my $decc_include_scripture = pop @decc_include_data;
+ $deps = join(' ', $deps, @decc_include_data,
+ compute_platform_depends(@perlmodules));
+ @perlmodules = map { '"-M'.basename($_, '.pm').'"' } @perlmodules;
+ my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
+
return <<"EOF";
$args{src} : $gen0 $deps
- \$(PERL)$modules $dofile "-o$target{build_file}" $gen0$gen_args > \$\@
+ \$(PERL)$perlmodules $dofile "-o$target{build_file}" $gen0$gen_args > \$\@
+$decc_include_scripture
EOF
} elsif (grep { $_ eq $gen0 } @{$unified_info{programs}}) {
#
# Generic generator using OpenSSL programs
#
- # Redo $deps, because programs aren't expected to have deps of their
- # own. This is a little more tricky, though, because running programs
- # may have dependencies on all sorts of files, so we search through
- # our database of programs and modules to see if our dependencies
- # are one of those.
- $deps = join(' ', map { my $x = $_;
- if (grep { $x eq $_ }
- @{$unified_info{programs}}) {
- platform->bin($x);
- } elsif (grep { $x eq $_ }
- @{$unified_info{modules}}) {
- platform->dso($x);
- } else {
- $x;
- }
- } @{$args{deps}});
- # Also redo $gen0, to ensure that we have the proper extension
+ # Redo $gen0, to ensure that we have the proper extension
$gen0 = platform->bin($gen0);
return <<"EOF";
$args{src} : $gen0 $deps
- PIPE $gen0$gen_args > \$@
+ PIPE MCR $gen0$gen_args > \$@
EOF
} else {
#
my $depn = basename($dep);
my $srcs =
join(", ", map { abs2rel(rel2abs($_), rel2abs($forward)) } @srcs);
- my $before = $unified_info{before}->{$obj} || "\@ !";
- my $after = $unified_info{after}->{$obj} || "\@ !";
+ my $incextra = join(',', map { "\"$_\"" }
+ @{$unified_info{includes_extra}->{$obj}});
+ $incextra = "/INCLUDE=($incextra)" if $incextra;
my $cflags;
if ($args{attrs}->{noinst}) {
lib => $lib_cppflags,
dso => $dso_cppflags,
bin => $bin_cppflags } -> {$args{intent}};
+ $cflags .= $incextra;
my $defs = join("", map { ",".$_ } @{$args{defs}});
my $asflags = { shlib => $lib_asflags,
lib => $lib_asflags,
dso => $dso_asflags,
bin => $bin_asflags } -> {$args{intent}};
- my @incs_cmds = includes({ shlib => '$(LIB_INCLUDES)',
- lib => '$(LIB_INCLUDES)',
- dso => '$(DSO_INCLUDES)',
- bin => '$(BIN_INCLUDES)' } -> {$args{intent}},
- '$(INCLUDES)',
- map {
- file_name_is_absolute($_)
- ? $_ : catdir($backward,$_)
- } @{$args{incs}});
- my $incs_on = join("\n\t\@ ", @{$incs_cmds[0]}) || '!';
- my $incs_off = join("\n\t\@ ", @{$incs_cmds[1]}) || '!';
-
if ($srcs[0] =~ /\Q${asmext}\E$/) {
return <<"EOF";
$obj : $deps
- ${before}
SET DEFAULT $forward
\$(AS) $asflags \$(ASOUTFLAG)${objd}${objn} $srcs
SET DEFAULT $backward
- ${after}
- PURGE $obj
EOF
} elsif ($srcs[0] =~ /.S$/) {
return <<"EOF";
$obj : $deps
- ${before}
SET DEFAULT $forward
\@ $incs_on
\@ extradefines = "$defs"
\@ DELETE/SYMBOL/LOCAL extradefines
\@ $incs_off
SET DEFAULT $backward
- ${after}
\$(AS) $asflags \$(ASOUTFLAG)$obj $obj-asm
- PURGE $obj
EOF
}
+ my ($incdir_filename, $incdir_scripture) =
+ make_includefile(@{ { shlib => [ @lib_cppincludes ],
+ lib => [ @lib_cppincludes ],
+ dso => [ @dso_cppincludes ],
+ bin => [ @bin_cppincludes ] } -> {$args{intent}} },
+ @{$args{incs}});
+ $deps .= ", -\n\t\t$incdir_filename";
+ $cflags =
+ $target{cflag_incfirst}
+ . '"'.make_unix_path(rel2abs($incdir_filename)).'"'
+ . $cflags;
+
my $depbuild = $disabled{makedepend} ? ""
: " /MMS=(FILE=${depd}${depn},TARGET=$obj)";
return <<"EOF";
$obj : $deps
- ${before}
SET DEFAULT $forward
\@ $incs_on
\@ extradefines = "$defs"
\@ DELETE/SYMBOL/LOCAL extradefines
\@ $incs_off
SET DEFAULT $backward
- ${after}
- PURGE $obj
+$incdir_scripture
EOF
}
sub obj2shlib {
# previous line's file spec as default, so if no directory spec
# is present in the current line and the previous line has one that
# doesn't apply, you're in for a surprise.
+ # Furthermore, we collect all object files and static libraries in
+ # an explicit cluster, to make it clear to the linker that these files
+ # shall be processed before shareable images.
+ # The shareable images are used with /SELECTIVE, to avoid warnings of
+ # multiply defined symbols when the module object files override some
+ # symbols that are present in the shareable image.
my $write_opt1 =
- join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
- "WRITE OPT_FILE \"$x" } @objs).
- "\"";
+ join(",-\"\n\t",
+ "\@ WRITE OPT_FILE \"CLUSTER=_,,",
+ (map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
+ "\@ WRITE OPT_FILE \"$x" } @objs),
+ (map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
+ "\@ WRITE OPT_FILE \"$x/LIB" }
+ grep { $_->{lib} =~ m|\.OLB$| }
+ @deps))
+ ."\"";
my $write_opt2 =
- join("\n\t", map { my $x = $_->{lib} =~ /\[/
- ? $_->{lib} : "[]".$_->{lib};
- $x =~ s|(\.EXE)|$1/SHARE|;
- $x =~ s|(\.OLB)|$1/LIB|;
- "WRITE OPT_FILE \"$x\"" } @deps)
+ join("\n\t",
+ (map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
+ "\@ WRITE OPT_FILE \"$x/SHARE/SELECTIVE\"" }
+ grep { $_->{lib} =~ m|\.EXE$| }
+ @deps))
|| "\@ !";
return <<"EOF"
$dso : $deps
# is present in the current line and the previous line has one that
# doesn't apply, you're in for a surprise.
my $write_opt1 =
- join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
- "\@ WRITE OPT_FILE \"$x" } @objs).
- "\"";
+ "\@ WRITE OPT_FILE \"CASE_SENSITIVE=YES\"\n\t"
+ .join(",-\"\n\t",
+ "\@ WRITE OPT_FILE \"CLUSTER=_,,",
+ (map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
+ "\@ WRITE OPT_FILE \"$x" } @objs),
+ (map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
+ # Special hack to include the MAIN object module
+ # explicitly, if it's known that there is one.
+ # |incmain| is defined in the rule generation further
+ # down, with the necessary /INCLUDE=main option unless
+ # the program has been determined to have a main function
+ # already.
+ $_->{attrs}->{has_main}
+ ? "\@ WRITE OPT_FILE \"$x/LIB''incmain'"
+ : "\@ WRITE OPT_FILE \"$x/LIB" }
+ grep { $_->{lib} =~ m|\.OLB$| }
+ @deps))
+ ."\"";
my $write_opt2 =
- join("\n\t", "WRITE OPT_FILE \"CASE_SENSITIVE=YES\"",
- map { my @lines = ();
- use Data::Dumper;
- my $x = $_->{lib} =~ /\[/
- ? $_->{lib} : "[]".$_->{lib};
- if ($x =~ m|\.EXE$|) {
- push @lines, "\@ WRITE OPT_FILE \"$x/SHARE\"";
- } elsif ($x =~ m|\.OLB$|) {
- # Special hack to include the MAIN object
- # module explicitly. This will only be done
- # if there isn't a 'main' in the program's
- # object modules already.
- my $main = $_->{attrs}->{has_main}
- ? '/INCLUDE=main' : '';
- push @lines,
- "\@ IF nomain THEN WRITE OPT_FILE \"$x/LIB$main\"",
- "\@ IF .NOT. nomain THEN WRITE OPT_FILE \"$x/LIB\""
- }
- @lines
- } @deps)
+ join("\n\t",
+ (map { my $x = $_->{lib} =~ /\[/ ? $_->{lib} : "[]".$_->{lib};
+ "\@ WRITE OPT_FILE \"$x/SHARE/SELECTIVE\"" }
+ grep { $_->{lib} =~ m|\.EXE$| }
+ @deps))
|| "\@ !";
# The linking commands looks a bit complex, but it's for good reason.
# When you link, say, foo.obj, bar.obj and libsomething.exe/share, and
return <<"EOF"
$bin : $deps
$analyse_objs
+ @ incmain = "/INCLUDE=main"
+ @ IF .NOT. nomain THEN incmain = ""
@ OPEN/WRITE/SHARE=READ OPT_FILE $binname.OPT
$write_opt1
$write_opt2
"util", "dofile.pl")),
rel2abs($config{builddir}));
return <<"EOF";
-$script : $sources
+$script : $sources configdata.pm
\$(PERL) "-I\$(BLDDIR)" "-Mconfigdata" $dofile -
"-o$target{build_file}" $sources > $script
SET FILE/PROT=(S:RWED,O:RWED,G:RE,W:RE) $script