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