a15418705b4e75b637d4b96be9e89193861eba03
[oweals/openssl.git] / util / pl / unix.pl
1 #!/usr/local/bin/perl
2 #
3 # unix.pl - the standard unix makefile stuff.
4 #
5
6 $o='/';
7 $cp='/bin/cp';
8 $rm='/bin/rm -f';
9
10 # C compiler stuff
11
12 if ($gcc)
13         {
14         $cc='gcc';
15         if ($debug)
16                 { $cflags="-g2 -ggdb"; }
17         else
18                 { $cflags="-O3 -fomit-frame-pointer"; }
19         }
20 else
21         {
22         $cc='cc';
23         if ($debug)
24                 { $cflags="-g"; }
25         else
26                 { $cflags="-O"; }
27         }
28 $obj='.o';
29 $asm_suffix='.s';
30 $ofile='-o ';
31
32 # EXE linking stuff
33 $link='${CC}';
34 $lflags='${CFLAG}';
35 $efile='-o ';
36 $exep='';
37 $ex_libs="";
38
39 # static library stuff
40 $mklib='ar r';
41 $mlflags='';
42 $ranlib=&which("ranlib") or $ranlib="true";
43 $plib='lib';
44 $libp=".a";
45 $shlibp=".a";
46 $lfile='';
47
48 $asm='as';
49 $afile='-o ';
50 $bn_asm_obj="";
51 $bn_asm_src="";
52 $des_enc_obj="";
53 $des_enc_src="";
54 $bf_enc_obj="";
55 $bf_enc_src="";
56
57 %perl1 = (
58           'md5-x86_64' => 'crypto/md5',
59           'x86_64-mont' => 'crypto/bn',
60           'x86_64-mont5' => 'crypto/bn',
61           'x86_64-gf2m' => 'crypto/bn',
62           'modexp512-x86_64' => 'crypto/bn',
63           'aes-x86_64' => 'crypto/aes',
64           'vpaes-x86_64' => 'crypto/aes',
65           'bsaes-x86_64' => 'crypto/aes',
66           'aesni-x86_64' => 'crypto/aes',
67           'aesni-sha1-x86_64' => 'crypto/aes',
68           'sha1-x86_64' => 'crypto/sha',
69           'e_padlock-x86_64' => 'engines',
70           'rc4-x86_64' => 'crypto/rc4',
71           'rc4-md5-x86_64' => 'crypto/rc4',
72           'ghash-x86_64' => 'crypto/modes',
73           'aesni-gcm-x86_64' => 'crypto/modes',
74           'aesni-sha256-x86_64' => 'crypto/aes',
75           'rsaz-x86_64' => 'crypto/bn',
76           'rsaz-avx2' => 'crypto/bn',
77          );
78
79 # If I were feeling more clever, these could probably be extracted
80 # from makefiles.
81 sub platform_perlasm_compile_target
82         {
83         local($target, $source, $bname) = @_;
84
85         for $p (keys %perl1)
86                 {
87                 if ($target eq "\$(OBJ_D)/$p.o")
88                         {
89                         return << "EOF";
90 \$(TMP_D)/$p.s: $perl1{$p}/asm/$p.pl
91         \$(PERL) $perl1{$p}/asm/$p.pl \$(PERLASM_SCHEME) > \$@
92 EOF
93                         }
94                 }
95         if ($target eq '$(OBJ_D)/x86_64cpuid.o')
96                 {
97                 return << 'EOF';
98 $(TMP_D)/x86_64cpuid.s: crypto/x86_64cpuid.pl
99         $(PERL) crypto/x86_64cpuid.pl $(PERLASM_SCHEME) > $@
100 EOF
101                 }
102         elsif ($target eq '$(OBJ_D)/sha256-x86_64.o')
103                 {
104                 return << 'EOF';
105 $(TMP_D)/sha256-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
106         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
107 EOF
108                 }
109         elsif ($target eq '$(OBJ_D)/sha512-x86_64.o')
110                 {
111                 return << 'EOF';
112 $(TMP_D)/sha512-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
113         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
114 EOF
115                 }
116         elsif ($target eq '$(OBJ_D)/sha512-x86_64.o')
117                 {
118                 return << 'EOF';
119 $(TMP_D)/sha512-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
120         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
121 EOF
122                 }
123
124         die $target;
125         }
126
127 sub special_compile_target
128         {
129         local($target) = @_;
130
131         if ($target eq 'crypto/bn/x86_64-gcc')
132                 {
133                 return << "EOF";
134 \$(TMP_D)/x86_64-gcc.o: crypto/bn/asm/x86_64-gcc.c
135         \$(CC) \$(CFLAGS) -c -o \$@ crypto/bn/asm/x86_64-gcc.c
136 EOF
137                 }
138         return undef;
139         }
140
141 sub do_lib_rule
142         {
143         local($obj,$target,$name,$shlib)=@_;
144         local($ret,$_,$Name);
145
146         $target =~ s/\//$o/g if $o ne '/';
147         $target="$target";
148         ($Name=$name) =~ tr/a-z/A-Z/;
149
150         $ret.="$target: \$(${Name}OBJ)\n";
151         $ret.="\t\$(RM) $target\n";
152         $ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
153         $ret.="\t\$(RANLIB) $target\n\n";
154         }
155
156 sub do_link_rule
157         {
158         local($target,$files,$dep_libs,$libs)=@_;
159         local($ret,$_);
160
161         $file =~ s/\//$o/g if $o ne '/';
162         $n=&bname($target);
163         $ret.="$target: $files $dep_libs\n";
164         $ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
165         return($ret);
166         }
167
168 sub which
169         {
170         my ($name)=@_;
171         my $path;
172         foreach $path (split /:/, $ENV{PATH})
173                 {
174                 if (-x "$path/$name")
175                         {
176                         return "$path/$name";
177                         }
178                 }
179         }
180
181 sub fixtests
182   {
183   my ($str, $tests) = @_;
184
185   foreach my $t (keys %$tests)
186     {
187     $str =~ s/(\.\/)?\$\($t\)/\$(TEST_D)\/$tests->{$t}/g;
188     }
189
190   return $str;
191   }
192
193 sub fixdeps
194   {
195   my ($str, $fakes) = @_;
196
197   my @t = split(/\s+/, $str);
198   $str = '';
199   foreach my $t (@t)
200     {
201     $str .= ' ' if $str ne '';
202     if (exists($fakes->{$t}))
203       {
204       $str .= $fakes->{$t};
205       next;
206       }
207     if ($t =~ /^[^\/]+$/)
208       {
209       $str .= '$(TEST_D)/' . $t;
210       }
211     else
212       {
213       $str .= $t;
214       }
215     }
216
217   return $str;
218   }
219
220 sub fixrules
221   {
222   my ($str) = @_;
223
224   # Compatible with -j...
225   $str =~ s/^(\s+@?)/$1cd \$(TEST_D) && /;
226   return $str;
227
228   # Compatible with not -j.
229   my @t = split("\n", $str);
230   $str = '';
231   my $prev;
232   foreach my $t (@t)
233     {
234     $t =~ s/^\s+//;
235     if (!$prev)
236       {
237       if ($t =~ /^@/)
238         {
239         $t =~ s/^@/\@cd \$(TEST_D) && /;
240         }
241       elsif ($t !~ /^\s*#/)
242         {
243         $t = 'cd $(TEST_D) && ' . $t;
244         }
245       }
246     $str .= "\t$t\n";
247     $prev = $t =~/\\$/;
248     }
249   return $str;
250 }
251
252 sub copy_scripts
253   {
254   my ($sed, $src, @targets) = @_;
255
256   my $s = '';
257   foreach my $t (@targets)
258     {
259     # Copy first so we get file modes...
260     $s .= "\$(TEST_D)/$t: \$(SRC_D)/$src/$t\n\tcp \$(SRC_D)/$src/$t \$(TEST_D)/$t\n";
261     $s .= "\tsed -e 's/\\.\\.\\/apps/..\\/\$(OUT_D)/' -e 's/\\.\\.\\/util/..\\/\$(TEST_D)/' < \$(SRC_D)/$src/$t > \$(TEST_D)/$t\n" if $sed;
262     $s .= "\n";
263     }
264   return $s;
265   }
266
267 sub get_tests
268   {
269   my ($makefile) = @_;
270
271   open(M, $makefile) || die "Can't open $makefile: $!";
272   my %targets;
273   my %deps;
274   my %tests;
275   my %alltests;
276   my %fakes;
277   while (my $line = <M>)
278     {
279     chomp $line;
280     while ($line =~ /^(.*)\\$/)
281       {
282       $line = $1 . <M>;
283       }
284
285     if ($line =~ /^alltests:(.*)$/)
286       {
287       my @t = split(/\s+/, $1);
288       foreach my $t (@t)
289         {
290         $targets{$t} = '';
291         $alltests{$t} = undef;
292         }
293       }
294
295     if (($line =~ /^(?<t>\S+):(?<d>.*)$/ && exists $targets{$1})
296         || $line =~ /^(?<t>test_(ss|gen) .*):(?<d>.*)/)
297       {
298       my $t = $+{t};
299       my $d = $+{d};
300       # If there are multiple targets stupid FreeBSD make runs the
301       # rules once for each dependency that matches one of the
302       # targets. Running the same rule twice concurrently causes
303       # breakage, so replace with a fake target.
304       if ($t =~ /\s/)
305         {
306         ++$fake;
307         my @targets = split /\s+/, $t;
308         $t = "_fake$fake";
309         foreach my $f (@targets)
310           {
311           $fakes{$f} = $t;
312           }
313         }
314       $deps{$t} = $d;
315       $deps{$t} =~ s/#.*$//;
316       for (;;)
317         {
318         $line = <M>;
319         chomp $line;
320         last if $line eq '';
321         $targets{$t} .= "$line\n";
322         }
323       next;
324       }
325
326     if ($line =~ /^(\S+TEST)=\s*(\S+)$/)
327       {
328       $tests{$1} = $2;
329       next;
330       }
331     }
332
333   delete $alltests{test_jpake} if $no_jpake;
334   delete $targets{test_ige} if $no_ige;
335   delete $alltests{test_md2} if $no_md2;
336   delete $alltests{test_rc5} if $no_rc5;
337
338   my $tests;
339   foreach my $t (keys %tests)
340     {
341     $tests .= "$t = $tests{$t}\n";
342     }
343
344   my $each;
345   foreach my $t (keys %targets)
346     {
347     next if $t eq '';
348
349     my $d = $deps{$t};
350     $d =~ s/\.\.\/apps/\$(BIN_D)/g;
351     $d =~ s/\.\.\/util/\$(TEST_D)/g;
352     $d = fixtests($d, \%tests);
353     $d = fixdeps($d, \%fakes);
354
355     my $r = $targets{$t};
356     $r =~ s/\.\.\/apps/..\/\$(BIN_D)/g;
357     $r =~ s/\.\.\/util/..\/\$(TEST_D)/g;
358     $r =~ s/\.\.\/(\S+)/\$(SRC_D)\/$1/g;
359     $r = fixrules($r);
360
361     next if $r eq '';
362
363     $t =~ s/\s+/ \$(TEST_D)\//g;
364
365     $each .= "$t: test_scripts $d\n\t\@echo '$t test started'\n$r\t\@echo '$t test done'\n\n";
366     }
367
368   # FIXME: Might be a clever way to figure out what needs copying
369   my @copies = ( 'bctest',
370                  'testgen',
371                  'cms-test.pl',
372                  'tx509',
373                  'test.cnf',
374                  'testenc',
375                  'tocsp',
376                  'testca',
377                  'CAss.cnf',
378                  'testtsa',
379                  'CAtsa.cnf',
380                  'Uss.cnf',
381                  'P1ss.cnf',
382                  'P2ss.cnf',
383                  'tcrl',
384                  'tsid',
385                  'treq',
386                  'tpkcs7',
387                  'tpkcs7d',
388                  'testcrl.pem',
389                  'testx509.pem',
390                  'v3-cert1.pem',
391                  'v3-cert2.pem',
392                  'testreq2.pem',
393                  'testp7.pem',
394                  'pkcs7-1.pem',
395                  'trsa',
396                  'testrsa.pem',
397                  'testsid.pem',
398                  'testss',
399                  'testssl',
400                  'testsslproxy',
401                  'serverinfo.pem',
402                );
403   my $copies = copy_scripts(1, 'test', @copies);
404   $copies .= copy_scripts(0, 'test', ('smcont.txt'));
405
406   my @utils = ( 'shlib_wrap.sh',
407                 'opensslwrap.sh',
408               );
409   $copies .= copy_scripts(1, 'util', @utils);
410
411   my @apps = ( 'CA.sh',
412                'openssl.cnf',
413                'server2.pem',
414              );
415   $copies .= copy_scripts(1, 'apps', @apps);
416
417   $copies .= copy_scripts(1, 'crypto/evp', ('evptests.txt'));
418
419   $scripts = "test_scripts: \$(TEST_D)/CA.sh \$(TEST_D)/opensslwrap.sh \$(TEST_D)/openssl.cnf \$(TEST_D)/shlib_wrap.sh ocsp smime\n";
420   $scripts .= "\nocsp:\n\tcp -R test/ocsp-tests \$(TEST_D)\n";
421   $scripts .= "\smime:\n\tcp -R test/smime-certs \$(TEST_D)\n";
422
423   my $all = 'test:';
424   foreach my $t (keys %alltests)
425     {
426     if (exists($fakes{$t}))
427       {
428       $all .= " $fakes{$t}";
429       }
430     else
431       {
432       $all .= " $t";
433       }
434     }
435
436   return "$scripts\n$copies\n$tests\n$all\n\n$each";
437   }
438
439 1;