2 # - create output for Makefile
4 # Copyright (C) Stefan (metze) Metzmacher 2004
5 # Copyright (C) Jelmer Vernooij 2005
6 # Released under the GNU GPL
8 package smb_build::makefile;
12 use base 'smb_build::env';
16 my ($myname, $config, $mkfile) = @_;
17 my $self = new smb_build::env($config);
19 bless($self, $myname);
21 $self->{manpages} = [];
22 $self->{sbin_progs} = [];
23 $self->{bin_progs} = [];
24 $self->{static_libs} = [];
25 $self->{shared_libs} = [];
26 $self->{headers} = [];
27 $self->{pc_files} = [];
28 $self->{proto_headers} = [];
31 $self->{mkfile} = $mkfile;
33 $self->output("#!gmake\n");
34 $self->output("################################################\n");
35 $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
36 $self->output("################################################\n");
39 $self->output("default: all\n\n");
41 $self->_prepare_path_vars();
42 $self->_prepare_compiler_linker();
43 $self->output(".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 .8 .8.xml .ho\n");
44 $self->_prepare_hostcc_rule();
45 $self->_prepare_std_CC_rule("c","o",'$(PICFLAG)',"Compiling","Rule for std objectfiles");
46 $self->_prepare_std_CC_rule("h","h.gch",'$(PICFLAG)',"Precompiling","Rule for precompiled headerfiles");
53 my ($self, $text) = @_;
55 $self->{output} .= $text;
58 sub _prepare_path_vars($)
62 $self->output(<< "__EOD__"
63 prefix = $self->{config}->{prefix}
64 exec_prefix = $self->{config}->{exec_prefix}
65 selftest_prefix = $self->{config}->{selftest_prefix}
66 VPATH = $self->{config}->{srcdir}
67 srcdir = $self->{config}->{srcdir}
68 builddir = $self->{config}->{builddir}
70 BASEDIR = $self->{config}->{prefix}
71 BINDIR = $self->{config}->{bindir}
72 SBINDIR = $self->{config}->{sbindir}
73 LIBDIR = $self->{config}->{libdir}
74 MODULESDIR = $self->{config}->{libdir}
75 INCLUDEDIR = $self->{config}->{includedir}
76 CONFIGDIR = $self->{config}->{sysconfdir}
77 SWATDIR = $self->{config}->{datadir}/swat
78 JSDIR = $self->{config}->{datadir}/js
79 SETUPDIR = $self->{config}->{datadir}/setup
80 VARDIR = $self->{config}->{localstatedir}
81 LOGFILEBASE = $self->{config}->{logfilebase}
82 NCALRPCDIR = $self->{config}->{localstatedir}/ncalrpc
83 LOCKDIR = $self->{config}->{lockdir}
84 PIDDIR = $self->{config}->{piddir}
85 MANDIR = $self->{config}->{mandir}
86 PRIVATEDIR = $self->{config}->{privatedir}
87 WINBINDD_SOCKET_DIR = $self->{config}->{winbindd_socket_dir}
93 sub _prepare_compiler_linker($)
98 my $devld_install = "";
100 $self->{duplicate_build} = 0;
101 if ($self->{config}->{LIBRARY_OUTPUT_TYPE} eq "SHARED_LIBRARY") {
102 if ($self->{developer}) {
103 $self->{duplicate_build} = 1;
104 $devld_local = " -Wl,-rpath,\$(builddir)/bin";
106 $devld_install = " -Wl,-rpath-link,\$(builddir)/bin";
109 $self->output(<< "__EOD__"
110 SHELL=$self->{config}->{SHELL}
112 PERL=$self->{config}->{PERL}
114 CPP=$self->{config}->{CPP}
115 CPPFLAGS=$self->{config}->{CPPFLAGS}
117 CC=$self->{config}->{CC}
118 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} \$(CPPFLAGS)
119 PICFLAG=$self->{config}->{PICFLAG}
120 HOSTCC=$self->{config}->{HOSTCC}
122 LD=$self->{config}->{LD}
123 LDFLAGS=$self->{config}->{LDFLAGS} -L\$(builddir)/bin
124 LOCAL_LINK_FLAGS=$devld_local
125 INSTALL_LINK_FLAGS=$devld_install
127 STLD=$self->{config}->{AR}
128 STLD_FLAGS=-rc -L\$(builddir)/bin
130 SHLD=$self->{config}->{CC}
131 SHLD_FLAGS=$self->{config}->{LDSHFLAGS} -L\$(builddir)/bin
132 SONAMEFLAG=$self->{config}->{SONAMEFLAG}
133 SHLIBEXT=$self->{config}->{SHLIBEXT}
135 XSLTPROC=$self->{config}->{XSLTPROC}
137 LEX=$self->{config}->{LEX}
138 YACC=$self->{config}->{YACC}
139 YAPP=$self->{config}->{YAPP}
140 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
142 GCOV=$self->{config}->{GCOV}
144 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
150 sub _prepare_mk_files($)
156 foreach (@smb_build::config_mk::parsed_files) {
161 $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
164 sub _prepare_dummy_MAKEDIR($)
168 $self->output(<< '__EOD__'
169 dynconfig.o: dynconfig.c Makefile
171 @$(CC) $(CFLAGS) $(PICFLAG) $(PATH_FLAGS) -c $< -o $@
174 if ($self->{config}->{BROKEN_CC} eq "yes") {
175 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
181 sub _prepare_std_CC_rule($$$$$$)
183 my ($self,$src,$dst,$flags,$message,$comment) = @_;
185 $self->output(<< "__EOD__"
188 \@echo $message \$\*.$src
189 \@\$(CC) `script/cflags.pl \$\@` \$(CFLAGS) $flags -c \$\*.$src -o \$\@
192 if ($self->{config}->{BROKEN_CC} eq "yes") {
193 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\'` $@
200 sub _prepare_hostcc_rule($)
204 $self->output(<< "__EOD__"
206 \@echo Compiling \$\*.c with host compiler
207 \@\$(HOSTCC) `script/cflags.pl \$\@` \$(CFLAGS) -c \$\*.c -o \$\@
210 if ($self->{config}->{BROKEN_CC} eq "yes") {
211 $self->output(' -mv `echo $@ | sed \'s%^.*/%%g\' -e \'s%\.ho$$%.o%\'` $@
218 sub array2oneperline($)
224 next unless defined($_);
226 $output .= " \\\n\t\t$_";
232 sub _prepare_list($$$)
234 my ($self,$ctx,$var) = @_;
236 my $tmplist = array2oneperline($ctx->{$var});
237 return if ($tmplist eq "");
239 $self->output("$ctx->{TYPE}\_$ctx->{NAME}_$var =$tmplist\n");
242 sub DependencyInfo($$)
244 my ($self,$ctx) = @_;
246 $self->output("bin/deps/$ctx->{TYPE}_$ctx->{NAME}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)");
248 $self->output("\t\@echo \"Generating dependency info for $ctx->{NAME}\"\n");
249 $self->output("\t\@./script/cdeps.pl \$^ > \$@\n");
251 $self->output("-include bin/deps/$ctx->{TYPE}_$ctx->{NAME}\n\n");
254 sub SharedLibrary($$)
256 my ($self,$ctx) = @_;
258 push (@{$self->{shared_libs}}, "bin/$ctx->{LIBRARY_REALNAME}");
259 push (@{$self->{shared_modules}}, "bin/$ctx->{LIBRARY_REALNAME}");
261 $self->_prepare_list($ctx, "OBJ_LIST");
262 $self->_prepare_list($ctx, "CFLAGS");
263 $self->_prepare_list($ctx, "DEPEND_LIST");
264 $self->_prepare_list($ctx, "LINK_LIST");
265 $self->_prepare_list($ctx, "LINK_FLAGS");
267 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
269 if ($ctx->{NOPROTO} eq "NO") {
270 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
273 $self->output(<< "__EOD__"
276 bin/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) bin/.dummy
278 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
279 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) \\
280 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
284 if (defined($ctx->{LIBRARY_SONAME})) {
285 $self->output(<< "__EOD__"
286 # Symlink $ctx->{LIBRARY_SONAME}
287 bin/$ctx->{LIBRARY_SONAME}: bin/$ctx->{LIBRARY_REALNAME} bin/.dummy
289 \@ln -sf $ctx->{LIBRARY_REALNAME} \$\@
290 # Symlink $ctx->{LIBRARY_NAME}
291 bin/$ctx->{LIBRARY_NAME}: bin/$ctx->{LIBRARY_SONAME} bin/.dummy
293 \@ln -sf $ctx->{LIBRARY_SONAME} \$\@
302 my ($self,$ctx) = @_;
304 return unless $ctx->{TARGET};
306 $self->_prepare_list($ctx, "OBJ_LIST");
307 $self->_prepare_list($ctx, "CFLAGS");
308 $self->_prepare_list($ctx, "DEPEND_LIST");
310 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
312 if ($ctx->{NOPROTO} eq "NO") {
313 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
316 $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
318 $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
319 $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) -o $ctx->{TARGET}\n");
325 my ($self,$ctx) = @_;
327 return unless $ctx->{TARGET};
329 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
331 if ($ctx->{NOPROTO} eq "NO") {
332 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
335 $self->_prepare_list($ctx, "OBJ_LIST");
336 $self->_prepare_list($ctx, "CFLAGS");
337 $self->_prepare_list($ctx, "DEPEND_LIST");
338 $self->output("$ctx->{TARGET}: ");
339 $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
340 $self->output("\t\@touch $ctx->{TARGET}\n");
343 sub StaticLibrary($$)
345 my ($self,$ctx) = @_;
347 push (@{$self->{static_libs}}, $ctx->{OUTPUT});
349 $self->_prepare_list($ctx, "OBJ_LIST");
350 $self->_prepare_list($ctx, "CFLAGS");
352 $self->_prepare_list($ctx, "DEPEND_LIST");
353 $self->_prepare_list($ctx, "LINK_LIST");
354 $self->_prepare_list($ctx, "LINK_FLAGS");
356 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
358 if ($ctx->{NOPROTO} eq "NO") {
359 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
362 $self->output(<< "__EOD__"
364 $ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) bin/.dummy
366 \@\$(STLD) \$(STLD_FLAGS) \$@ \\
367 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
375 my ($self,$ctx) = @_;
377 foreach (@{$ctx->{PUBLIC_HEADERS}}) {
378 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
384 my ($self,$ctx) = @_;
388 if ($self->{duplicate_build}) {
389 $installdir = "bin/install";
394 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
396 if ($ctx->{NOPROTO} eq "NO") {
397 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
400 unless (defined($ctx->{INSTALLDIR})) {
401 } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") {
402 push (@{$self->{sbin_progs}}, "$installdir/$ctx->{BINARY}");
403 } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
404 push (@{$self->{bin_progs}}, "$installdir/$ctx->{BINARY}");
407 push (@{$self->{binaries}}, "bin/$ctx->{BINARY}");
409 $self->_prepare_list($ctx, "OBJ_LIST");
410 $self->_prepare_list($ctx, "CFLAGS");
411 $self->_prepare_list($ctx, "DEPEND_LIST");
412 $self->_prepare_list($ctx, "LINK_LIST");
413 $self->_prepare_list($ctx, "LINK_FLAGS");
415 if ($self->{duplicate_build}) {
416 $self->output(<< "__EOD__"
418 bin/$ctx->{BINARY}: bin/.dummy \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
420 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \\
421 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
422 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS)
428 $self->output(<< "__EOD__"
429 $installdir/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
431 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(INSTALL_LINK_FLAGS) \\
432 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
433 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS)
441 my ($self,$ctx) = @_;
443 my $dir = $ctx->{BASEDIR};
447 push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
452 my ($self,$ctx) = @_;
454 my $link_name = $ctx->{NAME};
456 $link_name =~ s/^LIB//g;
457 $link_name = lc($link_name);
459 if (not defined($ctx->{DESCRIPTION})) {
460 warn("$ctx->{NAME} has not DESCRIPTION set, not generating .pc file");
464 my $path = "$ctx->{BASEDIR}/$link_name.pc";
466 push (@{$self->{pc_files}}, $path);
468 smb_build::env::PkgConfig($self,
472 join(' ', @{$ctx->{CFLAGS}}),
473 "$ctx->{MAJOR_VERSION}.$ctx->{MINOR_VERSION}.$ctx->{RELEASE_VERSION}",
480 my ($self,$ctx) = @_;
482 my $dir = $ctx->{BASEDIR};
487 if (defined($ctx->{PUBLIC_PROTO_HEADER})) {
488 $comment.= " and $dir/$ctx->{PUBLIC_PROTO_HEADER}";
489 push (@{$self->{proto_headers}}, "$dir/$ctx->{PUBLIC_PROTO_HEADER}");
491 $ctx->{PUBLIC_PROTO_HEADER} = $ctx->{PRIVATE_PROTO_HEADER};
493 push (@{$self->{proto_headers}}, "$dir/$ctx->{PRIVATE_PROTO_HEADER}");
495 $self->output("$dir/$ctx->{PUBLIC_PROTO_HEADER}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)\n");
496 $self->output("\t\@echo \"Creating $dir/$ctx->{PRIVATE_PROTO_HEADER}$comment\"\n");
498 $self->output("\t\@\$(PERL) \$(srcdir)/script/mkproto.pl --private=$dir/$ctx->{PRIVATE_PROTO_HEADER} --public=$dir/$ctx->{PUBLIC_PROTO_HEADER} \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n\n");
503 my ($self,$file) = @_;
505 $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
506 $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
507 $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
508 $self->output("BINARIES = " . array2oneperline($self->{binaries}) . "\n");
509 $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
510 $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
511 $self->output("PUBLIC_HEADERS = " . array2oneperline($self->{headers}) . "\n");
512 $self->output("PC_FILES = " . array2oneperline($self->{pc_files}) . "\n");
513 $self->output("ALL_OBJS = " . array2oneperline($self->{all_objs}) . "\n");
514 $self->output("PROTO_OBJS = " . array2oneperline($self->{proto_objs}) . "\n");
515 $self->output("PROTO_HEADERS = " . array2oneperline($self->{proto_headers}) . "\n");
516 $self->output("SHARED_MODULES = " . array2oneperline($self->{shared_modules}) . "\n");
518 $self->_prepare_mk_files();
520 if ($self->{developer}) {
521 $self->output(<<__EOD__
523 #-include \$(ALL_OBJS:.o=.d)
529 $self->_prepare_dummy_MAKEDIR();
531 $self->output($self->{mkfile});
533 open(MAKEFILE,">$file") || die ("Can't open $file\n");
534 print MAKEFILE $self->{output};
537 print __FILE__.": creating $file\n";