root/openpgpsdk/trunk/configure

Revision 298 (checked in by rachel, 8 years ago)

fixed path problem with ssl library

  • Property svn:executable set to *
Line 
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 use Carp;
6 use File::Temp;
7 use File::Spec;
8 use POSIX qw(:errno_h);
9 use IO::File;
10
11 $|=1;
12
13 our $Log;
14 our $LogFile='/dev/null';
15
16 sub trace {
17     return if !$Log;
18
19     $Log->seek(0,2);
20     print $Log join '',@_;
21 }
22
23 our %Subst=(
24             CRYPTO_LIBS => '-lcrypto',
25             ZLIB => '-lz',
26             INCLUDES => '',
27             CFLAGS => '',
28            );
29
30 my %Args=(
31           '--help' => \&usage,
32           '--use-dmalloc' => sub {
33               $Subst{DM_FLAGS}='-I/usr/local/include -DDMALLOC';
34               $Subst{DM_LIB}='/usr/local/lib/libdmalloc.a';
35           },
36           '--with-openssl=' => sub {
37               my $loc=shift;
38               $Subst{INCLUDES}.=" -I $loc/include";
39               $Subst{CRYPTO_LIBS}="$loc/lib/libcrypto.a";
40           },
41           '--with-zlib=' => sub {
42               my $loc=shift;
43               $Subst{INCLUDES}.=" -I $loc";
44               $Subst{ZLIB}="$loc/libz.a";
45           },
46           '--log=' => sub {
47               $LogFile=shift;
48               $Log=new IO::File(">$LogFile");
49               $Log->autoflush(1);
50           },
51           '--64' => sub {
52               $Subst{CFLAGS}.=' -m64';
53           },
54           '--maintainer' => sub {
55               $Subst{CFLAGS}.=' -fno-builtin';
56           },
57           '--cc=' => sub {
58               my $cc=shift;
59               $Subst{CC}=$cc;
60           }
61          );
62
63 my %Functions=(
64                'socket' => { headers => ['sys/types.h','sys/socket.h'],
65                              call => 'socket(0,0,0)',
66                              libs => [[],['socket','nsl']] },
67                );
68
69 my @Headers=qw(alloca.h);
70 my @Types=qw(time_t);
71 my @RHeaders=qw(openssl/bn.h zlib.h);
72
73 our %Knowledge=(
74                 cc => sub { return $Subst{CC} || chooseBinary('gcc','cc')
75                              || croak 'Can\'t find C compiler'; },
76                 path => sub { return [split /:/,$ENV{PATH}]; },
77                 time_t => sub { return typeInfo('time_t','time.h'); },
78                 base_cflags => \&baseCFlags,
79                 is_gcc => \&isGCC,
80                 gcc_major => \&gccMajor,
81                 gcc_version => \&gccVersion,
82               );
83
84 while(my $arg=shift) {
85     my $arg2;
86     if($arg =~ /^(.+=)(.+)$/) {
87         $arg=$1;
88         $arg2=$2;
89     }
90     my $code=$Args{$arg};
91     croak "Don't understand: $arg" if !defined $code;
92     &$code($arg2);
93 }
94
95 #my $os=`uname -s`;
96
97 $Subst{'CC'}=getKnowledge('cc');
98 $Subst{'CFLAGS'}.=' '.getKnowledge('base_cflags');
99
100 checkHeaders(\@RHeaders);
101
102 findHeaders(\@Headers);
103 investigateTypes(\@Types);
104 my $libs=findLibraries(\%Functions);
105 $Subst{'LIBS'}=join(' ',map { "-l$_" } @$libs);
106 #exit;
107
108 fixSubst();
109
110 create('src/.depend');
111 create('examples/.depend');
112
113 fileSubst('src/Makefile','#','');
114 fileSubst('examples/Makefile','#','');
115 fileSubst('include/openpgpsdk/configure.h','/*','*/');
116
117 print "make clean\n";
118 system 'make clean' || exit;
119 print "make force_depend\n";
120 if(system('make force_depend') != 0) {
121     print STDERR "Configuration failed\n";
122     exit 1;
123 }
124
125 sub subst {
126     my $line=shift;
127
128     while(my($k,$v)=each %Subst) {
129         $line =~ s/\%$k\%/$v/g;
130     }
131     $line =~ s/\%.+?\%//g;
132     return $line;
133 }
134
135 sub chooseBinary {
136     my $path=getKnowledge('path');
137     while(my $bin=shift) {
138         foreach my $p (@$path) {
139             return $bin if -x "$p/$bin";
140         }
141     }
142     return 'false';
143 }
144
145 sub getKnowledge {
146     my $thing=shift;
147
148     croak "Asked for nonexistent knowledge $thing"
149       if !exists $Knowledge{$thing};
150
151     if(ref $Knowledge{$thing} eq 'CODE') {
152         print "Finding $thing\n";
153         $Knowledge{$thing}=&{$Knowledge{$thing}}();
154     }
155     return $Knowledge{$thing};
156 }
157
158 sub usage {
159     foreach my $k (keys %Args) {
160         print "$k\n";
161     }
162     exit;
163 }
164
165 sub findHeaders {
166     my $list=shift;
167
168     foreach my $h (@$list) {
169         my $n='HAVE_'.uc $h;
170         $n =~ s/[\.\/]/_/;
171         print "Looking for header $h ($n)\n";
172         if(-e "/usr/include/$h") {
173             $Subst{$n}="#define $n 0";
174         } else {
175             $Subst{$n}="#undef $n";
176         }
177     }
178 }
179
180 sub fileSubst {
181     my $file=shift;
182     my $cs=shift;
183     my $ce=shift;
184
185     open(T,"$file.template") || croak "Can't open $file.template: $!";
186     unlink $file;
187     open(M,">$file") || croak "Can't create $file: $!";
188
189     print M "$cs generated by configure from $file.template. Don't edit. $ce\n\n";
190
191     while(my $line=<T>) {
192         print M subst($line);
193     }
194
195     close M;
196     close T;
197
198     chmod 0444,"$file";
199 }
200
201 sub fixSubst {
202     foreach my $k (keys %Subst) {
203         $Subst{$k} =~ s/~/$ENV{HOME}/g;
204     }
205 }
206
207 sub create {
208     my $file=shift;
209
210     print "Creating $file\n";
211     open(D,">$file") || croak "Can't create $file: $!";
212     close D;
213 }
214
215 sub build {
216     my $code=shift;
217     my $link=shift;
218
219     my $cc=getKnowledge('cc');
220     my $fh=new File::Temp(SUFFIX => '.c');
221
222     my($v,$d,$f)=File::Spec->splitpath($fh->filename());
223
224     my $cur=File::Spec->rel2abs(File::Spec->curdir());
225     chdir($d) || croak "chdir($d): $!";
226
227     print $fh $code;
228     $fh->close();
229
230     my $cflag='';
231     $cflag='-c' if !defined $link;
232     my $cmd="$cc $Subst{CFLAGS} $Subst{INCLUDES} $cflag ".$f;
233     $cmd.=" $link" if defined $link;
234     trace("$cmd\n--code--\n$code--------\n");
235     my $ret=system("$cmd >> $LogFile 2>&1");
236
237     my $obj=$fh->filename();
238     $obj =~ s/\.c$/.o/;
239     unlink($obj) || $! == ENOENT || croak "unlink($obj): $!";
240     unlink('a.out') || $! == ENOENT || croak "unlink(a.out): $!";
241
242     chdir($cur) || croak "chdir($cur): $!";
243
244     return $ret == 0;
245 }
246
247 sub typeInfo {
248     my $type=shift;
249     my $header=shift;
250
251     my %info;
252
253     print "Getting info about $type.\n";
254
255     foreach my $fmt (qw(%d %ld)) {
256         my $code="#include <$header>\n";
257         $code .= "#include <stdio.h>\n";
258         $code .= "void f(void) { static $type t; printf(\"$fmt\",t); }\n";
259         if(build($code)) {
260             $info{fmt}=$fmt;
261             print "  $type printf format is $fmt\n";
262         }
263     }
264     croak "Can't determine print format for $type" if !defined $info{fmt};
265
266     return \%info;
267 }
268
269 sub investigateTypes {
270     my $types=shift;
271
272     foreach my $type (@$types) {
273         my $info=getKnowledge($type);
274         $Subst{uc($type)."_FMT"}="\"$info->{fmt}\"";
275     }
276 }
277
278 sub checkHeaders {
279     my $headers=shift;
280
281     foreach my $h (@$headers) {
282         print "Check required header $h\n";
283         build("#include <$h>\n") || croak "Can't find required header $h";
284     }
285 }
286
287 sub findLibraries {
288     my $funcs=shift;
289
290     my @libs;
291   func:
292     foreach my $func (keys %$funcs) {
293         print "Checking libraries for $func()\n";
294         my $code=join("\n",map { "#include <$_>" }
295                       @{$funcs->{$func}->{headers}});
296         $code.="\nint main() { $funcs->{$func}->{call}; return 0; }\n";
297         foreach my $lgroup (@{$funcs->{$func}->{libs}}) {
298             print "  trying ",@$lgroup ? join(', ',@$lgroup) : 'no libraries';
299             if(build($code,join(' ',map { "-l$_" } @$lgroup))) {
300                 push @libs,@$lgroup;
301                 print " ... OK\n";
302                 next func;
303             }
304             print " ... no\n";
305         }
306     }
307     return \@libs;
308 }
309
310 sub baseCFlags {
311     my $flags='';
312     if(getKnowledge('is_gcc')) {
313         $flags='-Wall -Werror -W -g';
314 #       my $v=getKnowledge('gcc_major');
315 #       $flags.=' -Wdeclaration-after-statement' if $v >= 3;
316     }
317     return $flags;
318 }
319
320 sub isGCC {
321     my $cc=getKnowledge('cc');
322
323     my $ret=build("int main()\n{\n#ifndef __GNUC__\n  syntax error\n#endif\n return 0; }\n");
324     trace("isGCC=$ret\n");
325     return $ret;
326 }
327
328 sub gccVersion {
329     return undef if !getKnowledge('is_gcc');
330
331     my $cc=getKnowledge('cc');
332     my $vstr=`$cc --version`;
333
334     my($v)=$vstr =~ /(\d+\.\d+\.\d+)/;
335
336     trace("gcc version=$v\n");
337
338     return $v;
339 }
340
341 sub gccMajor {
342     my $v=getKnowledge('gcc_version');
343     return undef if !defined $v;
344
345     ($v)=$v =~ /^(\d+)/;
346
347     trace("gcc major=$v\n");
348
349     return $v;
350 }
Note: See TracBrowser for help on using the browser.