1 ###########################################################
2 ### SMB Build System ###
3 ### - create output for Makefile ###
5 ### Copyright (C) Stefan (metze) Metzmacher 2004 ###
6 ### Copyright (C) Jelmer Vernooij 2005 ###
7 ### Released under the GNU GPL ###
8 ###########################################################
10 package smb_build::makefile;
14 use base 'smb_build::env';
18 my ($myname, $config, $CTX, $mkfile) = @_;
19 my $self = new smb_build::env($config);
21 bless($self, $myname);
25 $self->output("################################################\n");
26 $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
27 $self->output("################################################\n");
30 $self->output("default: all\n\n");
32 $self->_prepare_path_vars();
33 $self->_prepare_compiler_linker();
34 $self->_prepare_SUFFIXES();
35 $self->_prepare_hostcc_rule();
36 $self->_prepare_depend_CC_rule();
37 $self->_prepare_std_CC_rule("c","o",'$(PICFLAG)',"Compiling","Rule for std objectfiles");
38 $self->_prepare_std_CC_rule("h","h.gch",'$(PICFLAG)',"Precompiling","Rule for precompiled headerfiles");
40 $self->_prepare_man_rule("1");
41 $self->_prepare_man_rule("3");
42 $self->_prepare_man_rule("5");
43 $self->_prepare_man_rule("7");
45 $self->_prepare_config_status();
47 $self->_prepare_dummy_MAKEDIR($CTX);
48 $self->_prepare_manpages($CTX);
49 $self->_prepare_binaries($CTX);
50 $self->_prepare_target_settings($CTX);
51 $self->_prepare_rule_lists($CTX);
52 $self->_prepare_clean_rules();
54 if ($self->{developer}) {
55 $self->output(<<__EOD__
56 #-include \$(_ALL_OBJS_OBJS:.o=.d)
57 IDL_FILES = \$(wildcard librpc/idl/*.idl)
58 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.c,\$(IDL_FILES)) \\
59 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_\%_c.c,\$(IDL_FILES)) \\
60 \$(patsubst librpc/idl/%.idl,librpc/gen_ndr/ndr_%.h,\$(IDL_FILES)): idl
65 $self->output($mkfile);
72 my ($self, $text) = @_;
74 $self->{output} .= $text;
77 sub _prepare_path_vars($)
81 $self->output(<< "__EOD__"
82 prefix = $self->{config}->{prefix}
83 exec_prefix = $self->{config}->{exec_prefix}
84 selftest_prefix = $self->{config}->{selftest_prefix}
85 VPATH = $self->{config}->{srcdir}
86 srcdir = $self->{config}->{srcdir}
87 builddir = $self->{config}->{builddir}
89 BASEDIR = $self->{config}->{prefix}
90 BINDIR = $self->{config}->{bindir}
91 SBINDIR = $self->{config}->{sbindir}
92 datadir = $self->{config}->{datadir}
93 LIBDIR = $self->{config}->{libdir}
94 CONFIGDIR = $self->{config}->{configdir}
95 localstatedir = $self->{config}->{localstatedir}
96 SWATDIR = $self->{config}->{swatdir}
97 VARDIR = $self->{config}->{localstatedir}
98 LOGFILEBASE = $self->{config}->{logfilebase}
99 NCALRPCDIR = $self->{config}->{localstatedir}/ncalrpc
100 LOCKDIR = $self->{config}->{lockdir}
101 PIDDIR = $self->{config}->{piddir}
102 MANDIR = $self->{config}->{mandir}
103 PRIVATEDIR = $self->{config}->{privatedir}
107 $self->output(<< '__EOD__'
109 # The permissions to give the executables
112 # set these to where to find various files
113 # These can be overridden by command line switches (see smbd(8))
114 # or in smb.conf (see smb.conf(5))
115 CONFIGFILE = $(CONFIGDIR)/smb.conf
116 LMHOSTSFILE = $(CONFIGDIR)/lmhosts
118 PATH_FLAGS = -DCONFIGFILE=\"$(CONFIGFILE)\" -DSBINDIR=\"$(SBINDIR)\" \
119 -DBINDIR=\"$(BINDIR)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\" \
120 -DLOCKDIR=\"$(LOCKDIR)\" -DPIDDIR=\"$(PIDDIR)\" -DLIBDIR=\"$(LIBDIR)\" \
121 -DLOGFILEBASE=\"$(LOGFILEBASE)\" -DSHLIBEXT=\"$(SHLIBEXT)\" \
122 -DCONFIGDIR=\"$(CONFIGDIR)\" -DNCALRPCDIR=\"$(NCALRPCDIR)\" \
123 -DSWATDIR=\"$(SWATDIR)\" -DPRIVATE_DIR=\"$(PRIVATEDIR)\"
128 sub _prepare_compiler_linker($)
132 $self->output(<< "__EOD__"
133 SHELL=$self->{config}->{SHELL}
135 PERL=$self->{config}->{PERL}
137 CC=$self->{config}->{CC}
138 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} $self->{config}->{CPPFLAGS}
139 PICFLAG=$self->{config}->{PICFLAG}
140 HOSTCC=$self->{config}->{HOSTCC}
142 CPP=$self->{config}->{CPP}
143 CPPFLAGS=$self->{config}->{CPPFLAGS}
145 LD=$self->{config}->{LD}
146 LD_FLAGS=$self->{config}->{LDFLAGS}
148 STLD=$self->{config}->{AR}
151 SHLD=$self->{config}->{CC}
152 SHLD_FLAGS=$self->{config}->{LDSHFLAGS}
153 SONAMEFLAG=$self->{config}->{SONAMEFLAG}
154 SHLIBEXT=$self->{config}->{SHLIBEXT}
156 XSLTPROC=$self->{config}->{XSLTPROC}
158 LEX=$self->{config}->{LEX}
159 YACC=$self->{config}->{YACC}
160 YAPP=$self->{config}->{YAPP}
161 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
163 GCOV=$self->{config}->{GCOV}
165 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
171 sub _prepare_SUFFIXES($)
174 $self->output(<< '__EOD__'
175 .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 .ho
181 sub _prepare_man_rule($$)
183 my ($self, $suffix) = @_;
185 $self->output(<< "__EOD__"
186 .$suffix.xml.$suffix:
187 \$(XSLTPROC) -o \$@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \$<
193 sub _prepare_config_status($)
196 my @parsed_files = @smb_build::config_mk::parsed_files;
199 foreach (@parsed_files) {
206 Makefile: config.status $deps
212 sub _prepare_binaries($$)
214 my ($self, $ctx) = @_;
219 foreach (values %$ctx) {
220 next unless defined $_->{OUTPUT_TYPE};
221 next unless ($_->{OUTPUT_TYPE} eq "BINARY");
223 next unless defined($_->{INSTALLDIR});
225 push(@sbn_list, $_->{OUTPUT}) if ($_->{INSTALLDIR} eq "SBINDIR");
226 push(@bbn_list, $_->{OUTPUT}) if ($_->{INSTALLDIR} eq "BINDIR");
229 $self->output("BIN_PROGS = " . array2oneperline(\@bbn_list) . "\n");
230 $self->output("SBIN_PROGS = " . array2oneperline(\@sbn_list) . "\n");
233 sub _prepare_manpages($$)
235 my ($self, $ctx) = @_;
239 foreach (values %$ctx) {
240 my $dir = $_->{BASEDIR};
241 next unless defined($dir);
243 push (@mp_list, "$dir/$_->{MANPAGE}") if (defined($_->{MANPAGE}) and $_->{MANPAGE} ne "");
246 my $mp = array2oneperline(\@mp_list);
247 $self->output("MANPAGES = $mp\n");
250 sub _prepare_dummy_MAKEDIR($$)
252 my ($self,$ctx) = @_;
254 $self->output(<< '__EOD__'
258 dynconfig.o: dynconfig.c Makefile
260 @$(CC) $(CFLAGS) $(PICFLAG) $(PATH_FLAGS) -c $< -o $@
263 if ($self->{config}->{BROKEN_CC} eq "yes") {
264 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
270 sub _prepare_depend_CC_rule($)
273 $self->output(<< '__EOD__'
276 @echo "Generating dependencies for $<"
277 @$(CC) -MM -MG -MT $(<:.c=.o) -MF $@ $(CFLAGS) $<
283 ###########################################################
284 # This function creates a standard make rule which is using $(CC)
286 # $output = _prepare_std_CC_rule($srcext,$destext,$flags,$message,$comment)
288 # $srcext - sourcefile extension
290 # $destext - destinationfile extension
292 # $flags - additional compiler flags
294 # $message - logmessage which is echoed while running this rule
296 # $comment - just a comment what this rule should do
298 # $output - the resulting output buffer
299 sub _prepare_std_CC_rule($$$$$$)
301 my ($self,$src,$dst,$flags,$message,$comment) = @_;
303 $self->output(<< "__EOD__"
306 \@echo $message \$\*.$src
307 \@\$(CC) `script/cflags.sh \$\@` \$(CFLAGS) $flags -c \$< -o \$\@
310 if ($self->{config}->{BROKEN_CC} eq "yes") {
311 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
318 sub _prepare_hostcc_rule($)
322 $self->output(<< "__EOD__"
324 \@echo Compiling \$\*.c with host compiler
325 \@\$(HOSTCC) `script/cflags.sh \$\@` \$(CFLAGS) -c \$< -o \$\@
328 if ($self->{config}->{BROKEN_CC} eq "yes") {
329 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\' -e \'s%\.ho$$%.o%\'` $@
338 sub array2oneperline($)
344 next unless defined($_);
346 $output .= " \\\n\t\t$_";
352 ###########################################################
353 # This function creates a object file list
355 # $output = _prepare_var_obj_list($var, $var_ctx)
357 # $var_ctx - the subsystem context
359 # $var_ctx->{NAME} - the <var> name
360 # $var_ctx->{OBJ_LIST} - the list of objectfiles which sould be linked to this <var>
362 # $output - the resulting output buffer
363 sub _prepare_obj_list($$)
367 my $tmplist = array2oneperline($ctx->{OBJ_LIST});
368 return "" if ($tmplist eq "");
370 return "$var\_$ctx->{NAME}_OBJS =$tmplist\n";
373 sub _prepare_cflags($$)
377 my $tmplist = array2oneperline($ctx->{CFLAGS});
378 return "" if ($tmplist eq "");
380 return "$var\_$ctx->{NAME}_CFLAGS =$tmplist\n";
383 ###########################################################
384 # This function creates a make rule for linking a library
386 # $output = _prepare_shared_library_rule($library_ctx)
388 # $library_ctx - the library context
390 # $library_ctx->{NAME} - the library name
392 # $library_ctx->{DEPEND_LIST} - the list of rules on which this library depends
394 # $library_ctx->{LIBRARY_NAME} - the shared library name
395 # $library_ctx->{LIBRARY_REALNAME} - the shared library real name
396 # $library_ctx->{LIBRARY_SONAME} - the shared library soname
397 # $library_ctx->{LINK_LIST} - the list of objectfiles and external libraries
398 # which sould be linked to this shared library
399 # $library_ctx->{LINK_FLAGS} - linker flags used by this shared library
401 # $output - the resulting output buffer
402 sub _prepare_shared_library_rule($$)
404 my ($self,$ctx) = @_;
406 my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
407 my $tmpshlink = array2oneperline($ctx->{LINK_LIST});
408 my $tmpshflag = array2oneperline($ctx->{LINK_FLAGS});
410 $self->output(<< "__EOD__"
411 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
412 LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST =$tmpshlink
413 LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS =$tmpshflag
416 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
418 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
419 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_FLAGS) \\
420 \$(LIBRARY_$ctx->{NAME}_SHARED_LINK_LIST)
424 if (defined($ctx->{LIBRARY_SONAME})) {
425 $self->output(<< "__EOD__"
426 # Symlink $ctx->{LIBRARY_SONAME}
427 bin/$ctx->{LIBRARY_SONAME}: bin/$ctx->{LIBRARY_REALNAME} bin/.dummy
429 \@ln -sf $ctx->{LIBRARY_REALNAME} \$\@
430 # Symlink $ctx->{LIBRARY_NAME}
431 bin/$ctx->{LIBRARY_NAME}: bin/$ctx->{LIBRARY_SONAME} bin/.dummy
433 \@ln -sf $ctx->{LIBRARY_SONAME} \$\@
439 $self->output("library_$ctx->{NAME}: basics bin/lib$ctx->{LIBRARY_NAME}\n");
442 sub _prepare_mergedobj_rule($$)
444 my ($self,$ctx) = @_;
446 return "" unless $ctx->{TARGET};
448 my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
450 $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
452 $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
454 $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
455 $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJS) -o $ctx->{TARGET}\n");
459 sub _prepare_objlist_rule($$)
461 my ($self,$ctx) = @_;
462 my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
464 return "" unless $ctx->{TARGET};
466 $self->output("$ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST = $tmpdepend\n");
467 $self->output("$ctx->{TARGET}: ");
468 $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJS)\n");
469 $self->output("\t\@touch $ctx->{TARGET}\n");
472 ###########################################################
473 # This function creates a make rule for linking a library
475 # $output = _prepare_static_library_rule($library_ctx)
477 # $library_ctx - the library context
479 # $library_ctx->{NAME} - the library name
481 # $library_ctx->{DEPEND_LIST} - the list of rules on which this library depends
483 # $library_ctx->{LIBRARY_NAME} - the static library name
484 # $library_ctx->{LINK_LIST} - the list of objectfiles which sould be linked
485 # to this static library
486 # $library_ctx->{LINK_FLAGS} - linker flags used by this static library
488 # $output - the resulting output buffer
489 sub _prepare_static_library_rule($$)
491 my ($self,$ctx) = @_;
493 my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
494 my $tmpstlink = array2oneperline($ctx->{LINK_LIST});
495 my $tmpstflag = array2oneperline($ctx->{LINK_FLAGS});
497 $self->output(<< "__EOD__"
498 LIBRARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
500 LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST =$tmpstlink
502 $ctx->{TARGET}: \$(LIBRARY_$ctx->{NAME}_DEPEND_LIST) \$(LIBRARY_$ctx->{NAME}_OBJS) bin/.dummy
504 \@\$(STLD) \$(STLD_FLAGS) \$@ \\
505 \$(LIBRARY_$ctx->{NAME}_STATIC_LINK_LIST)
507 library_$ctx->{NAME}: basics $ctx->{TARGET}
513 ###########################################################
514 # This function creates a make rule for linking a binary
516 # $output = _prepare_binary_rule($binary_ctx)
518 # $binary_ctx - the binary context
520 # $binary_ctx->{NAME} - the binary name
521 # $binary_ctx->{BINARY} - the binary binary name
523 # $binary_ctx->{DEPEND_LIST} - the list of rules on which this binary depends
524 # $binary_ctx->{LINK_LIST} - the list of objectfiles and external libraries
525 # which sould be linked to this binary
526 # $binary_ctx->{LINK_FLAGS} - linker flags used by this binary
528 # $output - the resulting output buffer
529 sub _prepare_binary_rule($$)
531 my ($self,$ctx) = @_;
533 my $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
534 my $tmplink = array2oneperline($ctx->{LINK_LIST});
535 my $tmpflag = array2oneperline($ctx->{LINK_FLAGS});
537 $self->output(<< "__EOD__"
539 BINARY_$ctx->{NAME}_DEPEND_LIST =$tmpdepend
540 BINARY_$ctx->{NAME}_LINK_LIST =$tmplink
541 BINARY_$ctx->{NAME}_LINK_FLAGS =$tmpflag
543 bin/$ctx->{BINARY}: bin/.dummy \$(BINARY_$ctx->{NAME}_DEPEND_LIST) \$(BINARY_$ctx->{NAME}_OBJS)
545 \@\$(CC) \$(LD_FLAGS) -o \$\@ \\
546 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS) \\
547 \$\(BINARY_$ctx->{NAME}_LINK_LIST) \\
548 \$\(BINARY_$ctx->{NAME}_LINK_FLAGS)
549 binary_$ctx->{BINARY}: basics bin/$ctx->{BINARY}
555 sub _prepare_clean_rules($)
558 $self->output(<< '__EOD__'
560 @echo Removing headers
561 @-rm -f include/proto.h
562 @echo Removing objects
563 @-find . -name '*.o' -exec rm -f '{}' \;
564 @echo Removing binaries
565 @-rm -f $(BIN_PROGS) $(SBIN_PROGS)
566 @echo Removing dummy targets
568 @echo Removing generated files
569 @-rm -rf librpc/gen_*
570 @-rm -f lib/registry/regf.h lib/registry/tdr_regf*
574 -rm -f include/config.h include/smb_build.h
577 -rm -f config.log config.cache
578 -rm -f samba4-deps.dot
579 -rm -f config.pm config.mk
580 -rm -f lib/registry/winregistry.pc
583 if ($self->{developer}) {
584 $self->output("\t\@-rm -f \$(_ALL_OBJS_OBJS:.o=.d)\n");
587 $self->output(<< '__EOD__'
590 -rm -f *.bak *~ */*.bak */*~ */*/*.bak */*/*~ */*/*/*.bak */*/*/*~
592 realdistclean: distclean removebackup
593 -rm -f include/config.h.in
594 -rm -f include/version.h
601 sub _prepare_make_target($)
606 $tmpdepend = array2oneperline($ctx->{DEPEND_LIST});
608 return "$ctx->{TARGET}: basics $tmpdepend\n";
611 sub _prepare_target_settings($$)
613 my ($self, $CTX) = @_;
615 foreach my $key (values %$CTX) {
616 if (defined($key->{OBJ_LIST})) {
617 $self->output(_prepare_obj_list($key->{TYPE}, $key));
618 $self->output(_prepare_cflags($key->{TYPE}, $key));
623 sub _prepare_rule_lists($$)
625 my ($self,$depend) = @_;
627 foreach my $key (values %{$depend}) {
628 next unless defined $key->{OUTPUT_TYPE};
630 $self->_prepare_mergedobj_rule($key) if $key->{OUTPUT_TYPE} eq "MERGEDOBJ";
631 $self->_prepare_objlist_rule($key) if $key->{OUTPUT_TYPE} eq "OBJLIST";
632 $self->_prepare_static_library_rule($key) if $key->{OUTPUT_TYPE} eq "STATIC_LIBRARY";
633 $self->_prepare_shared_library_rule($key) if $key->{OUTPUT_TYPE} eq "SHARED_LIBRARY";
634 $self->_prepare_binary_rule($key) if $key->{OUTPUT_TYPE} eq "BINARY";
638 ###########################################################
639 # This function creates Makefile from the OUTPUT
642 # create_makefile($OUTPUT)
644 # $OUTPUT - the global OUTPUT context
646 # $output - the resulting output buffer
649 my ($self,$file) = @_;
651 open(MAKEFILE,">$file") || die ("Can't open $file\n");
652 print MAKEFILE $self->{output};
655 print "build/smb_build/main.pl: creating $file\n";