be49a612c9c435ce8af9665bd2e7e628613ddf46
[bbaumbach/samba-autobuild/.git] / source4 / build / smb_build / makefile.pm
1 ###########################################################
2 ### SMB Build System                                    ###
3 ### - create output for Makefile                        ###
4 ###                                                     ###
5 ###  Copyright (C) Stefan (metze) Metzmacher 2004       ###
6 ###  Copyright (C) Jelmer Vernooij 2005                 ###
7 ###  Released under the GNU GPL                         ###
8 ###########################################################
9
10 package smb_build::makefile;
11 use smb_build::env;
12 use strict;
13
14 use base 'smb_build::env';
15
16 sub new($$$)
17 {
18         my ($myname, $config, $mkfile) = @_;
19         my $self = new smb_build::env($config);
20         
21         bless($self, $myname);
22
23         $self->{manpages} = [];
24         $self->{sbin_progs} = [];
25         $self->{bin_progs} = [];
26         $self->{static_libs} = [];
27         $self->{shared_libs} = [];
28         $self->{headers} = [];
29         $self->{pc_files} = [];
30         $self->{output} = "";
31
32         $self->{mkfile} = $mkfile;
33
34         $self->output("################################################\n");
35         $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
36         $self->output("################################################\n");
37         $self->output("\n");
38
39         $self->output("default: all\n\n");
40
41         $self->_prepare_path_vars();
42         $self->_prepare_compiler_linker();
43         $self->_prepare_hostcc_rule();
44         $self->_prepare_std_CC_rule("c","o",'$(PICFLAG)',"Compiling","Rule for std objectfiles");
45         $self->_prepare_std_CC_rule("h","h.gch",'$(PICFLAG)',"Precompiling","Rule for precompiled headerfiles");
46
47         return $self;
48 }
49
50 sub output($$)
51 {
52         my ($self, $text) = @_;
53
54         $self->{output} .= $text;
55 }
56
57 sub _prepare_path_vars($)
58 {
59         my ($self) = @_;
60
61         $self->output(<< "__EOD__"
62 prefix = $self->{config}->{prefix}
63 exec_prefix = $self->{config}->{exec_prefix}
64 selftest_prefix = $self->{config}->{selftest_prefix}
65 VPATH = $self->{config}->{srcdir}
66 srcdir = $self->{config}->{srcdir}
67 builddir = $self->{config}->{builddir}
68
69 BASEDIR = $self->{config}->{prefix}
70 BINDIR = $self->{config}->{bindir}
71 SBINDIR = $self->{config}->{sbindir}
72 datadir = $self->{config}->{datadir}
73 LIBDIR = $self->{config}->{libdir}
74 INCLUDEDIR = $self->{config}->{includedir}
75 CONFIGDIR = $self->{config}->{configdir}
76 localstatedir = $self->{config}->{localstatedir}
77 SWATDIR = $self->{config}->{swatdir}
78 VARDIR = $self->{config}->{localstatedir}
79 LOGFILEBASE = $self->{config}->{logfilebase}
80 NCALRPCDIR = $self->{config}->{localstatedir}/ncalrpc
81 LOCKDIR = $self->{config}->{lockdir}
82 PIDDIR = $self->{config}->{piddir}
83 MANDIR = $self->{config}->{mandir}
84 PRIVATEDIR = $self->{config}->{privatedir}
85
86 __EOD__
87 );
88 }
89
90 sub _prepare_compiler_linker($)
91 {
92         my ($self) = @_;
93
94         $self->output(<< "__EOD__"
95 SHELL=$self->{config}->{SHELL}
96
97 PERL=$self->{config}->{PERL}
98
99 CC=$self->{config}->{CC}
100 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} $self->{config}->{CPPFLAGS}
101 PICFLAG=$self->{config}->{PICFLAG}
102 HOSTCC=$self->{config}->{HOSTCC}
103
104 CPP=$self->{config}->{CPP}
105 CPPFLAGS=$self->{config}->{CPPFLAGS}
106
107 LD=$self->{config}->{LD}
108 LD_FLAGS=$self->{config}->{LDFLAGS} 
109
110 STLD=$self->{config}->{AR}
111 STLD_FLAGS=-rc
112
113 SHLD=$self->{config}->{CC}
114 SHLD_FLAGS=$self->{config}->{LDSHFLAGS}
115 SONAMEFLAG=$self->{config}->{SONAMEFLAG}
116 SHLIBEXT=$self->{config}->{SHLIBEXT}
117
118 XSLTPROC=$self->{config}->{XSLTPROC}
119
120 LEX=$self->{config}->{LEX}
121 YACC=$self->{config}->{YACC}
122 YAPP=$self->{config}->{YAPP}
123 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
124
125 GCOV=$self->{config}->{GCOV}
126
127 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
128
129 __EOD__
130 );
131 }
132
133 sub _prepare_mk_files($)
134 {
135         my $self = shift;
136         my @tmp = ();
137
138         
139         foreach (@smb_build::config_mk::parsed_files) {
140                 s/ .*$//g;
141                 push (@tmp, $_);
142         }
143
144         $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
145 }
146
147 sub _prepare_dummy_MAKEDIR($)
148 {
149         my ($self) = @_;
150
151         $self->output(<< '__EOD__'
152 dynconfig.o: dynconfig.c Makefile
153         @echo Compiling $*.c
154         @$(CC) $(CFLAGS) $(PICFLAG) $(PATH_FLAGS) -c $< -o $@
155 __EOD__
156 );
157         if ($self->{config}->{BROKEN_CC} eq "yes") {
158                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
159 ');
160         }
161         $self->output("\n");
162 }
163
164 sub _prepare_std_CC_rule($$$$$$)
165 {
166         my ($self,$src,$dst,$flags,$message,$comment) = @_;
167
168         $self->output(<< "__EOD__"
169 # $comment
170 .$src.$dst:
171         \@echo $message \$\*.$src
172         \@\$(CC) `script/cflags.sh \$\@` \$(CFLAGS) $flags -c \$< -o \$\@
173 __EOD__
174 );
175         if ($self->{config}->{BROKEN_CC} eq "yes") {
176                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
177 ');
178         }
179
180         $self->output("\n");
181 }
182
183 sub _prepare_hostcc_rule($)
184 {
185         my ($self) = @_;
186         
187         $self->output(<< "__EOD__"
188 .c.ho:
189         \@echo Compiling \$\*.c with host compiler
190         \@\$(HOSTCC) `script/cflags.sh \$\@` \$(CFLAGS) -c \$< -o \$\@
191 __EOD__
192 );
193         if ($self->{config}->{BROKEN_CC} eq "yes") {
194                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\' -e \'s%\.ho$$%.o%\'` $@
195 ');
196         }
197
198         $self->output("\n");
199 }
200
201 sub array2oneperline($)
202 {
203         my $array = shift;
204         my $output = "";
205
206         foreach (@$array) {
207                 next unless defined($_);
208
209                 $output .= " \\\n\t\t$_";
210         }
211
212         return $output;
213 }
214
215 sub _prepare_obj_list($$$)
216 {
217         my ($self,$var,$ctx) = @_;
218
219         my $tmplist = array2oneperline($ctx->{OBJ_LIST});
220         return if ($tmplist eq "");
221
222         $self->output("$var\_$ctx->{NAME}_OBJS =$tmplist\n");
223 }
224
225 sub _prepare_cflags($$$)
226 {
227         my ($self, $var,$ctx) = @_;
228
229         my $tmplist = array2oneperline($ctx->{CFLAGS});
230         return if ($tmplist eq "");
231
232         $self->output("$var\_$ctx->{NAME}_CFLAGS =$tmplist\n");
233 }
234
235 sub SharedLibrary($$)
236 {
237         my ($self,$ctx) = @_;
238
239         push (@{$self->{shared_libs}}, $ctx->{OUTPUT});
240
241         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
242         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
243
244         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
245         my $tmpshlink = array2oneperline($ctx->{LINK_LIST});
246         my $tmpshflag = array2oneperline($ctx->{LINK_FLAGS});
247
248         $self->output(<< "__EOD__"
249 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
250 LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST =$tmpshlink
251 LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS =$tmpshflag
252 #
253
254 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
255         \@echo Linking \$\@
256         \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
257                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS) \\
258                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST)
259
260 __EOD__
261 );
262         if (defined($ctx->{LIBRARY_SONAME})) {
263             $self->output(<< "__EOD__"
264 # Symlink $ctx->{LIBRARY_SONAME}
265 bin/$ctx->{LIBRARY_SONAME}: bin/$ctx->{LIBRARY_REALNAME} bin/.dummy
266         \@echo Symlink \$\@
267         \@ln -sf $ctx->{LIBRARY_REALNAME} \$\@
268 # Symlink $ctx->{LIBRARY_NAME}
269 bin/$ctx->{LIBRARY_NAME}: bin/$ctx->{LIBRARY_SONAME} bin/.dummy
270         \@echo Symlink \$\@
271         \@ln -sf $ctx->{LIBRARY_SONAME} \$\@
272
273 __EOD__
274 );
275         }
276
277         $self->output("library_$ctx->{NAME}: basics bin/lib$ctx->{LIBRARY_NAME}\n");
278 }
279
280 sub MergedObj($$)
281 {
282         my ($self,$ctx) = @_;
283
284         return unless $ctx->{TARGET};
285
286         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
287
288         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
289         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
290         $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
291
292         $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
293
294         $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
295         $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJS) -o $ctx->{TARGET}\n");
296         $self->output("\n");
297 }
298
299 sub ObjList($$)
300 {
301         my ($self,$ctx) = @_;
302         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
303
304         return unless $ctx->{TARGET};
305
306         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
307         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
308         $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
309         $self->output("$ctx->{TARGET}: ");
310         $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
311         $self->output("\t\@touch $ctx->{TARGET}\n");
312 }
313
314 sub StaticLibrary($$)
315 {
316         my ($self,$ctx) = @_;
317
318         push (@{$self->{static_libs}}, $ctx->{OUTPUT});
319
320         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
321         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
322
323         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
324         my $tmpstlink = array2oneperline($ctx->{LINK_LIST});
325         my $tmpstflag = array2oneperline($ctx->{LINK_FLAGS});
326
327         $self->output(<< "__EOD__"
328 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
329 #
330 LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST =$tmpstlink
331 #
332 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
333         \@echo Linking \$@
334         \@\$(STLD) \$(STLD_FLAGS) \$@ \\
335                 \$(LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST)
336
337 library_$ctx->{NAME}: basics $ctx->{TARGET}
338
339 __EOD__
340 );
341 }
342
343 sub Header($$)
344 {
345         my ($self,$ctx) = @_;
346
347         foreach (@{$ctx->{PUBLIC_HEADERS}}) {
348                 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
349         }
350 }
351
352 sub Binary($$)
353 {
354         my ($self,$ctx) = @_;
355
356         unless (defined($ctx->{INSTALLDIR})) {
357         } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") {
358                 push (@{$self->{sbin_progs}}, $ctx->{TARGET});
359         } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
360                 push (@{$self->{bin_progs}}, $ctx->{TARGET});
361         }
362
363         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
364         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
365         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
366         my $tmplink = array2oneperline($ctx->{LINK_LIST});
367         my $tmpflag = array2oneperline($ctx->{LINK_FLAGS});
368
369         $self->output(<< "__EOD__"
370 #
371 BINARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
372 BINARY_$ctx->{NAME}_LINK_LIST =$tmplink
373 BINARY_$ctx->{NAME}_LINK_FLAGS =$tmpflag
374 #
375 bin/$ctx->{BINARY}: bin/.dummy \$(BINARY_$ctx->{NAME}_DEPEND_LIST) \$(BINARY_$ctx->{NAME}_OBJS)
376         \@echo Linking \$\@
377         \@\$(CC) \$(LD_FLAGS) -o \$\@ \\
378                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS) \\
379                 \$\(BINARY_$ctx->{NAME}_LINK_LIST) \\
380                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS)
381 binary_$ctx->{BINARY}: basics bin/$ctx->{BINARY}
382
383 __EOD__
384 );
385 }
386
387 sub Manpage($$)
388 {
389         my ($self,$ctx) = @_;
390
391         my $dir = $ctx->{BASEDIR};
392
393         $dir =~ s/^\.\///g;
394
395         push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
396 }
397
398 sub PkgConfig($$)
399 {
400         my ($self,$ctx) = @_;
401         
402         my $path = "$ctx->{BASEDIR}/$ctx->{NAME}.pc";
403
404         push (@{$self->{pc_files}}, $path);
405
406         smb_build::env::PkgConfig($self,$path,$ctx->{NAME},"FIXME",join(' ', @{$ctx->{CFLAGS}}), "$ctx->{MAJOR_VERSION}.$ctx->{MINOR_VERSION}.$ctx->{RELEASE_VERSION}"); 
407 }
408
409 sub ProtoHeader($$)
410 {
411         my ($self,$ctx) = @_;
412
413         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
414 }
415
416 sub write($$)
417 {
418         my ($self,$file) = @_;
419
420         $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
421         $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
422         $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
423         $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
424         $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
425         $self->output("PUBLIC_HEADERS = " . array2oneperline($self->{headers}) . "\n");
426         $self->output("PC_FILES = " . array2oneperline($self->{pc_files}) . "\n");
427
428
429         $self->_prepare_mk_files();
430
431         if ($self->{developer}) {
432                 $self->output(<<__EOD__
433 #-include \$(_ALL_OBJS_OBJS:.o=.d)
434 IDL_FILES = \$(wildcard librpc/idl/*.idl)
435 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.c,\$(IDL_FILES)) \\
436 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_\%_c.c,\$(IDL_FILES)) \\
437 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.h,\$(IDL_FILES)): idl
438 __EOD__
439 );
440         }
441
442         $self->_prepare_dummy_MAKEDIR();
443
444         $self->output($self->{mkfile});
445
446         open(MAKEFILE,">$file") || die ("Can't open $file\n");
447         print MAKEFILE $self->{output};
448         close(MAKEFILE);
449
450         print __FILE__.": creating $file\n";
451 }
452
453 1;