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->{shared_modules} = [];
28 $self->{plugins} = [];
29 $self->{install_plugins} = "";
30 $self->{uninstall_plugins} = "";
31 $self->{pc_files} = [];
32 $self->{proto_headers} = [];
35 $self->{mkfile} = $mkfile;
37 $self->output("#!gmake\n");
38 $self->output("################################################\n");
39 $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
40 $self->output("################################################\n");
43 $self->output("default: all\n\n");
45 $self->_prepare_path_vars();
46 $self->_prepare_compiler_linker();
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}->{modulesdir}
75 INCLUDEDIR = $self->{config}->{includedir}
76 CONFIGDIR = $self->{config}->{sysconfdir}
77 DATADIR = $self->{config}->{datadir}
78 SWATDIR = $self->{config}->{datadir}/swat
79 JSDIR = $self->{config}->{datadir}/js
80 SETUPDIR = $self->{config}->{datadir}/setup
81 VARDIR = $self->{config}->{localstatedir}
82 LOGFILEBASE = $self->{config}->{logfilebase}
83 NCALRPCDIR = $self->{config}->{localstatedir}/ncalrpc
84 LOCKDIR = $self->{config}->{lockdir}
85 PIDDIR = $self->{config}->{piddir}
86 MANDIR = $self->{config}->{mandir}
87 PRIVATEDIR = $self->{config}->{privatedir}
88 WINBINDD_SOCKET_DIR = $self->{config}->{winbindd_socket_dir}
94 sub _prepare_compiler_linker($)
99 my $devld_install = "";
101 $self->{duplicate_build} = 0;
102 if ($self->{config}->{LIBRARY_OUTPUT_TYPE} eq "SHARED_LIBRARY") {
103 if ($self->{developer}) {
104 $self->{duplicate_build} = 1;
105 $devld_local = " -Wl,-rpath,\$(builddir)/bin";
107 $devld_install = " -Wl,-rpath-link,\$(builddir)/bin";
110 $self->output(<< "__EOD__"
111 SHELL=$self->{config}->{SHELL}
113 PERL=$self->{config}->{PERL}
115 CPP=$self->{config}->{CPP}
116 CPPFLAGS=$self->{config}->{CPPFLAGS}
118 CC=$self->{config}->{CC}
119 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} \$(CPPFLAGS)
120 PICFLAG=$self->{config}->{PICFLAG}
121 HOSTCC=$self->{config}->{HOSTCC}
123 LOCAL_LINK_FLAGS=$devld_local
124 INSTALL_LINK_FLAGS=$devld_install
126 LD=$self->{config}->{LD}
127 LDFLAGS=$self->{config}->{LDFLAGS} -L\$(builddir)/bin
129 STLD=$self->{config}->{AR}
130 STLD_FLAGS=-rc -L\$(builddir)/bin
132 SHLD=$self->{config}->{CC}
133 SHLD_FLAGS=$self->{config}->{LDSHFLAGS} -L\$(builddir)/bin
134 SHLIBEXT=$self->{config}->{SHLIBEXT}
136 XSLTPROC=$self->{config}->{XSLTPROC}
138 LEX=$self->{config}->{LEX}
139 YACC=$self->{config}->{YACC}
140 YAPP=$self->{config}->{YAPP}
141 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
143 GCOV=$self->{config}->{GCOV}
145 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
151 sub _prepare_mk_files($)
157 foreach (@smb_build::config_mk::parsed_files) {
162 $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
165 sub array2oneperline($)
171 next unless defined($_);
173 $output .= " \\\n\t\t$_";
179 sub _prepare_list($$$)
181 my ($self,$ctx,$var) = @_;
183 my $tmplist = array2oneperline($ctx->{$var});
184 return if ($tmplist eq "");
186 $self->output("$ctx->{TYPE}\_$ctx->{NAME}_$var =$tmplist\n");
189 sub DependencyInfo($$)
191 my ($self,$ctx) = @_;
193 $self->output("bin/deps/$ctx->{TYPE}_$ctx->{NAME}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)");
195 $self->output("\t\@echo \"Generating dependency info for $ctx->{NAME}\"\n");
196 $self->output("\t\@./script/cdeps.pl \$^ > \$@\n");
198 $self->output("-include bin/deps/$ctx->{TYPE}_$ctx->{NAME}\n\n");
201 sub SharedLibrary($$)
203 my ($self,$ctx) = @_;
208 if ($self->{duplicate_build}) {
209 $installdir = "bin/install";
214 if ($ctx->{TYPE} eq "LIBRARY") {
215 push (@{$self->{shared_libs}}, "bin/$ctx->{LIBRARY_REALNAME}");
216 } elsif ($ctx->{TYPE} eq "MODULE") {
217 push (@{$self->{shared_modules}}, "bin/$ctx->{LIBRARY_REALNAME}");
218 push (@{$self->{plugins}}, "$installdir/$ctx->{LIBRARY_REALNAME}");
220 my $fixedname = $ctx->{NAME};
222 $fixedname =~ s/^$ctx->{SUBSYSTEM}_//g;
224 $self->{install_plugins} .= "\t\@echo Installing $installdir/$ctx->{LIBRARY_REALNAME} as \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
225 $self->{install_plugins} .= "\t\@mkdir -p \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/\n";
226 $self->{install_plugins} .= "\t\@cp $installdir/$ctx->{LIBRARY_REALNAME} \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
227 $self->{uninstall_plugins} .= "\t\@echo Uninstalling \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
228 $self->{uninstall_plugins} .= "\t\@-rm \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
231 $self->_prepare_list($ctx, "OBJ_LIST");
232 $self->_prepare_list($ctx, "CFLAGS");
233 $self->_prepare_list($ctx, "DEPEND_LIST");
234 $self->_prepare_list($ctx, "LINK_LIST");
235 $self->_prepare_list($ctx, "LINK_FLAGS");
237 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
239 if ($ctx->{NOPROTO} eq "NO") {
240 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
243 if ($ctx->{TYPE} eq "MODULE" and defined($ctx->{INIT_FUNCTION})) {
244 my $init_fn = $ctx->{INIT_FUNCTION_TYPE};
245 $init_fn =~ s/\(\*\)/init_module/;
246 my $proto_fn = $ctx->{INIT_FUNCTION_TYPE};
247 $proto_fn =~ s/\(\*\)/$ctx->{INIT_FUNCTION}/;
249 $self->output(<< "__EOD__"
250 bin/$ctx->{NAME}_init_module.c:
252 \@echo \"#include \\\"includes.h\\\"\" > \$\@
253 \@echo \"$proto_fn;\" >> \$\@
254 \@echo -e \"_PUBLIC_ $init_fn \\n{\\n\\treturn $ctx->{INIT_FUNCTION}();\\n}\\n\" >> \$\@
257 $init_obj = "bin/$ctx->{NAME}_init_module.o";
261 if ($self->{config}->{SONAMEFLAG} ne "" and
262 defined($ctx->{LIBRARY_SONAME})) {
263 $soarg = "$self->{config}->{SONAMEFLAG}$ctx->{LIBRARY_SONAME} ";
266 if ($self->{duplicate_build}) {
267 $self->output(<< "__EOD__"
270 bin/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
272 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \\
273 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) $soarg \\
274 $init_obj \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
280 $self->output(<< "__EOD__"
283 $installdir/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
285 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
286 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) $soarg \\
287 $init_obj \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
295 my ($self,$ctx) = @_;
297 return unless $ctx->{TARGET};
299 $self->_prepare_list($ctx, "OBJ_LIST");
300 $self->_prepare_list($ctx, "CFLAGS");
301 $self->_prepare_list($ctx, "DEPEND_LIST");
303 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
305 if ($ctx->{NOPROTO} eq "NO") {
306 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
309 $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
311 $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
312 $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) -o $ctx->{TARGET}\n");
318 my ($self,$ctx) = @_;
320 return unless $ctx->{TARGET};
322 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
324 if ($ctx->{NOPROTO} eq "NO") {
325 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
328 $self->_prepare_list($ctx, "OBJ_LIST");
329 $self->_prepare_list($ctx, "CFLAGS");
330 $self->_prepare_list($ctx, "DEPEND_LIST");
331 $self->output("$ctx->{TARGET}: ");
332 $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
333 $self->output("\t\@touch $ctx->{TARGET}\n");
336 sub StaticLibrary($$)
338 my ($self,$ctx) = @_;
340 push (@{$self->{static_libs}}, $ctx->{OUTPUT});
342 $self->_prepare_list($ctx, "OBJ_LIST");
343 $self->_prepare_list($ctx, "CFLAGS");
345 $self->_prepare_list($ctx, "DEPEND_LIST");
346 $self->_prepare_list($ctx, "LINK_LIST");
347 $self->_prepare_list($ctx, "LINK_FLAGS");
349 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
351 if ($ctx->{NOPROTO} eq "NO") {
352 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
355 $self->output(<< "__EOD__"
357 $ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
359 \@\$(STLD) \$(STLD_FLAGS) \$@ \\
360 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
368 my ($self,$ctx) = @_;
370 foreach (@{$ctx->{PUBLIC_HEADERS}}) {
371 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
377 my ($self,$ctx) = @_;
381 if ($self->{duplicate_build}) {
382 $installdir = "bin/install";
387 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
389 if ($ctx->{NOPROTO} eq "NO") {
390 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
393 unless (defined($ctx->{INSTALLDIR})) {
394 } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") {
395 push (@{$self->{sbin_progs}}, "$installdir/$ctx->{BINARY}");
396 } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
397 push (@{$self->{bin_progs}}, "$installdir/$ctx->{BINARY}");
400 push (@{$self->{binaries}}, "bin/$ctx->{BINARY}");
402 $self->_prepare_list($ctx, "OBJ_LIST");
403 $self->_prepare_list($ctx, "CFLAGS");
404 $self->_prepare_list($ctx, "DEPEND_LIST");
405 $self->_prepare_list($ctx, "LINK_LIST");
406 $self->_prepare_list($ctx, "LINK_FLAGS");
408 if ($self->{duplicate_build}) {
409 $self->output(<< "__EOD__"
411 bin/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) \$(builddir)/dynconfig-devel.o
413 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \\
414 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
415 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) \$(builddir)/dynconfig-devel.o
421 $self->output(<< "__EOD__"
422 $installdir/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) \$(builddir)/dynconfig.o
424 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(INSTALL_LINK_FLAGS) \\
425 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
426 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) \$(builddir)/dynconfig.o
434 my ($self,$ctx) = @_;
436 my $dir = $ctx->{BASEDIR};
440 push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
445 my ($self,$ctx) = @_;
447 my $link_name = $ctx->{NAME};
449 $link_name =~ s/^LIB//g;
450 $link_name = lc($link_name);
452 if (not defined($ctx->{DESCRIPTION})) {
453 warn("$ctx->{NAME} has not DESCRIPTION set, not generating .pc file");
457 my $path = "$ctx->{BASEDIR}/$link_name.pc";
459 push (@{$self->{pc_files}}, $path);
461 smb_build::env::PkgConfig($self,
473 my ($self,$ctx) = @_;
475 my $dir = $ctx->{BASEDIR};
480 if (defined($ctx->{PUBLIC_PROTO_HEADER})) {
481 $comment.= " and $dir/$ctx->{PUBLIC_PROTO_HEADER}";
482 push (@{$self->{proto_headers}}, "$dir/$ctx->{PUBLIC_PROTO_HEADER}");
484 $ctx->{PUBLIC_PROTO_HEADER} = $ctx->{PRIVATE_PROTO_HEADER};
486 push (@{$self->{proto_headers}}, "$dir/$ctx->{PRIVATE_PROTO_HEADER}");
488 $self->output("$dir/$ctx->{PUBLIC_PROTO_HEADER}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)\n");
489 $self->output("\t\@echo \"Creating $dir/$ctx->{PRIVATE_PROTO_HEADER}$comment\"\n");
491 $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");
496 my ($self,$file) = @_;
498 $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
499 $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
500 $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
501 $self->output("BINARIES = " . array2oneperline($self->{binaries}) . "\n");
502 $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
503 $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
504 $self->output("PUBLIC_HEADERS = " . array2oneperline($self->{headers}) . "\n");
505 $self->output("PC_FILES = " . array2oneperline($self->{pc_files}) . "\n");
506 $self->output("ALL_OBJS = " . array2oneperline($self->{all_objs}) . "\n");
507 $self->output("PROTO_OBJS = " . array2oneperline($self->{proto_objs}) . "\n");
508 $self->output("PROTO_HEADERS = " . array2oneperline($self->{proto_headers}) . "\n");
509 $self->output("SHARED_MODULES = " . array2oneperline($self->{shared_modules}) . "\n");
510 $self->output("PLUGINS = " . array2oneperline($self->{plugins}) . "\n");
512 $self->output("\ninstallplugins: \$(PLUGINS)\n".$self->{install_plugins}."\n");
513 $self->output("\nuninstallplugins:\n".$self->{uninstall_plugins}."\n");
515 $self->_prepare_mk_files();
517 if ($self->{developer}) {
518 $self->output(<<__EOD__
520 #-include \$(ALL_OBJS:.o=.d)
526 $self->output($self->{mkfile});
528 open(MAKEFILE,">$file") || die ("Can't open $file\n");
529 print MAKEFILE $self->{output};
532 print __FILE__.": creating $file\n";