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