r11377: Add support for building LIBRARY elements as shared libraries:
[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         my $devld = "";
95         if ($self->{developer}) {
96                 $devld = " \$(DEVEL_LDFLAGS)";
97         }
98
99         $self->output(<< "__EOD__"
100 SHELL=$self->{config}->{SHELL}
101
102 PERL=$self->{config}->{PERL}
103
104 CC=$self->{config}->{CC}
105 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} $self->{config}->{CPPFLAGS}
106 PICFLAG=$self->{config}->{PICFLAG}
107 HOSTCC=$self->{config}->{HOSTCC}
108
109 CPP=$self->{config}->{CPP}
110 CPPFLAGS=$self->{config}->{CPPFLAGS}
111
112 DEVEL_LDFLAGS=-Wl,-rpath,bin/
113 LD=$self->{config}->{LD} 
114 LDFLAGS=$self->{config}->{LDFLAGS} -Lbin/$devld
115
116 STLD=$self->{config}->{AR}
117 STLD_FLAGS=-rc -Lbin/
118
119 SHLD=$self->{config}->{CC}
120 SHLD_FLAGS=$self->{config}->{LDSHFLAGS} -Lbin/$devld
121 SONAMEFLAG=$self->{config}->{SONAMEFLAG}
122 SHLIBEXT=$self->{config}->{SHLIBEXT}
123
124 XSLTPROC=$self->{config}->{XSLTPROC}
125
126 LEX=$self->{config}->{LEX}
127 YACC=$self->{config}->{YACC}
128 YAPP=$self->{config}->{YAPP}
129 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
130
131 GCOV=$self->{config}->{GCOV}
132
133 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
134
135 __EOD__
136 );
137 }
138
139 sub _prepare_mk_files($)
140 {
141         my $self = shift;
142         my @tmp = ();
143
144         
145         foreach (@smb_build::config_mk::parsed_files) {
146                 s/ .*$//g;
147                 push (@tmp, $_);
148         }
149
150         $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
151 }
152
153 sub _prepare_dummy_MAKEDIR($)
154 {
155         my ($self) = @_;
156
157         $self->output(<< '__EOD__'
158 dynconfig.o: dynconfig.c Makefile
159         @echo Compiling $*.c
160         @$(CC) $(CFLAGS) $(PICFLAG) $(PATH_FLAGS) -c $< -o $@
161 __EOD__
162 );
163         if ($self->{config}->{BROKEN_CC} eq "yes") {
164                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
165 ');
166         }
167         $self->output("\n");
168 }
169
170 sub _prepare_std_CC_rule($$$$$$)
171 {
172         my ($self,$src,$dst,$flags,$message,$comment) = @_;
173
174         $self->output(<< "__EOD__"
175 # $comment
176 .$src.$dst:
177         \@echo $message \$\*.$src
178         \@\$(CC) `script/cflags.sh \$\@` \$(CFLAGS) $flags -c \$< -o \$\@
179 __EOD__
180 );
181         if ($self->{config}->{BROKEN_CC} eq "yes") {
182                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
183 ');
184         }
185
186         $self->output("\n");
187 }
188
189 sub _prepare_hostcc_rule($)
190 {
191         my ($self) = @_;
192         
193         $self->output(<< "__EOD__"
194 .c.ho:
195         \@echo Compiling \$\*.c with host compiler
196         \@\$(HOSTCC) `script/cflags.sh \$\@` \$(CFLAGS) -c \$< -o \$\@
197 __EOD__
198 );
199         if ($self->{config}->{BROKEN_CC} eq "yes") {
200                 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\' -e \'s%\.ho$$%.o%\'` $@
201 ');
202         }
203
204         $self->output("\n");
205 }
206
207 sub array2oneperline($)
208 {
209         my $array = shift;
210         my $output = "";
211
212         foreach (@$array) {
213                 next unless defined($_);
214
215                 $output .= " \\\n\t\t$_";
216         }
217
218         return $output;
219 }
220
221 sub _prepare_obj_list($$$)
222 {
223         my ($self,$var,$ctx) = @_;
224
225         my $tmplist = array2oneperline($ctx->{OBJ_LIST});
226         return if ($tmplist eq "");
227
228         $self->output("$var\_$ctx->{NAME}_OBJS =$tmplist\n");
229 }
230
231 sub _prepare_cflags($$$)
232 {
233         my ($self, $var,$ctx) = @_;
234
235         my $tmplist = array2oneperline($ctx->{CFLAGS});
236         return if ($tmplist eq "");
237
238         $self->output("$var\_$ctx->{NAME}_CFLAGS =$tmplist\n");
239 }
240
241 sub SharedLibrary($$)
242 {
243         my ($self,$ctx) = @_;
244
245         push (@{$self->{shared_libs}}, "bin/$ctx->{LIBRARY_NAME}");
246
247         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
248         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
249
250         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
251         my $tmpshlink = array2oneperline($ctx->{LINK_LIST});
252         my $tmpshflag = array2oneperline($ctx->{LINK_FLAGS});
253
254         $self->output(<< "__EOD__"
255 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
256 LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST =$tmpshlink
257 LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS =$tmpshflag
258 #
259
260 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
261         \@echo Linking \$\@
262         \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
263                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS) \\
264                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST)
265
266 __EOD__
267 );
268         if (defined($ctx->{LIBRARY_SONAME})) {
269             $self->output(<< "__EOD__"
270 # Symlink $ctx->{LIBRARY_SONAME}
271 bin/$ctx->{LIBRARY_SONAME}: bin/$ctx->{LIBRARY_REALNAME} bin/.dummy
272         \@echo Symlink \$\@
273         \@ln -sf $ctx->{LIBRARY_REALNAME} \$\@
274 # Symlink $ctx->{LIBRARY_NAME}
275 bin/$ctx->{LIBRARY_NAME}: bin/$ctx->{LIBRARY_SONAME} bin/.dummy
276         \@echo Symlink \$\@
277         \@ln -sf $ctx->{LIBRARY_SONAME} \$\@
278
279 __EOD__
280 );
281         }
282
283         $self->output("library_$ctx->{NAME}: basics bin/lib$ctx->{LIBRARY_NAME}\n");
284 }
285
286 sub MergedObj($$)
287 {
288         my ($self,$ctx) = @_;
289
290         return unless $ctx->{TARGET};
291
292         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
293
294         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
295         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
296         $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
297
298         $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
299
300         $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
301         $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJS) -o $ctx->{TARGET}\n");
302         $self->output("\n");
303 }
304
305 sub ObjList($$)
306 {
307         my ($self,$ctx) = @_;
308         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
309
310         return unless $ctx->{TARGET};
311
312         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
313         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
314         $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
315         $self->output("$ctx->{TARGET}: ");
316         $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
317         $self->output("\t\@touch $ctx->{TARGET}\n");
318 }
319
320 sub StaticLibrary($$)
321 {
322         my ($self,$ctx) = @_;
323
324         push (@{$self->{static_libs}}, $ctx->{OUTPUT});
325
326         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
327         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
328
329         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
330         my $tmpstlink = array2oneperline($ctx->{LINK_LIST});
331         my $tmpstflag = array2oneperline($ctx->{LINK_FLAGS});
332
333         $self->output(<< "__EOD__"
334 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
335 #
336 LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST =$tmpstlink
337 #
338 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
339         \@echo Linking \$@
340         \@\$(STLD) \$(STLD_FLAGS) \$@ \\
341                 \$(LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST)
342
343 library_$ctx->{NAME}: basics $ctx->{TARGET}
344
345 __EOD__
346 );
347 }
348
349 sub Header($$)
350 {
351         my ($self,$ctx) = @_;
352
353         foreach (@{$ctx->{PUBLIC_HEADERS}}) {
354                 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
355         }
356 }
357
358 sub Binary($$)
359 {
360         my ($self,$ctx) = @_;
361
362         unless (defined($ctx->{INSTALLDIR})) {
363         } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") {
364                 push (@{$self->{sbin_progs}}, $ctx->{TARGET});
365         } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
366                 push (@{$self->{bin_progs}}, $ctx->{TARGET});
367         }
368
369         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
370         $self->_prepare_cflags($ctx->{TYPE}, $ctx);
371         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
372         my $tmplink = array2oneperline($ctx->{LINK_LIST});
373         my $tmpflag = array2oneperline($ctx->{LINK_FLAGS});
374
375         $self->output(<< "__EOD__"
376 #
377 BINARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
378 BINARY_$ctx->{NAME}_LINK_LIST =$tmplink
379 BINARY_$ctx->{NAME}_LINK_FLAGS =$tmpflag
380 #
381 bin/$ctx->{BINARY}: bin/.dummy \$(BINARY_$ctx->{NAME}_DEPEND_LIST) \$(BINARY_$ctx->{NAME}_OBJS)
382         \@echo Linking \$\@
383         \@\$(CC) \$(LDFLAGS) -o \$\@ \\
384                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS) \\
385                 \$\(BINARY_$ctx->{NAME}_LINK_LIST) \\
386                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS)
387 binary_$ctx->{BINARY}: basics bin/$ctx->{BINARY}
388
389 __EOD__
390 );
391 }
392
393 sub Manpage($$)
394 {
395         my ($self,$ctx) = @_;
396
397         my $dir = $ctx->{BASEDIR};
398
399         $dir =~ s/^\.\///g;
400
401         push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
402 }
403
404 sub PkgConfig($$)
405 {
406         my ($self,$ctx) = @_;
407         
408         my $link_name = $ctx->{NAME};
409
410         $link_name =~ s/^LIB//g;
411         $link_name = lc($link_name);
412
413         my $path = "$ctx->{BASEDIR}/$link_name.pc";
414
415         push (@{$self->{pc_files}}, $path);
416
417         smb_build::env::PkgConfig($self,
418                 $path,
419                 $link_name,
420                 $ctx->{OUTPUT},
421                 join(' ', @{$ctx->{CFLAGS}}), 
422                 "$ctx->{MAJOR_VERSION}.$ctx->{MINOR_VERSION}.$ctx->{RELEASE_VERSION}",
423                 $ctx->{DESCRIPTION}
424         ); 
425 }
426
427 sub ProtoHeader($$)
428 {
429         my ($self,$ctx) = @_;
430
431         $self->_prepare_obj_list($ctx->{TYPE}, $ctx);
432 }
433
434 sub write($$)
435 {
436         my ($self,$file) = @_;
437
438         $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
439         $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
440         $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
441         $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
442         $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
443         $self->output("PUBLIC_HEADERS = " . array2oneperline($self->{headers}) . "\n");
444         $self->output("PC_FILES = " . array2oneperline($self->{pc_files}) . "\n");
445
446
447         $self->_prepare_mk_files();
448
449         if ($self->{developer}) {
450                 $self->output(<<__EOD__
451 #-include \$(_ALL_OBJS_OBJS:.o=.d)
452 IDL_FILES = \$(wildcard librpc/idl/*.idl)
453 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.c,\$(IDL_FILES)) \\
454 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_\%_c.c,\$(IDL_FILES)) \\
455 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.h,\$(IDL_FILES)): idl
456 __EOD__
457 );
458         }
459
460         $self->_prepare_dummy_MAKEDIR();
461
462         $self->output($self->{mkfile});
463
464         open(MAKEFILE,">$file") || die ("Can't open $file\n");
465         print MAKEFILE $self->{output};
466         close(MAKEFILE);
467
468         print __FILE__.": creating $file\n";
469 }
470
471 1;