b43a738613fb1b0af59e629034c7660134b350c8
[sfrench/samba-autobuild/.git] / source / 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 makefile;
11 use config qw(%config);
12 use strict;
13
14 sub _prepare_path_vars()
15 {
16         my $output;
17
18         $output = << '__EOD__';
19 prefix = @prefix@
20 exec_prefix = @exec_prefix@
21 selftest_prefix = @selftest_prefix@
22 VPATH = @srcdir@
23 srcdir = @srcdir@
24 builddir = @builddir@
25
26 BASEDIR = @prefix@
27 BINDIR = @bindir@
28 SBINDIR = @sbindir@
29 LIBDIR = @libdir@
30 CONFIGDIR = @configdir@
31 localstatedir = @localstatedir@
32 SWATDIR = @swatdir@
33 VARDIR = @localstatedir@
34
35 # The permissions to give the executables
36 INSTALLPERMS = 0755
37
38 # set these to where to find various files
39 # These can be overridden by command line switches (see smbd(8))
40 # or in smb.conf (see smb.conf(5))
41 LOGFILEBASE = @logfilebase@
42 CONFIGFILE = $(CONFIGDIR)/smb.conf
43 LMHOSTSFILE = $(CONFIGDIR)/lmhosts
44 NCALRPCDIR = @localstatedir@/ncalrpc
45
46 # This is where smbpasswd et al go
47 PRIVATEDIR = @privatedir@
48 SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd
49
50 # the directory where lock files go
51 LOCKDIR = @lockdir@
52
53 # the directory where pid files go
54 PIDDIR = @piddir@
55
56 MANDIR = @mandir@
57
58 PATH_FLAGS = -DCONFIGFILE=\"$(CONFIGFILE)\"  -DSBINDIR=\"$(SBINDIR)\" \
59          -DBINDIR=\"$(BINDIR)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\" \
60          -DLOCKDIR=\"$(LOCKDIR)\" -DPIDDIR=\"$(PIDDIR)\" -DLIBDIR=\"$(LIBDIR)\" \
61          -DLOGFILEBASE=\"$(LOGFILEBASE)\" -DSHLIBEXT=\"@SHLIBEXT@\" \
62          -DCONFIGDIR=\"$(CONFIGDIR)\" -DNCALRPCDIR=\"$(NCALRPCDIR)\" \
63          -DSWATDIR=\"$(SWATDIR)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
64          -DPRIVATE_DIR=\"$(PRIVATEDIR)\"
65 __EOD__
66
67         return $output;
68 }
69
70 sub _prepare_compiler_linker()
71 {
72         return << "__EOD__";
73 SHELL=$config{SHELL}
74 PERL=$config{PERL}
75 CC=$config{CC}
76 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -D_SAMBA_BUILD_ -DHAVE_CONFIG_H -I\$(srcdir)/lib $config{CFLAGS} $config{CPPFLAGS}
77
78 LD=$config{LD}
79 LD_FLAGS=$config{LDFLAGS} -Lbin
80
81 STLD=$config{AR}
82 STLD_FLAGS=-rc
83
84 SHLD=$config{CC}
85 SHLD_FLAGS=$config{LDSHFLAGS} -Lbin
86
87 XSLTPROC=$config{XSLTPROC}
88
89 LEX=$config{LEX}
90 YACC=$config{YACC}
91
92 CPP=$config{CPP}
93
94 DEFAULT_TEST_TARGET=$config{DEFAULT_TEST_TARGET}
95
96 __EOD__
97 }
98
99 sub _prepare_default_rule()
100 {
101         return << '__EOD__';
102 default: all
103
104 __EOD__
105 }
106
107 sub _prepare_SUFFIXES()
108 {
109         return << '__EOD__';
110 .SUFFIXES: .x .c .et .y .l .d .o .h .h.gch .a .so .1 .1.xml .3 .3.xml .5 .5.xml .7 .7.xml
111
112 __EOD__
113 }
114
115 sub _prepare_man_rule($)
116 {
117         my $suffix = shift;
118
119         return << "__EOD__";
120 .$suffix.xml.$suffix:
121         \$(XSLTPROC) -o \$@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \$<
122
123 __EOD__
124 }
125
126 sub _prepare_config_status()
127 {
128         my @parsed_files = @smb_build::config_mk::parsed_files;
129         my $deps = "";
130         
131         foreach (@parsed_files) {
132                 /^([^ |]+)/;
133                 $deps.= " $1";
134         }
135
136         return "
137
138 Makefile: config.status $deps
139         ./config.status
140
141 ";
142 }
143
144 sub _prepare_binaries($)
145 {
146         my $ctx = shift;
147
148         my @bbn_list = ();
149         my @sbn_list = ();
150
151         foreach (values %$ctx) {
152                 next unless defined $_->{OUTPUT_TYPE};
153                 next unless ($_->{OUTPUT_TYPE} eq "BINARY");
154
155                 push(@sbn_list, $_->{OUTPUT}) if ($_->{INSTALLDIR} eq "SBINDIR");
156                 push(@bbn_list, $_->{OUTPUT}) if ($_->{INSTALLDIR} eq "BINDIR");
157         }
158
159         my $bbn = array2oneperline(\@bbn_list);
160         my $sbn = array2oneperline(\@sbn_list);
161         return << "__EOD__";
162 BIN_PROGS = $bbn
163 SBIN_PROGS = $sbn
164 __EOD__
165 }
166
167 sub _prepare_manpages($)
168 {
169         my $ctx = shift;
170
171         my @mp_list = ();
172
173         foreach (values %$ctx) {
174                 push (@mp_list, $_->{MANPAGE}) if (defined($_->{MANPAGE}) and $_->{MANPAGE} ne "");
175         }
176         
177         my $mp = array2oneperline(\@mp_list);
178         return << "__EOD__";
179 MANPAGES = $mp
180
181 __EOD__
182 }
183
184 sub _prepare_dummy_MAKEDIR()
185 {
186         my $ctx = shift;
187
188         return  << '__EOD__';
189 bin/.dummy:
190         @: >> $@ || : > $@
191
192 dynconfig.o: dynconfig.c Makefile
193         @echo Compiling $*.c
194         @$(CC) $(CFLAGS) @PICFLAG@ $(PATH_FLAGS) -c $< -o $@
195 @BROKEN_CC@     -mv `echo $@ | sed 's%^.*/%%g'` $@
196
197 __EOD__
198 }
199
200 sub _prepare_depend_CC_rule()
201 {
202         return << '__EOD__';
203
204 .c.d:
205         @echo "Generating dependencies for $<"
206         @$(CC) -MM -MG -MT $(<:.c=.o) -MF $@ $(CFLAGS) $<
207
208 __EOD__
209 }
210
211 ###########################################################
212 # This function creates a standard make rule which is using $(CC)
213 #
214 # $output = _prepare_std_CC_rule($srcext,$destext,$flags,$message,$comment)
215 #
216 # $srcext -     sourcefile extension
217 #
218 # $destext -    destinationfile extension
219 #
220 # $flags -      additional compiler flags
221 #
222 # $message -    logmessage which is echoed while running this rule
223 #
224 # $comment -    just a comment what this rule should do
225 #
226 # $output -             the resulting output buffer
227 sub _prepare_std_CC_rule($$$$$)
228 {
229         my ($src,$dst,$flags,$message,$comment) = @_;
230
231         return << "__EOD__";
232 # $comment
233 .$src.$dst:
234         \@echo $message \$\*.$src
235         \@\$(CC) `script/cflags.sh \$\@` \$(CFLAGS) $flags -c \$< -o \$\@
236 \@BROKEN_CC\@   -mv `echo \$\@ | sed 's%^.*/%%g'` \$\@
237
238 __EOD__
239 }
240
241 sub array2oneperline($)
242 {
243         my $array = shift;
244         my $output = "";
245
246         foreach (@$array) {
247                 next unless defined($_);
248
249                 $output .= " \\\n\t\t$_";
250         }
251
252         return $output;
253 }
254
255 ###########################################################
256 # This function creates a object file list
257 #
258 # $output = _prepare_var_obj_list($var, $var_ctx)
259 #
260 # $var_ctx -            the subsystem context
261 #
262 # $var_ctx->{NAME}      -       the <var> name
263 # $var_ctx->{OBJ_LIST}  -       the list of objectfiles which sould be linked to this <var>
264 #
265 # $output -             the resulting output buffer
266 sub _prepare_obj_list($$)
267 {
268         my ($var,$ctx) = @_;
269
270         my $tmplist = array2oneperline($ctx->{OBJ_LIST});
271         return "" if ($tmplist eq "");
272
273         return << "__EOD__";
274 $var\_$ctx->{NAME}_OBJS =$tmplist
275 __EOD__
276 }
277
278 sub _prepare_cflags($$)
279 {
280         my ($var,$ctx) = @_;
281
282         my $tmplist = array2oneperline($ctx->{CFLAGS});
283         return "" if ($tmplist eq "");
284
285         return << "__EOD__";
286 $var\_$ctx->{NAME}_CFLAGS =$tmplist
287
288 __EOD__
289 }
290
291 ###########################################################
292 # This function creates a make rule for linking a library
293 #
294 # $output = _prepare_shared_library_rule($library_ctx)
295 #
296 # $library_ctx -                the library context
297 #
298 # $library_ctx->{NAME} -                the library name
299 #
300 # $library_ctx->{DEPEND_LIST} -         the list of rules on which this library depends
301 #
302 # $library_ctx->{LIBRARY_NAME} -        the shared library name
303 # $library_ctx->{LIBRARY_REALNAME} -    the shared library real name
304 # $library_ctx->{LIBRARY_SONAME} - the shared library soname
305 # $library_ctx->{LINK_LIST} -   the list of objectfiles and external libraries
306 #                                       which sould be linked to this shared library
307 # $library_ctx->{LINK_FLAGS} -  linker flags used by this shared library
308 #
309 # $output -             the resulting output buffer
310 sub _prepare_shared_library_rule($)
311 {
312         my $ctx = shift;
313         my $output;
314
315         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
316         my $tmpshlink = array2oneperline($ctx->{LINK_LIST});
317         my $tmpshflag = array2oneperline($ctx->{LINK_FLAGS});
318
319         $output = << "__EOD__";
320 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
321 LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST =$tmpshlink
322 LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS =$tmpshflag
323 #
324
325 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
326         \@echo Linking \$\@
327         \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
328                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS) \\
329                 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST)
330
331 __EOD__
332
333         if (defined($ctx->{LIBRARY_SONAME})) {
334             $output .= << "__EOD__";
335 # Symlink $ctx->{LIBRARY_SONAME}
336 bin/$ctx->{LIBRARY_SONAME}: bin/$ctx->{LIBRARY_REALNAME} bin/.dummy
337         \@echo Symlink \$\@
338         \@ln -sf $ctx->{LIBRARY_REALNAME} \$\@
339 # Symlink $ctx->{LIBRARY_NAME}
340 bin/$ctx->{LIBRARY_NAME}: bin/$ctx->{LIBRARY_SONAME} bin/.dummy
341         \@echo Symlink \$\@
342         \@ln -sf $ctx->{LIBRARY_SONAME} \$\@
343
344 __EOD__
345         }
346
347 $output .= << "__EOD__";
348 library_$ctx->{NAME}: basics bin/lib$ctx->{LIBRARY_NAME}
349
350 __EOD__
351
352         return $output;
353 }
354
355 sub _prepare_mergedobj_rule($)
356 {
357         my $ctx = shift;
358
359         return "" unless $ctx->{TARGET};
360
361         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
362
363         my $output = "$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n";
364
365         $output .= "$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n";
366
367         $output .= "\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n";
368         $output .= "\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJS) -o $ctx->{TARGET}\n";
369         $output .= "\n";
370
371         return $output;
372 }
373
374 sub _prepare_objlist_rule($)
375 {
376         my $ctx = shift;
377         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
378
379         return "" unless $ctx->{TARGET};
380
381         my $output = "$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n";
382         $output .= "$ctx->{TARGET}: ";
383         $output .= "\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n";
384         $output .= "\t\@touch $ctx->{TARGET}\n";
385
386         return $output;
387 }
388
389 ###########################################################
390 # This function creates a make rule for linking a library
391 #
392 # $output = _prepare_static_library_rule($library_ctx)
393 #
394 # $library_ctx -                the library context
395 #
396 # $library_ctx->{NAME} -                the library name
397 #
398 # $library_ctx->{DEPEND_LIST} -         the list of rules on which this library depends
399 #
400 # $library_ctx->{LIBRARY_NAME} -        the static library name
401 # $library_ctx->{LINK_LIST} -   the list of objectfiles which sould be linked
402 #                                       to this static library
403 # $library_ctx->{LINK_FLAGS} -  linker flags used by this static library
404 #
405 # $output -             the resulting output buffer
406 sub _prepare_static_library_rule($)
407 {
408         my $ctx = shift;
409         my $output;
410
411         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
412         my $tmpstlink = array2oneperline($ctx->{LINK_LIST});
413         my $tmpstflag = array2oneperline($ctx->{LINK_FLAGS});
414
415         $output = << "__EOD__";
416 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
417 #
418 LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST =$tmpstlink
419 #
420 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
421         \@echo Linking \$@
422         \@\$(STLD) \$(STLD_FLAGS) \$@ \\
423                 \$(LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST)
424
425 library_$ctx->{NAME}: basics $ctx->{TARGET}
426
427 __EOD__
428
429         return $output;
430 }
431
432 ###########################################################
433 # This function creates a make rule for linking a binary
434 #
435 # $output = _prepare_binary_rule($binary_ctx)
436 #
437 # $binary_ctx -         the binary context
438 #
439 # $binary_ctx->{NAME} -         the binary name
440 # $binary_ctx->{BINARY} -       the binary binary name
441 #
442 # $binary_ctx->{DEPEND_LIST} -  the list of rules on which this binary depends
443 # $binary_ctx->{LINK_LIST} -    the list of objectfiles and external libraries
444 #                               which sould be linked to this binary
445 # $binary_ctx->{LINK_FLAGS} -   linker flags used by this binary
446 #
447 # $output -             the resulting output buffer
448 sub _prepare_binary_rule($)
449 {
450         my $ctx = shift;
451
452         my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
453         my $tmplink = array2oneperline($ctx->{LINK_LIST});
454         my $tmpflag = array2oneperline($ctx->{LINK_FLAGS});
455
456         my $output = << "__EOD__";
457 #
458 BINARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
459 BINARY_$ctx->{NAME}_LINK_LIST =$tmplink
460 BINARY_$ctx->{NAME}_LINK_FLAGS =$tmpflag
461 #
462 bin/$ctx->{BINARY}: bin/.dummy \$(BINARY_$ctx->{NAME}_DEPEND_LIST) \$(BINARY_$ctx->{NAME}_OBJS)
463         \@echo Linking \$\@
464         \@\$(CC) \$(LD_FLAGS) -o \$\@ \\
465                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS) \\
466                 \$\(BINARY_$ctx->{NAME}_LINK_LIST) \\
467                 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS)
468 binary_$ctx->{BINARY}: basics bin/$ctx->{BINARY}
469
470 __EOD__
471
472         return $output;
473 }
474
475 sub _prepare_custom_rule($)
476 {
477         my $ctx = shift;
478         return "
479 $ctx->{NAME}: bin/.TARGET_$ctx->{NAME}
480
481 bin/.TARGET_$ctx->{NAME}:
482         $ctx->{CMD}
483         touch bin/.TARGET_$ctx->{NAME}
484 ";
485 }
486
487 sub _prepare_clean_rules()
488 {
489         my $output = << '__EOD__';
490 clean: heimdal_clean
491         @echo Removing headers
492         @-rm -f include/proto.h
493         @echo Removing objects
494         @-find . -name '*.o' -exec rm -f '{}' \;
495         @echo Removing binaries
496         @-rm -f $(BIN_PROGS) $(SBIN_PROGS)
497         @echo Removing dummy targets
498         @-rm -f bin/.*_*
499         @echo Removing generated files
500         @-rm -rf librpc/gen_*
501
502 distclean: clean
503         -rm -f bin/.dummy
504         -rm -f include/config.h include/smb_build.h
505         -rm -f Makefile Makefile.in
506         -rm -f config.status
507         -rm -f config.log config.cache
508         -rm -f samba4-deps.dot
509         -rm -f config.pm config.mk
510         -rm -f lib/registry/winregistry.pc
511 __EOD__
512
513         if ($config{developer} eq "yes") {
514                 $output .= "\t\@-rm -f \$(_ALL_OBJS_OBJS:.o=.d)\n";
515         }
516
517         $output .= << '__EOD__';
518
519 removebackup:
520         -rm -f *.bak *~ */*.bak */*~ */*/*.bak */*/*~ */*/*/*.bak */*/*/*~
521
522 realdistclean: distclean removebackup
523         -rm -f include/config.h.in
524         -rm -f include/version.h
525         -rm -f configure
526         -rm -f $(MANPAGES)
527 __EOD__
528
529         return $output;
530 }
531
532 sub _prepare_make_target($)
533 {
534         my $ctx = shift;
535         my $tmpdepend;
536
537         $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
538
539         return << "__EOD__";
540 $ctx->{TARGET}: basics $tmpdepend
541
542 __EOD__
543 }
544
545 sub _prepare_target_settings($)
546 {
547         my $CTX = shift;
548         my $output = "";
549
550         foreach my $key (values %$CTX) {
551                 if (defined($key->{OBJ_LIST})) {
552                         $output .= _prepare_obj_list($key->{TYPE}, $key);
553                         $output .= _prepare_cflags($key->{TYPE}, $key);
554                 }
555         }
556
557         return $output;
558 }
559
560 sub _prepare_rule_lists($)
561 {
562         my $depend = shift;
563         my $output = "";
564
565         foreach my $key (values %{$depend}) {
566                 next unless defined $key->{OUTPUT_TYPE};
567
568                 ($output .= _prepare_mergedobj_rule($key)) if $key->{OUTPUT_TYPE} eq "MERGEDOBJ";
569                 ($output .= _prepare_objlist_rule($key)) if $key->{OUTPUT_TYPE} eq "OBJLIST";
570                 ($output .= _prepare_static_library_rule($key)) if $key->{OUTPUT_TYPE} eq "STATIC_LIBRARY";
571                 ($output .= _prepare_shared_library_rule($key)) if $key->{OUTPUT_TYPE} eq "SHARED_LIBRARY";
572                 ($output .= _prepare_binary_rule($key)) if $key->{OUTPUT_TYPE} eq "BINARY";
573                 ($output .= _prepare_custom_rule($key) ) if $key->{TYPE} eq "TARGET";
574         }
575
576         $output .= _prepare_clean_rules();
577
578         return $output;
579 }
580
581 ###########################################################
582 # This function prepares the output for Makefile
583 #
584 # $output = _prepare_makefile_in($OUTPUT)
585 #
586 # $OUTPUT -     the global OUTPUT context
587 #
588 # $output -             the resulting output buffer
589 sub _prepare_makefile_in($)
590 {
591         my ($CTX) = @_;
592         my $output;
593
594         $output  = "############################################\n";
595         $output .= "# Autogenerated by build/smb_build/main.pl #\n";
596         $output .= "############################################\n";
597         $output .= "\n";
598
599         $output .= _prepare_path_vars();
600         $output .= _prepare_compiler_linker();
601         $output .= _prepare_default_rule();
602         $output .= _prepare_SUFFIXES();
603         $output .= _prepare_dummy_MAKEDIR();
604         $output .= _prepare_std_CC_rule("c","o",$config{PICFLAG},"Compiling","Rule for std objectfiles");
605         $output .= _prepare_std_CC_rule("h","h.gch",$config{PICFLAG},"Precompiling","Rule for precompiled headerfiles");
606
607         $output .= _prepare_depend_CC_rule();
608         
609         $output .= _prepare_man_rule("1");
610         $output .= _prepare_man_rule("3");
611         $output .= _prepare_man_rule("5");
612         $output .= _prepare_man_rule("7");
613         $output .= _prepare_manpages($CTX);
614         $output .= _prepare_binaries($CTX);
615         $output .= _prepare_target_settings($CTX);
616         $output .= _prepare_rule_lists($CTX);
617         $output .= _prepare_config_status();
618
619         if ($config{developer} eq "yes") {
620                 $output .= <<__EOD__
621 #-include \$(_ALL_OBJS_OBJS:.o=.d)
622 IDL_FILES = \$(wildcard librpc/idl/*.idl)
623 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.c,\$(IDL_FILES)) \\
624 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_\%_c.c,\$(IDL_FILES)) \\
625 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.h,\$(IDL_FILES)): idl
626 __EOD__
627         }
628
629         return $output;
630 }
631
632 ###########################################################
633 # This function creates Makefile.in from the OUTPUT 
634 # context
635 #
636 # create_makefile_in($OUTPUT)
637 #
638 # $OUTPUT       -       the global OUTPUT context
639 #
640 # $output -             the resulting output buffer
641 sub create_makefile_in($$$)
642 {
643         my ($CTX, $mk, $file) = @_;
644
645         open(MAKEFILE_IN,">$file") || die ("Can't open $file\n");
646         print MAKEFILE_IN _prepare_makefile_in($CTX) . $mk;
647         close(MAKEFILE_IN);
648
649         print "build/smb_build/main.pl: creating $file\n";
650         return; 
651 }
652
653 1;