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