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