c975cb862fd8abde8d7d82724711cf6b5251c88d
[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           'aesni-mb-x86_64' => 'crypto/aes',
78           'sha1-mb-x86_64' => 'crypto/sha',
79           'sha256-mb-x86_64' => 'crypto/sha',
80           'ecp_nistz256-x86_64' => 'crypto/ec',
81           'wp-x86_64' => 'crypto/whrlpool',
82           'cmll-x86_64' => 'crypto/camellia',
83          );
84
85 # If I were feeling more clever, these could probably be extracted
86 # from makefiles.
87 sub platform_perlasm_compile_target
88         {
89         local($target, $source, $bname) = @_;
90
91         for $p (keys %perl1)
92                 {
93 # FIXME: export CC so rsaz-avx2 can test for it, since BSD make does
94 # not export variables, unlike GNU make. But this also requires fixing
95 # the .s.o rule to use CC!
96                 if ($target eq "\$(OBJ_D)/$p.o")
97                         {
98                         return << "EOF";
99 \$(TMP_D)/$p.s: $perl1{$p}/asm/$p.pl
100         \$(PERL) $perl1{$p}/asm/$p.pl \$(PERLASM_SCHEME) > \$@
101 EOF
102                         }
103                 }
104         if ($target eq '$(OBJ_D)/x86_64cpuid.o')
105                 {
106                 return << 'EOF';
107 $(TMP_D)/x86_64cpuid.s: crypto/x86_64cpuid.pl
108         $(PERL) crypto/x86_64cpuid.pl $(PERLASM_SCHEME) > $@
109 EOF
110                 }
111         elsif ($target eq '$(OBJ_D)/sha256-x86_64.o')
112                 {
113                 return << 'EOF';
114 $(TMP_D)/sha256-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
115         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
116 EOF
117                 }
118         elsif ($target eq '$(OBJ_D)/sha512-x86_64.o')
119                 {
120                 return << 'EOF';
121 $(TMP_D)/sha512-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
122         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
123 EOF
124                 }
125         elsif ($target eq '$(OBJ_D)/sha512-x86_64.o')
126                 {
127                 return << 'EOF';
128 $(TMP_D)/sha512-x86_64.s: crypto/sha/asm/sha512-x86_64.pl
129         $(PERL) crypto/sha/asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
130 EOF
131                 }
132
133         die $target;
134         }
135
136 sub special_compile_target
137         {
138         local($target) = @_;
139
140         if ($target eq 'crypto/bn/x86_64-gcc')
141                 {
142                 return << "EOF";
143 \$(TMP_D)/x86_64-gcc.o: crypto/bn/asm/x86_64-gcc.c
144         \$(CC) \$(LIB_CFLAGS) -c -o \$@ crypto/bn/asm/x86_64-gcc.c
145 EOF
146                 }
147         return undef;
148         }
149
150 sub do_lib_rule
151         {
152         local($obj,$target,$name,$shlib)=@_;
153         local($ret,$_,$Name);
154
155         $target =~ s/\//$o/g if $o ne '/';
156         $target="$target";
157         ($Name=$name) =~ tr/a-z/A-Z/;
158
159         $ret.="$target: \$(${Name}OBJ)\n";
160         $ret.="\t\$(RM) $target\n";
161         $ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
162         $ret.="\t\$(RANLIB) $target\n\n";
163         }
164
165 sub do_link_rule
166         {
167         local($target,$files,$dep_libs,$libs)=@_;
168         local($ret,$_);
169
170         $file =~ s/\//$o/g if $o ne '/';
171         $n=&bname($target);
172         $ret.="$target: $files $dep_libs\n";
173         $ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
174         return($ret);
175         }
176
177 sub which
178         {
179         my ($name)=@_;
180         my $path;
181         foreach $path (split /:/, $ENV{PATH})
182                 {
183                 if (-x "$path/$name")
184                         {
185                         return "$path/$name";
186                         }
187                 }
188         }
189
190 sub fixtests
191   {
192   my ($str, $tests) = @_;
193
194   foreach my $t (keys %$tests)
195     {
196     $str =~ s/(\.\/)?\$\($t\)/\$(TEST_D)\/$tests->{$t}/g;
197     }
198
199   return $str;
200   }
201
202 sub fixdeps
203   {
204   my ($str, $fakes) = @_;
205
206   my @t = split(/\s+/, $str);
207   $str = '';
208   foreach my $t (@t)
209     {
210     $str .= ' ' if $str ne '';
211     if (exists($fakes->{$t}))
212       {
213       $str .= $fakes->{$t};
214       next;
215       }
216     if ($t =~ /^[^\/]+$/)
217       {
218       $str .= '$(TEST_D)/' . $t;
219       }
220     else
221       {
222       $str .= $t;
223       }
224     }
225
226   return $str;
227   }
228
229 sub fixrules
230   {
231   my ($str) = @_;
232
233   # Compatible with -j...
234   $str =~ s/^(\s+@?)/$1cd \$(TEST_D) && /;
235   return $str;
236
237   # Compatible with not -j.
238   my @t = split("\n", $str);
239   $str = '';
240   my $prev;
241   foreach my $t (@t)
242     {
243     $t =~ s/^\s+//;
244     if (!$prev)
245       {
246       if ($t =~ /^@/)
247         {
248         $t =~ s/^@/\@cd \$(TEST_D) && /;
249         }
250       elsif ($t !~ /^\s*#/)
251         {
252         $t = 'cd $(TEST_D) && ' . $t;
253         }
254       }
255     $str .= "\t$t\n";
256     $prev = $t =~/\\$/;
257     }
258   return $str;
259 }
260
261 sub copy_scripts
262   {
263   my ($sed, $src, @targets) = @_;
264
265   my $s = '';
266   foreach my $t (@targets)
267     {
268     # Copy first so we get file modes...
269     $s .= "\$(TEST_D)/$t: \$(SRC_D)/$src/$t\n\tcp \$(SRC_D)/$src/$t \$(TEST_D)/$t\n";
270     $s .= "\tsed -e 's/\\.\\.\\/apps/..\\/\$(OUT_D)/' -e 's/\\.\\.\\/util/..\\/\$(TEST_D)/' < \$(SRC_D)/$src/$t > \$(TEST_D)/$t\n" if $sed;
271     $s .= "\n";
272     }
273   return $s;
274   }
275
276 sub get_tests
277   {
278   my ($makefile) = @_;
279
280   open(M, $makefile) || die "Can't open $makefile: $!";
281   my %targets;
282   my %deps;
283   my %tests;
284   my %alltests;
285   my %fakes;
286   while (my $line = <M>)
287     {
288     chomp $line;
289     while ($line =~ /^(.*)\\$/)
290       {
291       $line = $1 . <M>;
292       }
293
294     if ($line =~ /^alltests:(.*)$/)
295       {
296       my @t = split(/\s+/, $1);
297       foreach my $t (@t)
298         {
299         $targets{$t} = '';
300         $alltests{$t} = undef;
301         }
302       }
303
304     if (($line =~ /^(?<t>\S+):(?<d>.*)$/ && exists $targets{$1})
305         || $line =~ /^(?<t>test_(ss|gen) .*):(?<d>.*)/)
306       {
307       my $t = $+{t};
308       my $d = $+{d};
309       # If there are multiple targets stupid FreeBSD make runs the
310       # rules once for each dependency that matches one of the
311       # targets. Running the same rule twice concurrently causes
312       # breakage, so replace with a fake target.
313       if ($t =~ /\s/)
314         {
315         ++$fake;
316         my @targets = split /\s+/, $t;
317         $t = "_fake$fake";
318         foreach my $f (@targets)
319           {
320           $fakes{$f} = $t;
321           }
322         }
323       $deps{$t} = $d;
324       $deps{$t} =~ s/#.*$//;
325       for (;;)
326         {
327         $line = <M>;
328         chomp $line;
329         last if $line eq '';
330         $targets{$t} .= "$line\n";
331         }
332       next;
333       }
334
335     if ($line =~ /^(\S+TEST)=\s*(\S+)$/)
336       {
337       $tests{$1} = $2;
338       next;
339       }
340     }
341
342   delete $alltests{test_jpake} if $no_jpake;
343   delete $targets{test_ige} if $no_ige;
344   delete $alltests{test_md2} if $no_md2;
345   delete $alltests{test_rc5} if $no_rc5;
346
347   my $tests;
348   foreach my $t (keys %tests)
349     {
350     $tests .= "$t = $tests{$t}\n";
351     }
352
353   my $each;
354   foreach my $t (keys %targets)
355     {
356     next if $t eq '';
357
358     my $d = $deps{$t};
359     $d =~ s/\.\.\/apps/\$(BIN_D)/g;
360     $d =~ s/\.\.\/util/\$(TEST_D)/g;
361     $d = fixtests($d, \%tests);
362     $d = fixdeps($d, \%fakes);
363
364     my $r = $targets{$t};
365     $r =~ s/\.\.\/apps/..\/\$(BIN_D)/g;
366     $r =~ s/\.\.\/util/..\/\$(TEST_D)/g;
367     $r =~ s/\.\.\/(\S+)/\$(SRC_D)\/$1/g;
368     $r = fixrules($r);
369
370     next if $r eq '';
371
372     $t =~ s/\s+/ \$(TEST_D)\//g;
373
374     $each .= "$t: test_scripts $d\n\t\@echo '$t test started'\n$r\t\@echo '$t test done'\n\n";
375     }
376
377   # FIXME: Might be a clever way to figure out what needs copying
378   my @copies = ( 'bctest',
379                  'testgen',
380                  'cms-test.pl',
381                  'tx509',
382                  'test.cnf',
383                  'testenc',
384                  'tocsp',
385                  'testca',
386                  'CAss.cnf',
387                  'testtsa',
388                  'CAtsa.cnf',
389                  'Uss.cnf',
390                  'P1ss.cnf',
391                  'P2ss.cnf',
392                  'tcrl',
393                  'tsid',
394                  'treq',
395                  'tpkcs7',
396                  'tpkcs7d',
397                  'testcrl.pem',
398                  'testx509.pem',
399                  'v3-cert1.pem',
400                  'v3-cert2.pem',
401                  'testreq2.pem',
402                  'testp7.pem',
403                  'pkcs7-1.pem',
404                  'trsa',
405                  'testrsa.pem',
406                  'testsid.pem',
407                  'testss',
408                  'testssl',
409                  'testsslproxy',
410                  'serverinfo.pem',
411                );
412   my $copies = copy_scripts(1, 'test', @copies);
413   $copies .= copy_scripts(0, 'test', ('smcont.txt'));
414
415   my @utils = ( 'shlib_wrap.sh',
416                 'opensslwrap.sh',
417               );
418   $copies .= copy_scripts(1, 'util', @utils);
419
420   my @apps = ( 'CA.sh',
421                'openssl.cnf',
422                'server2.pem',
423              );
424   $copies .= copy_scripts(1, 'apps', @apps);
425
426   $copies .= copy_scripts(1, 'crypto/evp', ('evptests.txt'));
427
428   $scripts = "test_scripts: \$(TEST_D)/CA.sh \$(TEST_D)/opensslwrap.sh \$(TEST_D)/openssl.cnf \$(TEST_D)/shlib_wrap.sh ocsp smime\n";
429   $scripts .= "\nocsp:\n\tcp -R test/ocsp-tests \$(TEST_D)\n";
430   $scripts .= "\smime:\n\tcp -R test/smime-certs \$(TEST_D)\n";
431
432   my $all = 'test:';
433   foreach my $t (keys %alltests)
434     {
435     if (exists($fakes{$t}))
436       {
437       $all .= " $fakes{$t}";
438       }
439     else
440       {
441       $all .= " $t";
442       }
443     }
444
445   return "$scripts\n$copies\n$tests\n$all\n\n$each";
446   }
447
448 1;