1## descrip.mms to build OpenSSL on OpenVMS
2##
3## {- join("\n## ", @autowarntext) -}
4{-
5  use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
6  use File::Basename;
7  use OpenSSL::Util;
8
9  (our $osslprefix_q = platform->osslprefix()) =~ s/\$/\\\$/;
10
11  our $sover_dirname = platform->shlib_version_as_filename();
12  our $osslver = sprintf "%02d", split(/\./, $config{version});
13
14  our $sourcedir = $config{sourcedir};
15  our $builddir = $config{builddir};
16  sub make_unix_path {
17      # Split the native path
18      (my $vol, my $dirs, my $file) = File::Spec->splitpath($_[0]);
19      my @dirs = File::Spec->splitdir($dirs);
20
21      # Reassemble it as a Unix path
22      $vol =~ s|:$||;
23      return File::Spec::Unix->catpath(
24          '', File::Spec::Unix->catdir('', $vol ? $vol : (), @dirs), $file);
25  }
26  sub sourcefile {
27      catfile($sourcedir, @_);
28  }
29  sub buildfile {
30      catfile($builddir, @_);
31  }
32  sub sourcedir {
33      catdir($sourcedir, @_);
34  }
35  sub builddir {
36      catdir($builddir, @_);
37  }
38  sub tree {
39      (my $x = shift) =~ s|\]$|...]|;
40      $x
41  }
42
43  # Because we need to make two computations of these data,
44  # we store them in arrays for reuse
45  our @libs =
46      map { platform->staticname($_) }
47      @{$unified_info{libraries}};
48  our @shlibs =
49      map { platform->sharedname($_) // () }
50      @{$unified_info{libraries}};
51  our @install_libs =
52      map { platform->staticname($_) }
53      grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
54      @{$unified_info{libraries}};
55  our @install_shlibs =
56      map { platform->sharedname($_) // () }
57      grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
58      @{$unified_info{libraries}};
59  our @install_engines =
60      grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
61             && $unified_info{attributes}->{modules}->{$_}->{engine} }
62      @{$unified_info{modules}};
63  our @install_modules =
64      grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
65             && !$unified_info{attributes}->{modules}->{$_}->{engine}
66             && !$unified_info{attributes}->{modules}->{$_}->{fips} }
67      @{$unified_info{modules}};
68  our @install_fipsmodules =
69      grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
70             && $unified_info{attributes}->{modules}->{$_}->{fips} }
71      @{$unified_info{modules}};
72  our @install_programs =
73      grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
74      @{$unified_info{programs}};
75  our @install_bin_scripts =
76      grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
77             && !$unified_info{attributes}->{scripts}->{$_}->{misc} }
78      @{$unified_info{scripts}};
79  our @install_misc_scripts =
80      grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
81             && $unified_info{attributes}->{scripts}->{$_}->{misc} }
82      @{$unified_info{scripts}};
83
84  # Configured flags
85
86  our @cnf_asflags = ($target{asflags} || (), @{$config{asflags}});
87  our @cnf_defines = (@{$target{defines}}, @{$config{defines}});
88  our @cnf_includes = (@{$target{includes}}, @{$config{includes}});
89  our @cnf_cppflags = ($target{cppflags} || (), @{$config{cppflags}});
90  our @cnf_cflags = ($target{cflags} || (), @{$config{cflags}});
91  our @cnf_cxxflags = ($target{cxxflags} || (), @{$config{cxxflags}});
92  our @cnf_ldflags = ($target{lflags} || (), @{$config{lflags}});
93  our @cnf_ex_libs = (map{ ",$_" } @{$target{ex_libs}}, @{$config{ex_libs}});
94
95  # Variables starting with $lib_ are used to build library object files
96  # and shared libraries.
97  # Variables starting with $dso_ are used to build DSOs and their object files.
98  # Variables starting with $bin_ are used to build programs and their object
99  # files.
100
101  # The following array is special and is treated separately from the rest of
102  # the lib_ variables.
103  our @lib_cppincludes = (@{$target{lib_includes}}, @{$target{shared_includes}},
104                          @{$config{lib_includes}}, @{$config{shared_includes}},
105                          @cnf_includes);
106
107  our $lib_cppdefines =
108      join(',', @{$target{lib_defines}}, @{$target{shared_defines}},
109                @{$config{lib_defines}}, @{$config{shared_defines}},
110                @cnf_defines,
111                'OPENSSLDIR="""$(OPENSSLDIR_C)"""',
112                'ENGINESDIR="""$(ENGINESDIR_C)"""',
113                'MODULESDIR="""$(MODULESDIR_C)"""'
114                )
115      . '$(DEFINES)'
116      . "'extradefines'";
117  our $lib_asflags =
118      join(' ', $target{lib_asflags} || (), @{$config{lib_asflags}},
119                @cnf_asflags, '$(ASFLAGS)');
120  our $lib_cppflags =
121      join('', $target{lib_cppflags} || (), $target{shared_cppflags} || (),
122               @{$config{lib_cppflags}}, @{$config{shared_cppflag}},
123               @cnf_cppflags, '/DEFINE=('.$lib_cppdefines.')', '$(CPPFLAGS)');
124  my @lib_cflags = ( $target{lib_cflags} // () );
125  my @lib_cflags_no_inst = ( $target{no_inst_lib_cflags} // @lib_cflags );
126  my @lib_cflags_cont = ( $target{shared_cflag} || (),
127                          @{$config{lib_cflags}}, @{$config{shared_cflag}},
128                          @cnf_cflags, '$(CFLAGS)');
129  our $lib_cflags = join('', @lib_cflags, @lib_cflags_cont );
130  our $lib_cflags_no_inst = join('', @lib_cflags_no_inst, @lib_cflags_cont );
131  our $lib_ldflags =
132      join('', $target{lib_lflags} || (), $target{shared_ldflag} || (),
133               @{$config{lib_lflags}}, @{$config{shared_ldflag}},
134               @cnf_ldflags, '$(LDFLAGS)');
135  our $lib_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
136
137  # The following array is special and is treated separately from the rest of
138  # the dso_ variables.
139  our @dso_cppincludes = (@{$target{dso_includes}}, @{$target{module_includes}},
140                          @{$config{dso_includes}}, @{$config{module_includes}},
141                          @cnf_includes);
142
143  our $dso_cppdefines =
144      join(',', @{$target{dso_defines}}, @{$target{module_defines}},
145                @{$config{dso_defines}}, @{$config{module_defines}},
146                @cnf_defines,
147                )
148      . '$(DEFINES)'
149      . "'extradefines'";
150  our $dso_asflags =
151      join(' ', $target{dso_asflags} || (), $target{module_asflags} || (),
152                @{$config{dso_asflags}}, @{$config{module_asflags}},
153                @cnf_asflags, '$(ASFLAGS)');
154  our $dso_cppflags =
155      join('', $target{dso_cppflags} || (), $target{module_cppflags} || (),
156               @{$config{dso_cppflags}}, @{$config{module_cppflag}},
157               @cnf_cppflags,
158               '/DEFINE=('.$dso_cppdefines.')',
159               '$(CPPFLAGS)');
160  my @dso_cflags = ( $target{dso_cflags} // () );
161  my @dso_cflags_no_inst = ( $target{no_inst_dso_cflags} // @dso_cflags );
162  my @dso_cflags_cont = ( $target{module_cflag} || (),
163                          @{$config{dso_cflags}}, @{$config{module_cflag}},
164                          @cnf_cflags, '$(CFLAGS)');
165  our $dso_cflags = join('', @dso_cflags, @dso_cflags_cont );
166  our $dso_cflags_no_inst = join('', @dso_cflags_no_inst, @dso_cflags_cont );
167  our $dso_ldflags =
168      join('', $target{dso_lflags} || (), $target{module_ldflag} || (),
169               @{$config{dso_lflags}}, @{$config{module_ldflag}},
170               @cnf_ldflags, '$(LDFLAGS)');
171  our $dso_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
172
173  # The following array is special and is treated separately from the rest of
174  # the bin_ variables.
175  our @bin_cppincludes = (@{$target{bin_includes}},
176                          @{$config{bin_includes}},
177                          @cnf_includes);
178
179  our $bin_cppdefines =
180      join(',', @{$target{bin_defines}},
181                @{$config{bin_defines}},
182                @cnf_defines,
183                )
184      . '$(DEFINES)'
185      . "'extradefines'";
186  our $bin_asflags =
187      join(' ', $target{bin_asflags} || (),
188                @{$config{bin_asflags}},
189                @cnf_asflags, '$(ASFLAGS)');
190  our $bin_cppflags =
191      join('', $target{bin_cppflags} || (),
192               @{$config{bin_cppflags}},
193               @cnf_cppflags,
194               '/DEFINE=('.$bin_cppdefines.')',
195               '$(CPPFLAGS)');
196  my @bin_cflags = ( $target{bin_cflags} // () );
197  my @bin_cflags_no_inst = ( $target{no_inst_bin_cflags} // @bin_cflags );
198  my @bin_cflags_cont = ( @{$config{bin_cflags}},
199                          @cnf_cflags, '$(CFLAGS)');
200  our $bin_cflags = join('', @bin_cflags, @bin_cflags_cont );
201  our $bin_cflags_no_inst = join('', @bin_cflags_no_inst, @bin_cflags_cont );
202  our $bin_ldflags =
203      join('', $target{bin_lflags} || (),
204               @{$config{bin_lflags}},
205               @cnf_ldflags, '$(LDFLAGS)');
206  our $bin_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
207
208  # This is a horrible hack, but is needed because recursive inclusion of files
209  # in different directories does not work well with VMS C.  We try to help by
210  # specifying extra relative directories.  They must always be in Unix format,
211  # relative to the directory where the .c file is located.  The logic is that
212  # any inclusion, merged with one of these relative directories, will find the
213  # requested inclusion file.
214  foreach (grep /\[\.crypto\.async\.arch\].*\.o$/, keys %{$unified_info{sources}}) {
215      my $obj = platform->obj($_);
216      push @{$unified_info{includes_extra}->{$obj}}, qw(../);
217  }
218  foreach (grep /\[\.crypto\.ec\.curve448\].*?\.o$/, keys %{$unified_info{sources}}) {
219      my $obj = platform->obj($_);
220      push @{$unified_info{includes_extra}->{$obj}}, qw(./arch_32 ./arch64);
221  }
222  foreach (grep /\[\.crypto\.ec\.curve448.arch_(?:32|64)\].*?\.o$/, keys %{$unified_info{sources}}) {
223      my $obj = platform->obj($_);
224      push @{$unified_info{includes_extra}->{$obj}}, qw(../);
225  }
226  foreach (grep /\[\.ssl\.(?:record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
227      my $obj = platform->obj($_);
228      # Most of the files in [.ssl.record] and [.ssl.statem] include
229      # "../ssl_local.h", which includes things like "record/record.h".
230      # Adding "../" as an inclusion directory helps making this sort of header
231      # from these directories.
232      push @{$unified_info{includes_extra}->{$obj}}, qw(../);
233
234  }
235  foreach (grep /\[\.test\].*?\.o$/, keys %{$unified_info{sources}}) {
236      my $obj = platform->obj($_);
237      push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl ./helpers);
238  }
239  foreach (grep /\[\.test\.helpers\].*?\.o$/, keys %{$unified_info{sources}}) {
240      my $obj = platform->obj($_);
241      push @{$unified_info{includes_extra}->{$obj}}, qw(../../ssl);
242  }
243
244  # This makes sure things get built in the order they need
245  # to. You're welcome.
246  sub dependmagic {
247      my $target = shift;
248
249      return "$target : build_generated\n\t\pipe \$(MMS) \$(MMSQUALIFIERS) depend && \$(MMS) \$(MMSQUALIFIERS) _$target\n_$target";
250  }
251  "";
252-}
253PLATFORM={- $config{target} -}
254OPTIONS={- $config{options} -}
255CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
256SRCDIR={- $config{sourcedir} -}
257BLDDIR={- $config{builddir} -}
258FIPSKEY={- $config{FIPSKEY} -}
259
260# Allow both V and VERBOSE to indicate verbosity.  This only applies
261# to testing.
262VERBOSE=$(V)
263VERBOSE_FAILURE=$(VF)
264
265VERSION={- "$config{full_version}" -}
266VERSION_NUMBER={- "$config{version}" -}
267MAJOR={- $config{major} -}
268MINOR={- $config{minor} -}
269SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
270SHLIB_TARGET={- $target{shared_target} -}
271
272LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @libs) -}
273SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @shlibs) -}
274MODULES={- join(", ", map { "-\n\t".$_.".EXE" }
275                      # Drop all modules that are dependencies, they will
276                      # be processed through their dependents
277                      grep { my $x = $_;
278                             !grep { grep { $_ eq $x } @$_ }
279                                   values %{$unified_info{depends}} }
280                      @{$unified_info{modules}}) -}
281FIPSMODULE={- # We do some extra checking here, as there should be only one
282              use File::Basename;
283              our @fipsmodules =
284                  grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
285                         && $unified_info{attributes}->{modules}->{$_}->{fips} }
286                  @{$unified_info{modules}};
287              die "More that one FIPS module" if scalar @fipsmodules > 1;
288              join(" ", map { platform->dso($_) } @fipsmodules) -}
289FIPSMODULENAME={- die "More that one FIPS module" if scalar @fipsmodules > 1;
290                  join(", ", map { basename(platform->dso($_)) } @fipsmodules) -}
291PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{programs}}) -}
292SCRIPTS={- join(", ", map { "-\n\t".$_ } @{$unified_info{scripts}}) -}
293{- output_off() if $disabled{makedepend}; "" -}
294DEPS={- our @deps = map { platform->isobj($_) ? platform->dep($_) : $_ }
295                    grep { $unified_info{sources}->{$_}->[0] =~ /\.c$/ }
296                    keys %{$unified_info{sources}};
297        join(", ", map { "-\n\t".$_ } @deps); -}
298{- output_on() if $disabled{makedepend}; "" -}
299GENERATED_MANDATORY={- join(", ",
300                            map { "-\n\t".$_ } @{$unified_info{depends}->{""}} ) -}
301GENERATED_PODS={- # common0.tmpl provides @generated
302                  join(", ",
303                       map { my $x = $_;
304                             (
305                               grep { 
306                                      $unified_info{attributes}->{depends}
307                                      ->{$x}->{$_}->{pod} // 0
308                                    }
309                                   keys %{$unified_info{attributes}->{depends}->{$x}}
310                             ) ? "-\n\t".$x : ();
311                           }
312                           @generated) -}
313GENERATED={- # common0.tmpl provides @generated
314             join(", ", map { platform->convertext($_) } @generated) -}
315
316INSTALL_LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @install_libs) -}
317INSTALL_SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @install_shlibs) -}
318INSTALL_ENGINES={- join(", ", map { "-\n\t".$_.".EXE" } @install_engines) -}
319INSTALL_MODULES={- join(", ", map { "-\n\t".$_.".EXE" } @install_modules) -}
320INSTALL_FIPSMODULE={- join(", ", map { "-\n\t".$_.".EXE" } @install_fipsmodules) -}
321INSTALL_FIPSMODULECONF=[.providers]fipsmodule.cnf
322INSTALL_PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @install_programs) -}
323BIN_SCRIPTS={- join(", ", @install_bin_scripts) -}
324MISC_SCRIPTS={- join(", ", @install_misc_scripts) -}
325HTMLDOCS1={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man1}}) -}
326HTMLDOCS3={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man3}}) -}
327HTMLDOCS5={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man5}}) -}
328HTMLDOCS7={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man7}}) -}
329
330APPS_OPENSSL="{- use File::Spec::Functions;
331                 catfile("apps","openssl") -}"
332
333# DESTDIR is for package builders so that they can configure for, say,
334# SYS$COMMON:[OPENSSL] and yet have everything installed in STAGING:[USER].
335# In that case, configure with --prefix=SYS$COMMON:[OPENSSL] and then run
336# MMS with /MACROS=(DESTDIR=STAGING:[USER]).  The result will end up in
337# STAGING:[USER.OPENSSL].
338# Normally it is left empty.
339DESTDIR=
340
341# Do not edit this manually. Use Configure --prefix=DIR to change this!
342INSTALLTOP={- our $installtop =
343                  catdir($config{prefix}) || "SYS\$COMMON:[OPENSSL]";
344              $installtop -}
345SYSTARTUP={- catdir($installtop, '[.SYS$STARTUP]'); -}
346# This is the standard central area to store certificates, private keys...
347OPENSSLDIR={- catdir($config{openssldir}) or
348              $config{prefix} ? catdir($config{prefix},"COMMON")
349                              : "SYS\$COMMON:[OPENSSL-COMMON]" -}
350# The same, but for C
351OPENSSLDIR_C={- platform->osslprefix() -}DATAROOT:[000000]
352# Where installed ENGINE modules reside, for C
353ENGINESDIR_C={- platform->osslprefix() -}ENGINES{- $sover_dirname.$target{pointer_size} -}:
354# Where modules reside, for C
355MODULESDIR_C={- platform->osslprefix() -}MODULES{- $target{pointer_size} -}:
356
357##### User defined commands and flags ################################
358
359CC={- $config{CC} -}
360CPP={- $config{CPP} -}
361DEFINES={- our $defines = join('', map { ",$_" } @{$config{CPPDEFINES}}) -}
362#INCLUDES={- our $includes = join(',', @{$config{CPPINCLUDES}}) -}
363CPPFLAGS={- our $cppflags = join('', @{$config{CPPFLAGS}}) -}
364CFLAGS={- join('', @{$config{CFLAGS}}) -}
365LDFLAGS={- join('', @{$config{LFLAGS}}) -}
366EX_LIBS={- join('', map { ",$_" } @{$config{LDLIBS}}) -}
367
368PERL={- $config{PERL} -}
369
370AS={- $config{AS} -}
371ASFLAGS={- join(' ', @{$config{ASFLAGS}}) -}
372
373##### Special command flags ##########################################
374
375ASOUTFLAG={- $target{asoutflag} -}$(OSSL_EMPTY)
376
377PERLASM_SCHEME={- $target{perlasm_scheme} -}
378
379# CPPFLAGS_Q is used for one thing only: to build up buildinf.h
380CPPFLAGS_Q={- (my $c = $lib_cppflags.$cppflags) =~ s|"|""|g;
381              (my $d = $lib_cppdefines) =~ s|"|""|g;
382              my $i = join(',', @lib_cppincludes || (), '$(INCLUDES)');
383              my $x = $c;
384              $x .= "/INCLUDE=($i)" if $i;
385              $x .= "/DEFINE=($d)" if $d;
386              $x; -}
387
388# .FIRST and .LAST are special targets with MMS and MMK.
389NODEBUG=@
390.FIRST :
391        {- join( "\n        \$(NODEBUG) ", @{ $target{setup_commands} // [] },
392                                           '!' ) -}
393        $(NODEBUG) sourcetop = F$PARSE("$(SRCDIR)","[]A.;",,,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;" + ".]"
394        $(NODEBUG) DEFINE ossl_sourceroot 'sourcetop'
395        $(NODEBUG) !
396        $(NODEBUG) staging_dir = "$(DESTDIR)"
397        $(NODEBUG) staging_instdir = ""
398        $(NODEBUG) staging_datadir = ""
399        $(NODEBUG) IF staging_dir .NES. "" THEN -
400                staging_instdir = F$PARSE("A.;",staging_dir,"[]",,"SYNTAX_ONLY")
401        $(NODEBUG) IF staging_instdir - "]A.;" .NES. staging_instdir THEN -
402                staging_instdir = staging_instdir - "]A.;" + ".OPENSSL-INSTALL]"
403        $(NODEBUG) IF staging_instdir - "A.;" .NES. staging_instdir THEN -
404                staging_instdir = staging_instdir - "A.;" + "[OPENSSL-INSTALL]"
405        $(NODEBUG) IF staging_dir .NES. "" THEN -
406                staging_datadir = F$PARSE("A.;",staging_dir,"[]",,"SYNTAX_ONLY")
407        $(NODEBUG) IF staging_datadir - "]A.;" .NES. staging_datadir THEN -
408                staging_datadir = staging_datadir - "]A.;" + ".OPENSSL-COMMON]"
409        $(NODEBUG) IF staging_datadir - "A.;" .NES. staging_datadir THEN -
410                staging_datadir = staging_datadir - "A.;" + "[OPENSSL-COMMON]"
411        $(NODEBUG) !
412        $(NODEBUG) ! Installation logical names
413        $(NODEBUG) !
414        $(NODEBUG) ! This also creates a few DCL variables that are used for
415        $(NODEBUG) ! the "install_msg" target.
416        $(NODEBUG) !
417        $(NODEBUG) installroot = F$PARSE(staging_instdir,"$(INSTALLTOP)","[]A.;",,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;"
418        $(NODEBUG) installtop = installroot + ".]"
419        $(NODEBUG) dataroot = F$PARSE(staging_datadir,"$(OPENSSLDIR)","[]A.;",,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;"
420        $(NODEBUG) datatop = dataroot + ".]"
421        $(NODEBUG) DEFINE ossl_installroot 'installtop'
422        $(NODEBUG) DEFINE ossl_dataroot 'datatop'
423        $(NODEBUG) !
424        $(NODEBUG) ! Override disturbing system logicals.  We can't deassign
425        $(NODEBUG) ! them, so we create it instead.  This is an unfortunate
426        $(NODEBUG) ! necessity.
427        $(NODEBUG) !
428        $(NODEBUG) openssl_inc1 = F$PARSE("[.include.openssl]","A.;",,,"syntax_only") - "A.;"
429        $(NODEBUG) openssl_inc2 = F$PARSE("sourcetop:[include.openssl]","A.;",,,"SYNTAX_ONLY") - "A.;"
430        $(NODEBUG) DEFINE openssl 'openssl_inc1','openssl_inc2'
431        $(NODEBUG) !
432        $(NODEBUG) ! Figure out the architecture
433        $(NODEBUG) !
434        $(NODEBUG) arch = f$edit( f$getsyi( "arch_name"), "upcase")
435        $(NODEBUG) !
436        $(NODEBUG) ! Set up logical names for the libraries, so LINK and
437        $(NODEBUG) ! running programs can use them.
438        $(NODEBUG) !
439        $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_)."\$(SHLIB_EXT)" } @shlibs) || "!" -}
440
441.LAST :
442        $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEASSIGN ".uc($_) } @shlibs) || "!" -}
443        $(NODEBUG) DEASSIGN openssl
444        $(NODEBUG) DEASSIGN ossl_dataroot
445        $(NODEBUG) DEASSIGN ossl_installroot
446        $(NODEBUG) DEASSIGN ossl_sourceroot
447.DEFAULT :
448        @ ! MMS cannot handle no actions...
449
450# The main targets ###################################################
451
452{- dependmagic('build_sw'); -} : build_libs_nodep, build_modules_nodep, build_programs_nodep
453{- dependmagic('build_libs'); -} : build_libs_nodep
454{- dependmagic('build_modules'); -} : build_modules_nodep
455{- dependmagic('build_programs'); -} : build_programs_nodep
456
457build_generated_pods : $(GENERATED_PODS)
458build_docs : build_html_docs
459build_html_docs : $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7)
460
461build_generated : $(GENERATED_MANDATORY)
462build_libs_nodep : $(LIBS), $(SHLIBS)
463build_modules_nodep : $(MODULES)
464build_programs_nodep : $(PROGRAMS), $(SCRIPTS)
465
466# Kept around for backward compatibility
467build_apps build_tests : build_programs
468
469# Convenience target to prebuild all generated files, not just the mandatory
470# ones
471build_all_generated : $(GENERATED_MANDATORY) $(GENERATED) build_docs
472	@ ! {- output_off() if $disabled{makedepend}; "" -}
473	@ WRITE SYS$OUTPUT "Warning: consider configuring with no-makedepend, because if"
474	@ WRITE SYS$OUTPUT "         target system doesn't have $(PERL),"
475	@ WRITE SYS$OUTPUT "         then make will fail..."
476	@ ! {- output_on() if $disabled{makedepend}; "" -}
477
478all : build_sw build_docs
479
480test : tests
481{- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep run_tests
482run_tests :
483        @ ! {- output_off() if $disabled{tests}; "" -}
484        DEFINE SRCTOP "$(SRCDIR)"
485        DEFINE BLDTOP "$(BLDDIR)"
486        DEFINE FIPSKEY "$(FIPSKEY)"
487        IF "$(VERBOSE)" .NES. "" THEN DEFINE VERBOSE "$(VERBOSE)"
488        $(PERL) {- sourcefile("test", "run_tests.pl") -} $(TESTS)
489        DEASSIGN BLDTOP
490        DEASSIGN SRCTOP
491        DEASSIGN FIPSKEY
492        @ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
493        @ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options"
494        @ ! {- output_on() if !$disabled{tests}; "" -}
495
496list-tests :
497        @ ! {- output_off() if $disabled{tests}; "" -}
498        @ DEFINE SRCTOP "$(SRCDIR)"
499        @ $(PERL) {- sourcefile("test", "run_tests.pl") -} list
500        @ DEASSIGN SRCTOP
501        @ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
502        @ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options"
503        @ ! {- output_on() if !$disabled{tests}; "" -}
504
505install : install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -} install_msg
506
507install_msg :
508        @ WRITE SYS$OUTPUT ""
509        @ WRITE SYS$OUTPUT "######################################################################"
510        @ WRITE SYS$OUTPUT ""
511        @ IF "$(DESTDIR)" .EQS. "" THEN -
512             @{- sourcefile("VMS", "msg_install.com") -} "$(SYSTARTUP)" "{- $osslver -}"
513        @ IF "$(DESTDIR)" .NES. "" THEN -
514             @{- sourcefile("VMS", "msg_staging.com") -} -
515             "''installroot']" "''dataroot']" "$(INSTALLTOP)" "$(OPENSSLDIR)" -
516             "$(SYSTARTUP)" "{- $osslver -}"
517
518check_install :
519        spawn/nolog @ossl_installroot:[SYSTEST]openssl_ivp{- $osslver -}.com
520
521uninstall : uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
522
523# Because VMS wants the generation number (or *) to delete files, we can't
524# use $(LIBS), $(PROGRAMS), $(GENERATED) and $(MODULES) directly.
525libclean :
526        {- join("\n\t", map { "- DELETE $_.OLB;*" } @libs) || "@ !" -}
527        {- join("\n\t", map { "- DELETE $_.EXE;*,$_.MAP;*" } @shlibs) || "@ !" -}
528
529clean : libclean
530        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man1}}) || "@ !" -}
531        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man3}}) || "@ !" -}
532        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man5}}) || "@ !" -}
533        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man7}}) || "@ !" -}
534        {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{programs}}) || "@ !" -}
535        {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{modules}}) || "@ !" -}
536        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{scripts}}) || "@ !" -}
537        {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{depends}->{""}}) || "@ !" -}
538        {- join("\n\t", map { "- DELETE $_;*" } @generated) || "@ !" -}
539        - DELETE [...]*.MAP;*
540        - DELETE [...]*.D;*
541        - DELETE [...]*.OBJ;*,*.LIS;*
542        - DELETE []CXX$DEMANGLER_DB.;*
543        - DELETE [.VMS]openssl_startup.com;*
544        - DELETE [.VMS]openssl_shutdown.com;*
545        - DELETE []vmsconfig.pm;*
546
547distclean : clean
548        - DELETE [.include.openssl]configuration.h;*
549        - DELETE configdata.pm;*
550        - DELETE descrip.mms;*
551
552depend : descrip.mms
553	@ ! {- output_off() if $disabled{makedepend}; "" -}
554	@ $(PERL) {- sourcefile("util", "add-depends.pl") -} "{- $config{makedep_scheme} -}"
555	@ ! {- output_on() if $disabled{makedepend}; "" -}
556
557# Install helper targets #############################################
558
559install_sw : install_dev install_engines install_modules -
560             install_runtime install_startup install_ivp
561
562uninstall_sw : uninstall_dev uninstall_modules uninstall_engines -
563               uninstall_runtime uninstall_startup uninstall_ivp
564
565install_docs : install_html_docs
566
567uninstall_docs : uninstall_html_docs
568
569{- output_off() if $disabled{fips}; "" -}
570install_fips : build_sw $(INSTALL_FIPSMODULECONF)
571	@ WRITE SYS$OUTPUT "*** Installing FIPS module"
572	- CREATE/DIR ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']
573	- CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[000000]
574	COPY/PROT=W:RE $(INSTALL_FIPSMODULES) -
575                ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']$(FIPSMODULENAME)
576	@ WRITE SYS$OUTPUT "*** Installing FIPS module configuration"
577	COPY/PROT=W:RE $(INSTALL_FIPSMODULECONF) OSSL_DATAROOT:[000000]
578
579uninstall_fips :
580	@ WRITE SYS$OUTPUT "*** Uninstalling FIPS module configuration"
581	DELETE OSSL_DATAROOT:[000000]fipsmodule.cnf;*
582	@ WRITE SYS$OUTPUT "*** Uninstalling FIPS module"
583	DELETE ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']$(FIPSMODULENAME);*
584{- output_on() if $disabled{fips}; "" -}
585
586install_ssldirs : check_INSTALLTOP
587        - CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[000000]
588        IF F$SEARCH("OSSL_DATAROOT:[000000]CERTS.DIR;1") .EQS. "" THEN -
589                CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[CERTS]
590        IF F$SEARCH("OSSL_DATAROOT:[000000]PRIVATE.DIR;1") .EQS. "" THEN -
591                CREATE/DIR/PROT=(S:RWED,O:RWE,G,W) OSSL_DATAROOT:[PRIVATE]
592        IF F$SEARCH("OSSL_DATAROOT:[000000]MISC.DIR;1") .EQS. "" THEN -
593                CREATE/DIR/PROT=(S:RWED,O:RWE,G,W) OSSL_DATAROOT:[MISC]
594        COPY/PROT=W:RE $(MISC_SCRIPTS) OSSL_DATAROOT:[MISC]
595        @ ! Install configuration file
596        COPY/PROT=W:R {- sourcefile("apps", "openssl-vms.cnf") -} -
597                ossl_dataroot:[000000]openssl.cnf-dist
598        IF F$SEARCH("OSSL_DATAROOT:[000000]openssl.cnf") .EQS. "" THEN -
599                COPY/PROT=W:R {- sourcefile("apps", "openssl-vms.cnf") -} -
600                        ossl_dataroot:[000000]openssl.cnf
601        @ ! Install CTLOG configuration file
602        COPY/PROT=W:R {- sourcefile("apps", "ct_log_list.cnf") -} -
603                ossl_dataroot:[000000]ct_log_list.cnf-dist
604        IF F$SEARCH("OSSL_DATAROOT:[000000]ct_log_list.cnf") .EQS. "" THEN -
605                COPY/PROT=W:R {- sourcefile("apps", "ct_log_list.cnf") -} -
606                        ossl_dataroot:[000000]ct_log_list.cnf
607
608install_dev : check_INSTALLTOP install_runtime_libs
609        @ WRITE SYS$OUTPUT "*** Installing development files"
610        @ ! Install header files
611        - CREATE/DIR ossl_installroot:[include.openssl]
612        COPY/PROT=W:R ossl_sourceroot:[include.openssl]*.h -
613                ossl_installroot:[include.openssl]
614        COPY/PROT=W:R [.include.openssl]*.h ossl_installroot:[include.openssl]
615        @ ! Install static (development) libraries
616        - CREATE/DIR ossl_installroot:[LIB.'arch']
617        {- join("\n        ",
618                map { "COPY/PROT=W:R $_.OLB ossl_installroot:[LIB.'arch']" }
619                @install_libs) -}
620
621install_engines : check_INSTALLTOP install_runtime_libs build_modules
622        @ {- output_off() unless scalar @install_engines; "" -} !
623        @ WRITE SYS$OUTPUT "*** Installing engines"
624        - CREATE/DIR ossl_installroot:[ENGINES{- $sover_dirname.$target{pointer_size} -}.'arch']
625        {- join("\n        ",
626                map { "COPY/PROT=W:RE $_.EXE ossl_installroot:[ENGINES$sover_dirname$target{pointer_size}.'arch']" }
627                @install_engines) -}
628        @ {- output_on() unless scalar @install_engines; "" -} !
629
630install_modules : check_INSTALLTOP install_runtime_libs build_modules
631        @ {- output_off() unless scalar @install_modules; "" -} !
632        @ WRITE SYS$OUTPUT "*** Installing modules"
633        - CREATE/DIR ossl_installroot:[MODULES{- $target{pointer_size} -}.'arch']
634        {- join("\n        ",
635                map { "COPY/PROT=W:RE $_.EXE ossl_installroot:[MODULES$target{pointer_size}.'arch']" }
636                @install_modules) -}
637        @ {- output_on() unless scalar @install_modules; "" -} !
638
639install_runtime : install_programs
640
641install_runtime_libs : check_INSTALLTOP build_libs
642        @ {- output_off() if $disabled{shared}; "" -} !
643        @ WRITE SYS$OUTPUT "*** Installing shareable images"
644        @ ! Install shared (runtime) libraries
645        - CREATE/DIR ossl_installroot:[LIB.'arch']
646        {- join("\n        ",
647                map { "COPY/PROT=W:R $_.EXE ossl_installroot:[LIB.'arch']" }
648                @install_shlibs) -}
649        @ {- output_on() if $disabled{shared}; "" -} !
650
651install_programs : check_INSTALLTOP install_runtime_libs build_programs
652        @ {- output_off() if $disabled{apps}; "" -} !
653        @ ! Install the main program
654        - CREATE/DIR ossl_installroot:[EXE.'arch']
655        COPY/PROT=W:RE [.APPS]openssl.EXE -
656                ossl_installroot:[EXE.'arch']openssl{- $osslver -}.EXE
657        @ ! Install scripts
658        COPY/PROT=W:RE $(BIN_SCRIPTS) ossl_installroot:[EXE]
659        @ ! {- output_on() if $disabled{apps}; "" -}
660
661install_startup : [.VMS]openssl_startup.com [.VMS]openssl_shutdown.com -
662                 [.VMS]openssl_utils.com, check_INSTALLTOP
663        - CREATE/DIR ossl_installroot:[SYS$STARTUP]
664        COPY/PROT=W:RE [.VMS]openssl_startup.com -
665                ossl_installroot:[SYS$STARTUP]openssl_startup{- $osslver -}.com
666        COPY/PROT=W:RE [.VMS]openssl_shutdown.com -
667                ossl_installroot:[SYS$STARTUP]openssl_shutdown{- $osslver -}.com
668        COPY/PROT=W:RE [.VMS]openssl_utils.com -
669                ossl_installroot:[SYS$STARTUP]openssl_utils{- $osslver -}.com
670
671install_ivp : [.VMS]openssl_ivp.com check_INSTALLTOP
672        - CREATE/DIR ossl_installroot:[SYSTEST]
673        COPY/PROT=W:RE [.VMS]openssl_ivp.com -
674                ossl_installroot:[SYSTEST]openssl_ivp{- $osslver -}.com
675
676[.VMS]openssl_startup.com : vmsconfig.pm {- sourcefile("VMS", "openssl_startup.com.in") -}
677        - CREATE/DIR [.VMS]
678        $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} -
679                {- sourcefile("VMS", "openssl_startup.com.in") -} -
680                > [.VMS]openssl_startup.com
681
682[.VMS]openssl_utils.com : vmsconfig.pm {- sourcefile("VMS", "openssl_utils.com.in") -}
683        - CREATE/DIR [.VMS]
684        $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} -
685                {- sourcefile("VMS", "openssl_utils.com.in") -} -
686                > [.VMS]openssl_utils.com
687
688[.VMS]openssl_shutdown.com : vmsconfig.pm {- sourcefile("VMS", "openssl_shutdown.com.in") -}
689        - CREATE/DIR [.VMS]
690        $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} -
691                {- sourcefile("VMS", "openssl_shutdown.com.in") -} -
692                > [.VMS]openssl_shutdown.com
693
694[.VMS]openssl_ivp.com : vmsconfig.pm {- sourcefile("VMS", "openssl_ivp.com.in") -}
695        - CREATE/DIR [.VMS]
696        $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} -
697                {- sourcefile("VMS", "openssl_ivp.com.in") -} -
698                > [.VMS]openssl_ivp.com
699
700vmsconfig.pm : configdata.pm
701        OPEN/WRITE/SHARE=READ CONFIG []vmsconfig.pm
702        WRITE CONFIG "package vmsconfig;"
703        WRITE CONFIG "use strict; use warnings;"
704        WRITE CONFIG "use Exporter;"
705        WRITE CONFIG "our @ISA = qw(Exporter);"
706        WRITE CONFIG "our @EXPORT = qw(%config %target %withargs %unified_info %disabled);"
707        WRITE CONFIG "our %config = ("
708        WRITE CONFIG "  target => '","{- $config{target} -}","',"
709        WRITE CONFIG "  version => '","{- $config{version} -}","',"
710        WRITE CONFIG "  shlib_version => '","{- $config{shlib_version} -}","',"
711        WRITE CONFIG "  shlib_major => '","{- $config{shlib_major} -}","',"
712        WRITE CONFIG "  shlib_minor => '","{- $config{shlib_minor} -}","',"
713        WRITE CONFIG "  no_shared => '","{- $disabled{shared} -}","',"
714        WRITE CONFIG "  INSTALLTOP => '$(INSTALLTOP)',"
715        WRITE CONFIG "  OPENSSLDIR => '$(OPENSSLDIR)',"
716        WRITE CONFIG "  pointer_size => '","{- $target{pointer_size} -}","',"
717        WRITE CONFIG ");"
718        WRITE CONFIG "our %target = ();"
719        WRITE CONFIG "our %disabled = ();"
720        WRITE CONFIG "our %withargs = ();"
721        WRITE CONFIG "our %unified_info = ();"
722        WRITE CONFIG "1;"
723        CLOSE CONFIG
724
725install_html_docs : check_INSTALLTOP build_html_docs
726        @ WRITE SYS$OUTPUT "*** Installing HTML docs"
727        - CREATE/DIR ossl_installroot:[HTML.MAN1]
728        - CREATE/DIR ossl_installroot:[HTML.MAN3]
729        - CREATE/DIR ossl_installroot:[HTML.MAN5]
730        - CREATE/DIR ossl_installroot:[HTML.MAN7]
731        {- join("\n        ",
732                ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN1]" }
733                  @{$unified_info{htmldocs}->{man1}} ),
734                ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN3]" }
735                  @{$unified_info{htmldocs}->{man3}} ),
736                ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN5]" }
737                  @{$unified_info{htmldocs}->{man5}} ),
738                ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN7]" }
739                  @{$unified_info{htmldocs}->{man7}} )) -}
740
741check_INSTALLTOP :
742        @ IF "$(INSTALLTOP)" .EQS. "" THEN -
743                WRITE SYS$ERROR "INSTALLTOP should not be empty"
744        @ IF "$(INSTALLTOP)" .EQS. "" THEN -
745                EXIT %x10000002
746
747# Developer targets ##################################################
748
749debug_logicals :
750        SH LOGICAL/PROC openssl,internal,ossl_installroot,ossl_dataroot
751
752# Building targets ###################################################
753
754descrip.mms : configdata.pm {- join(" ", @{$config{build_file_templates}}) -}
755	perl configdata.pm
756        @ WRITE SYS$OUTPUT "*************************************************"
757        @ WRITE SYS$OUTPUT "***                                           ***"
758        @ WRITE SYS$OUTPUT "***   Please run the same mms command again   ***"
759        @ WRITE SYS$OUTPUT "***                                           ***"
760        @ WRITE SYS$OUTPUT "*************************************************"
761        @ PIPE ( EXIT %X10000000 )
762
763configdata.pm : $(SRCDIR)Configure $(SRCDIR)config.com {- join(" ", @{$config{build_infos}}, @{$config{conf_files}}) -}
764        perl configdata.pm -r
765        @ WRITE SYS$OUTPUT "*************************************************"
766        @ WRITE SYS$OUTPUT "***                                           ***"
767        @ WRITE SYS$OUTPUT "***   Please run the same mms command again   ***"
768        @ WRITE SYS$OUTPUT "***                                           ***"
769        @ WRITE SYS$OUTPUT "*************************************************"
770        @ PIPE ( EXIT %X10000000 )
771
772reconfigure reconf :
773	perl configdata.pm -r
774
775{-
776  use File::Basename;
777  use File::Spec::Functions qw/abs2rel rel2abs catfile catdir/;
778  use File::Spec::Unix;
779
780  # Helper function to convert dependencies in platform agnostic form to
781  # dependencies in platform form.
782  sub compute_platform_depends {
783      map { my $x = $_;
784
785            grep { $x eq $_ } @{$unified_info{programs}} and platform->bin($x)
786            or grep { $x eq $_ } @{$unified_info{modules}} and platform->dso($x)
787            or grep { $x eq $_ } @{$unified_info{libraries}} and platform->lib($x)
788            or platform->convertext($x); } @_;
789  }
790
791  # Helper function to figure out dependencies on libraries
792  # It takes a list of library names and outputs a list of dependencies
793  sub compute_lib_depends {
794      # Depending on shared libraries:
795      # On Windows POSIX layers, we depend on {libname}.dll.a
796      # On Unix platforms, we depend on {shlibname}.so
797      return map {
798          { lib   => platform->sharedlib($_) // platform->staticlib($_),
799            attrs => $unified_info{attributes}->{libraries}->{$_} }
800      } @_;
801  }
802
803  # Helper function to deal with inclusion directory specs.
804  # We're dealing with two issues:
805  # 1. A lot of include directory specs take up a lot of command line real
806  #    estate, and the DCL command line is very limited (2KiB).
807  # 2. For optimal usage, include directory paths must be in Unix form,
808  #    that's the only way the C compiler can merge multiple include paths
809  #    in a sane way (we can stop worrying about 1.h including foo/2.h
810  #    including ../3.h).
811  #
812  # To resolve 1, we need to create a file with include directory pragmas,
813  # and let the compiler use it with /FIRST_INCLUDE=.
814  # To resolve 2, we convert all include directory specs we get to Unix,
815  # with available File::Spec functions.
816  #
817  # We use CRC-24 from https://tools.ietf.org/html/rfc4880#section-6,
818  # reimplemented in Perl to get a workable and constant file name for each
819  # combination of include directory specs.  It is assumed that the order of
820  # these directories don't matter.
821  #
822  # This function takes as input a list of include directories
823  # This function returns a list two things:
824  # 1. The file name to use with /FIRST_INCLUDE=
825  # 2. Text to insert into descrip.mms (may be the empty string)
826  sub crc24 {
827      my $input = shift;
828
829      my $init_value = 0x00B704CE;
830      my $poly_value = 0x01864CFB;
831
832      my $crc = $init_value;
833
834      foreach my $x (unpack ('C*', $input)) {
835          $crc ^= $x << 16;
836
837          for (my $i; $i < 8; $i++) {
838              $crc <<= 1;
839              if ($crc & 0x01000000) {
840                  $crc ^= $poly_value;
841              }
842          }
843      }
844      $crc &= 0xFFFFFF;
845
846      return $crc;
847  }
848  my %includefile_cache;
849  sub make_includefile {
850      my %dirs = map {
851          my $udir = make_unix_path(rel2abs($_));
852
853          $udir => 1;
854      } @_;
855      my @dirs = sort keys %dirs;
856      my $filename = sprintf 'incdirs_%x.h', crc24(join(',', @dirs));
857
858      if ($includefile_cache{$filename}) {
859          return ($filename, "");
860      }
861
862      my $scripture = <<"EOF";
863$filename :
864	open/write inc_output $filename
865EOF
866      foreach (@dirs) {
867          $scripture .= <<"EOF";
868	write inc_output "#pragma include_directory ""$_"""
869EOF
870      }
871      $scripture .= <<"EOF";
872	close inc_output
873EOF
874      $includefile_cache{$filename} = $scripture;
875
876      return ($filename, $scripture);
877  }
878
879  # On VMS, (some) header file directories include the files
880  # __DECC_INCLUDE_EPILOGUE.H and __DECC_INCLUDE_PROLOGUE.H.
881  # When header files are generated, and the build directory
882  # isn't the same as the source directory, these files must
883  # be copied alongside the generated header file, or their
884  # effect will be lost.
885  # We use the same include file cache as make_includefile
886  # to check if the scripture to copy these files has already
887  # been generated.
888  sub make_decc_include_files {
889      my $outd = shift;
890      my $ind = shift;
891
892      # If the build directory and the source directory are the
893      # same, there's no need to copy the prologue and epilogue
894      # files.
895      return ('') if $outd eq $ind;
896
897      my $outprologue = catfile($outd, '__DECC_INCLUDE_PROLOGUE.H');
898      my $outepilogue = catfile($outd, '__DECC_INCLUDE_EPILOGUE.H');
899      my $inprologue = catfile($ind, '__DECC_INCLUDE_PROLOGUE.H');
900      my $inepilogue = catfile($ind, '__DECC_INCLUDE_EPILOGUE.H');
901      my @filenames = ();
902      my $scripture = '';
903
904      if ($includefile_cache{$outprologue}) {
905          push @filenames, $outprologue;
906      } elsif (-f $inprologue) {
907          my $local_scripture .= <<"EOF";
908$outprologue : $inprologue
909	COPY $inprologue $outprologue
910EOF
911          $includefile_cache{$outprologue} = $local_scripture;
912
913          push @filenames, $outprologue;
914          $scripture .= $local_scripture;
915      }
916      if ($includefile_cache{$outepilogue}) {
917          push @filenames, $outepilogue;
918      } elsif (-f $inepilogue) {
919          my $local_scripture .= <<"EOF";
920$outepilogue : $inepilogue
921	COPY $inepilogue $outepilogue
922EOF
923          $includefile_cache{$outepilogue} = $local_scripture;
924
925          push @filenames, $outepilogue;
926          $scripture .= $local_scripture;
927      }
928
929      return (@filenames, $scripture);
930  }
931
932  sub generatetarget {
933      my %args = @_;
934      my $deps = join(" ", compute_platform_depends(@{$args{deps}}));
935      return <<"EOF";
936$args{target} : $deps
937EOF
938  }
939
940  sub generatesrc {
941      my %args = @_;
942      my $gen0 = $args{generator}->[0];
943      my $gen_args = join('', map { " $_" }
944                              @{$args{generator}}[1..$#{$args{generator}}]);
945      my $gen_incs = join("", map { ' "-I'.$_.'"' } @{$args{generator_incs}});
946      my $deps = join(", -\n\t\t",
947                      compute_platform_depends(@{$args{generator_deps}},
948                                               @{$args{deps}}));
949
950      if ($args{src} =~ /\.html$/) {
951          #
952          # HTML generator
953          #
954          my $title = basename($args{src}, ".html");
955          my $pod = $gen0;
956          my $mkpod2html = sourcefile('util', 'mkpod2html.pl');
957          my $srcdoc = sourcedir('doc');
958          return <<"EOF";
959$args{src} : $pod
960	\$(PERL) $mkpod2html -i $pod -o \$\@ -t "$title" -r "$srcdoc"
961EOF
962      } elsif ($args{src} =~ /\.(\d)$/) {
963          #
964          # Man-page generator, on VMS we simply ignore man-pages
965          #
966          return "";
967      } elsif (platform->isdef($args{src})) {
968          #
969          # Linker script-ish generator
970          #
971          my $target = platform->def($args{src});
972          my $mkdef = sourcefile('util', 'mkdef.pl');
973          my $ord_ver = $args{intent} eq 'lib' ? ' --version $(VERSION_NUMBER)' : '';
974          my $ord_name =
975              $args{generator}->[1] || basename($args{product}, '.EXE');
976          my $case_insensitive =
977              $target{$args{intent}.'_cflags'} =~ m|/NAMES=[^/]*AS_IS|i
978              ? '' : ' --case-insensitive';
979          return <<"EOF";
980$target : $gen0 $deps $mkdef
981	\$(PERL) $mkdef$ord_ver --type $args{intent} --ordinals $gen0 --name $ord_name "--OS" "VMS"$case_insensitive > $target
982EOF
983      } elsif (platform->isasm($args{src})
984               || platform->iscppasm($args{src})) {
985          #
986          # Assembler generator
987          #
988          my $cppflags =
989              { shlib => "$lib_cflags $lib_cppflags",
990                lib => "$lib_cflags $lib_cppflags",
991                dso => "$dso_cflags $dso_cppflags",
992                bin => "$bin_cflags $bin_cppflags" } -> {$args{intent}};
993          my $defs = join("", map { ",".$_ } @{$args{defs}});
994          my $target = platform->isasm($args{src})
995                       ? platform->asm($args{src})
996                       : $args{src};
997
998          my $generator;
999          if ($gen0 =~ /\.pl$/) {
1000              $generator = '$(PERL)'.$gen_incs.' '.$gen0.$gen_args
1001                  .' '.$cppflags;
1002          } elsif ($gen0 =~ /\.S$/) {
1003              $generator = undef;
1004          } else {
1005              die "Generator type for $src unknown: $gen0.$gen_args\n";
1006          }
1007
1008          if (defined($generator)) {
1009              return <<"EOF";
1010$target : $gen0 $deps
1011        \@ extradefines = "$defs"
1012	$generator \$\@
1013        \@ DELETE/SYMBOL/LOCAL extradefines
1014EOF
1015          }
1016          return <<"EOF";
1017$target : $gen0 $deps
1018        \@ extradefines = "$defs"
1019        PIPE \$(CPP) $cppflags $gen0 | -
1020        \$(PERL) "-ne" "/^#(\\s*line)?\\s*[0-9]+\\s+""/ or print" > \$\@
1021        \@ DELETE/SYMBOL/LOCAL extradefines
1022EOF
1023      } elsif ($gen0 =~ m|^.*\.in$|) {
1024          #
1025          # "dofile" generator (file.in -> file)
1026          #
1027          my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
1028                                               "util", "dofile.pl")),
1029                               rel2abs($config{builddir}));
1030          my @perlmodules = ( 'configdata.pm',
1031                              grep { $_ =~ m|\.pm$| } @{$args{deps}} );
1032          my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
1033          my @decc_include_data
1034              = make_decc_include_files(dirname($args{src}), dirname($gen0));
1035          my $decc_include_scripture = pop @decc_include_data;
1036          $deps = join(' ', $deps, @decc_include_data,
1037                            compute_platform_depends(@perlmodules));
1038          @perlmodules = map { '"-M'.basename($_, '.pm').'"' } @perlmodules;
1039          my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
1040
1041          return <<"EOF";
1042$args{src} : $gen0 $deps
1043	\$(PERL)$perlmodules $dofile "-o$target{build_file}" $gen0$gen_args > \$\@
1044$decc_include_scripture
1045EOF
1046      } elsif (grep { $_ eq $gen0 } @{$unified_info{programs}}) {
1047          #
1048          # Generic generator using OpenSSL programs
1049          #
1050
1051          # Redo $gen0, to ensure that we have the proper extension
1052          $gen0 = platform->bin($gen0);
1053          return <<"EOF";
1054$args{src} : $gen0 $deps
1055	PIPE MCR $gen0$gen_args > \$@
1056EOF
1057      } else {
1058          #
1059          # Generic generator using Perl
1060          #
1061          return <<"EOF";
1062$args{src} : $gen0 $deps
1063	\$(PERL)$gen_incs $gen0$gen_args > \$\@
1064EOF
1065      }
1066  }
1067
1068  sub src2obj {
1069      my $asmext = platform->asmext();
1070      my %args = @_;
1071      my @srcs =
1072          map { my $x = $_;
1073                (platform->isasm($x) && grep { $x eq $_ } @generated)
1074                ? platform->asm($x) : $x }
1075          ( @{$args{srcs}} );
1076      my $obj = platform->obj($args{obj});
1077      my $dep = platform->dep($args{obj});
1078      my $deps = join(", -\n\t\t", @srcs, @{$args{deps}});
1079
1080      # Because VMS C isn't very good at combining a /INCLUDE path with
1081      # #includes having a relative directory (like '#include "../foo.h"),
1082      # the best choice is to move to the first source file's intended
1083      # directory before compiling, and make sure to write the object file
1084      # in the correct position (important when the object tree is other
1085      # than the source tree).
1086      my $forward = dirname($args{srcs}->[0]);
1087      my $backward = abs2rel(rel2abs("."), rel2abs($forward));
1088      my $objd = abs2rel(rel2abs(dirname($obj)), rel2abs($forward));
1089      my $objn = basename($obj);
1090      my $depd = abs2rel(rel2abs(dirname($dep)), rel2abs($forward));
1091      my $depn = basename($dep);
1092      my $srcs =
1093          join(", ", map { abs2rel(rel2abs($_), rel2abs($forward)) } @srcs);
1094      my $incextra = join(',', map { "\"$_\"" }
1095                               @{$unified_info{includes_extra}->{$obj}});
1096      $incextra = "/INCLUDE=($incextra)" if $incextra;
1097
1098      my $cflags;
1099      if ($args{attrs}->{noinst}) {
1100          $cflags .= { shlib => $lib_cflags_no_inst,
1101                       lib => $lib_cflags_no_inst,
1102                       dso => $dso_cflags_no_inst,
1103                       bin => $bin_cflags_no_inst } -> {$args{intent}};
1104      } else {
1105          $cflags .= { shlib => $lib_cflags,
1106                       lib => $lib_cflags,
1107                       dso => $dso_cflags,
1108                       bin => $bin_cflags } -> {$args{intent}};
1109      }
1110      $cflags .= { shlib => $lib_cppflags,
1111		   lib => $lib_cppflags,
1112		   dso => $dso_cppflags,
1113		   bin => $bin_cppflags } -> {$args{intent}};
1114      $cflags .= $incextra;
1115      my $defs = join("", map { ",".$_ } @{$args{defs}});
1116      my $asflags = { shlib => $lib_asflags,
1117		      lib => $lib_asflags,
1118		      dso => $dso_asflags,
1119		      bin => $bin_asflags } -> {$args{intent}};
1120
1121      if ($srcs[0] =~ /\Q${asmext}\E$/) {
1122          return <<"EOF";
1123$obj : $deps
1124        SET DEFAULT $forward
1125        \$(AS) $asflags \$(ASOUTFLAG)${objd}${objn} $srcs
1126        SET DEFAULT $backward
1127        - PURGE $obj
1128EOF
1129      } elsif ($srcs[0] =~ /.S$/) {
1130         return <<"EOF";
1131$obj : $deps
1132        SET DEFAULT $forward
1133        \@ $incs_on
1134        \@ extradefines = "$defs"
1135        PIPE \$(CPP) ${cflags} $srcs | -
1136             \$(PERL) -ne "/^#(\\s*line)?\\s*[0-9]+\\s+""/ or print" -
1137             > ${objd}${objn}-asm
1138        \@ DELETE/SYMBOL/LOCAL extradefines
1139        \@ $incs_off
1140        SET DEFAULT $backward
1141        \$(AS) $asflags \$(ASOUTFLAG)$obj $obj-asm
1142        - PURGE $obj
1143EOF
1144      }
1145
1146      my ($incdir_filename, $incdir_scripture) =
1147          make_includefile(@{ { shlib => [ @lib_cppincludes ],
1148                                lib => [ @lib_cppincludes ],
1149                                dso => [ @dso_cppincludes ],
1150                                bin => [ @bin_cppincludes ] } -> {$args{intent}} },
1151                           @{$args{incs}});
1152      $deps .= ", -\n\t\t$incdir_filename";
1153      $cflags =
1154          $target{cflag_incfirst}
1155          . '"'.make_unix_path(rel2abs($incdir_filename)).'"'
1156          . $cflags;
1157
1158      my $depbuild = $disabled{makedepend} ? ""
1159          : " /MMS=(FILE=${depd}${depn},TARGET=$obj)";
1160
1161      return <<"EOF";
1162$obj : $deps
1163        SET DEFAULT $forward
1164        \@ $incs_on
1165        \@ extradefines = "$defs"
1166        \$(CC) ${cflags}${depbuild} /OBJECT=${objd}${objn} /REPOSITORY=$backward $srcs
1167        \@ DELETE/SYMBOL/LOCAL extradefines
1168        \@ $incs_off
1169        SET DEFAULT $backward
1170        - PURGE $obj
1171$incdir_scripture
1172EOF
1173  }
1174  sub obj2shlib {
1175      my %args = @_;
1176      my $shlibname = platform->sharedname($args{lib});
1177      my $shlib = platform->sharedlib($args{lib});
1178      my @objs = map { platform->convertext($_) }
1179                 grep { platform->isobj($_) }
1180                 @{$args{objs}};
1181      my @defs = map { platform->convertext($_) }
1182                 grep { platform->isdef($_) }
1183                 @{$args{objs}};
1184      my @deps = compute_lib_depends(@{$args{deps}});
1185      die "More than one symbol vector" if scalar @defs > 1;
1186      my $deps = join(", -\n\t\t", @objs, @defs, map { $_->{lib} } @deps);
1187      my $shlib_target = $disabled{shared} ? "" : $target{shared_target};
1188      my $translatesyms_pl = abs2rel(rel2abs(catfile($config{sourcedir},
1189                                                     "VMS", "translatesyms.pl")),
1190                                     rel2abs($config{builddir}));
1191      # The "[]" hack is because in .OPT files, each line inherits the
1192      # previous line's file spec as default, so if no directory spec
1193      # is present in the current line and the previous line has one that
1194      # doesn't apply, you're in for a surprise.
1195      my $write_opt1 =
1196          join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
1197                                 "WRITE OPT_FILE \"$x" } @objs).
1198          "\"";
1199      my $write_opt2 =
1200          join("\n\t", map { my $x = $_->{lib} =~ /\[/
1201                                 ? $_->{lib} : "[]".$_->{lib};
1202                             $x =~ s|(\.EXE)|$1/SHARE|;
1203                             $x =~ s|(\.OLB)|$1/LIB|;
1204                             "WRITE OPT_FILE \"$x\"" } @deps)
1205          || "\@ !";
1206      return <<"EOF"
1207$shlib : $deps
1208        \$(PERL) $translatesyms_pl \$(BLDDIR)CXX\$DEMANGLER_DB. < $defs[0] > $defs[0]-translated
1209        OPEN/WRITE/SHARE=READ OPT_FILE $shlibname-components.OPT
1210        $write_opt1
1211        $write_opt2
1212        CLOSE OPT_FILE
1213        LINK ${lib_ldflags}/SHARE=\$\@ $defs[0]-translated/OPT,-
1214                $shlibname-components.OPT/OPT \$(LIB_EX_LIBS)
1215        DELETE $defs[0]-translated;*,$shlibname-components.OPT;*
1216        PURGE $shlibname.EXE,$shlibname.MAP
1217EOF
1218        . ($config{target} =~ m|alpha| ? "" : <<"EOF"
1219        SET IMAGE/FLAGS=(NOCALL_DEBUG) \$\@
1220EOF
1221        );
1222  }
1223  sub obj2dso {
1224      my %args = @_;
1225      my $dsoname = platform->dsoname($args{module});
1226      my $dso = platform->dso($args{module});
1227      my @objs = map { platform->convertext($_) }
1228                 grep { platform->isobj($_) }
1229                 @{$args{objs}};
1230      my @defs = map { platform->convertext($_) }
1231                 grep { platform->isdef($_) }
1232                 @{$args{objs}};
1233      my @deps = compute_lib_depends(@{$args{deps}});
1234      my $deps = join(", -\n\t\t", @objs, @defs, map { $_->{lib} } @deps);
1235      die "More than one symbol vector" if scalar @defs > 1;
1236      my $shlib_target = $disabled{shared} ? "" : $target{shared_target};
1237      # The "[]" hack is because in .OPT files, each line inherits the
1238      # previous line's file spec as default, so if no directory spec
1239      # is present in the current line and the previous line has one that
1240      # doesn't apply, you're in for a surprise.
1241      my $write_opt1 =
1242          join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
1243                                 "WRITE OPT_FILE \"$x" } @objs).
1244          "\"";
1245      my $write_opt2 =
1246          join("\n\t", map { my $x = $_->{lib} =~ /\[/
1247                                 ? $_->{lib} : "[]".$_->{lib};
1248                             $x =~ s|(\.EXE)|$1/SHARE|;
1249                             $x =~ s|(\.OLB)|$1/LIB|;
1250                             "WRITE OPT_FILE \"$x\"" } @deps)
1251          || "\@ !";
1252      return <<"EOF"
1253$dso : $deps
1254        OPEN/WRITE/SHARE=READ OPT_FILE $dsoname-components.OPT
1255        $write_opt1
1256        $write_opt2
1257        CLOSE OPT_FILE
1258        LINK ${dso_ldflags}/SHARE=\$\@ $defs[0]/OPT,-
1259		$dsoname-components.OPT/OPT \$(DSO_EX_LIBS)
1260        - PURGE $dsoname.EXE,$dsoname.OPT,$dsoname.MAP
1261EOF
1262        . ($config{target} =~ m|alpha| ? "" : <<"EOF"
1263        SET IMAGE/FLAGS=(NOCALL_DEBUG) \$\@
1264EOF
1265        );
1266  }
1267  sub obj2lib {
1268      my %args = @_;
1269      my $lib = platform->staticlib($args{lib});
1270      my @objs = map { platform->convertext($_) }
1271                 grep { platform->isobj($_) }
1272                 @{$args{objs}};
1273      my $objs = join(", -\n\t\t", @objs);
1274      my $fill_lib = join("\n\t", (map { "LIBRARY/REPLACE $lib $_" } @objs));
1275      return <<"EOF";
1276$lib : $objs
1277        LIBRARY/CREATE/OBJECT $lib
1278        $fill_lib
1279        - PURGE $lib
1280EOF
1281  }
1282  sub obj2bin {
1283      my %args = @_;
1284      my $bin = platform->bin($args{bin});
1285      my $binname = platform->binname($args{bin});
1286      my @objs = map { platform->convertext($_) }
1287                 grep { platform->isobj($_) }
1288                 @{$args{objs}};
1289      my $objs = join(",", @objs);
1290      my @deps = compute_lib_depends(@{$args{deps}});
1291      my $deps = join(", -\n\t\t", @objs, map { $_->{lib} } @deps);
1292
1293      my $olb_count = scalar grep(m|\.OLB$|, map { $_->{lib} } @deps);
1294      my $analyse_objs = "@ !";
1295      if ($olb_count > 0) {
1296          my $analyse_quals =
1297              $config{target} =~ m|alpha| ? "/GSD" : "/SECTIONS=SYMTAB";
1298          $analyse_objs = "- pipe ANALYSE/OBJECT$analyse_quals $objs | SEARCH SYS\$INPUT \"\"\"main\"\"\" ; nomain = \$severity .NE. 1"
1299      }
1300      # The "[]" hack is because in .OPT files, each line inherits the
1301      # previous line's file spec as default, so if no directory spec
1302      # is present in the current line and the previous line has one that
1303      # doesn't apply, you're in for a surprise.
1304      my $write_opt1 =
1305          join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
1306                                 "\@ WRITE OPT_FILE \"$x" } @objs).
1307          "\"";
1308      my $write_opt2 =
1309          join("\n\t", "WRITE OPT_FILE \"CASE_SENSITIVE=YES\"",
1310                       map { my @lines = ();
1311                             use Data::Dumper;
1312                             my $x = $_->{lib} =~ /\[/
1313                                 ? $_->{lib} : "[]".$_->{lib};
1314                             if ($x =~ m|\.EXE$|) {
1315                                 push @lines, "\@ WRITE OPT_FILE \"$x/SHARE\"";
1316                             } elsif ($x =~ m|\.OLB$|) {
1317                                 # Special hack to include the MAIN object
1318                                 # module explicitly.  This will only be done
1319                                 # if there isn't a 'main' in the program's
1320                                 # object modules already.
1321                                 my $main = $_->{attrs}->{has_main}
1322                                     ? '/INCLUDE=main' : '';
1323                                 push @lines,
1324                                     "\@ IF nomain THEN WRITE OPT_FILE \"$x/LIB$main\"",
1325                                     "\@ IF .NOT. nomain THEN WRITE OPT_FILE \"$x/LIB\""
1326                             }
1327                             @lines
1328                           } @deps)
1329          || "\@ !";
1330      # The linking commands looks a bit complex, but it's for good reason.
1331      # When you link, say, foo.obj, bar.obj and libsomething.exe/share, and
1332      # bar.obj happens to have a symbol that also exists in libsomething.exe,
1333      # the linker will warn about it, loudly, and will then choose to pick
1334      # the first copy encountered (the one in bar.obj in this example).
1335      # On Unix and on Windows, the corresponding maneuver goes through
1336      # silently with the same effect.
1337      # With some test programs, made for checking the internals of OpenSSL,
1338      # we do this kind of linking deliberately, picking a few specific object
1339      # files from within [.crypto] or [.ssl] so we can reach symbols that are
1340      # otherwise unreachable (since the shareable images only exports the
1341      # symbols listed in [.util]*.num), and then with the shared libraries
1342      # themselves.  So we need to silence the warning about multiply defined
1343      # symbols, to mimic the way linking work on Unix and Windows, and so
1344      # the build isn't interrupted (MMS stops when warnings are signaled,
1345      # by default), and so someone building doesn't have to worry where it
1346      # isn't necessary.  If there are other warnings, however, we show them
1347      # and let it break the build.
1348      return <<"EOF"
1349$bin : $deps
1350        $analyse_objs
1351        @ OPEN/WRITE/SHARE=READ OPT_FILE $binname.OPT
1352        $write_opt1
1353        $write_opt2
1354        @ CLOSE OPT_FILE
1355        TYPE $binname.OPT ! For debugging
1356        - pipe SPAWN/WAIT/NOLOG/OUT=$binname.LINKLOG -
1357                    LINK ${bin_ldflags}/EXEC=\$\@ $binname.OPT/OPT \$(BIN_EX_LIBS) ; -
1358               link_status = \$status ; link_severity = link_status .AND. 7
1359        @ search_severity = 1
1360        -@ IF link_severity .EQ. 0 THEN -
1361                pipe SEARCH $binname.LINKLOG "%","-"/MATCH=AND | -
1362                     SPAWN/WAIT/NOLOG/OUT=NLA0: -
1363                          SEARCH SYS\$INPUT: "-W-MULDEF,"/MATCH=NOR ; -
1364                     search_severity = \$severity
1365        @ ! search_severity is 3 when the last search didn't find any matching
1366        @ ! string: %SEARCH-I-NOMATCHES, no strings matched
1367        @ ! If that was the result, we pretend linking got through without
1368        @ ! fault or warning.
1369        @ IF search_severity .EQ. 3 THEN link_severity = 1
1370        @ ! At this point, if link_severity shows that there was a fault
1371        @ ! or warning, make sure to restore the linking status.
1372        -@ IF .NOT. link_severity THEN TYPE $binname.LINKLOG
1373        -@ DELETE $binname.LINKLOG;*
1374        @ IF .NOT. link_severity THEN SPAWN/WAIT/NOLOG EXIT 'link_status'
1375        - PURGE $bin,$binname.OPT
1376EOF
1377      . ($config{target} =~ m|alpha| ? "" : <<"EOF"
1378        SET IMAGE/FLAGS=(NOCALL_DEBUG) \$\@
1379EOF
1380        );
1381  }
1382  sub in2script {
1383      my %args = @_;
1384      my $script = $args{script};
1385      return "" if grep { $_ eq $script } @{$args{sources}}; # No overwrite!
1386      my $sources = join(" ", @{$args{sources}});
1387      my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
1388                                           "util", "dofile.pl")),
1389                           rel2abs($config{builddir}));
1390      return <<"EOF";
1391$script : $sources configdata.pm
1392        \$(PERL) "-I\$(BLDDIR)" "-Mconfigdata" $dofile -
1393	    "-o$target{build_file}" $sources > $script
1394        SET FILE/PROT=(S:RWED,O:RWED,G:RE,W:RE) $script
1395        PURGE $script
1396EOF
1397  }
1398  ""    # Important!  This becomes part of the template result.
1399-}
1400