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