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->{automatic_deps} = 0;
22 $self->{manpages} = [];
23 $self->{sbin_progs} = [];
24 $self->{bin_progs} = [];
25 $self->{static_libs} = [];
26 $self->{shared_libs} = [];
27 $self->{installable_shared_libs} = [];
28 $self->{headers} = [];
29 $self->{shared_modules} = [];
30 $self->{plugins} = [];
31 $self->{install_plugins} = "";
32 $self->{uninstall_plugins} = "";
33 $self->{pc_files} = [];
34 $self->{proto_headers} = [];
37 $self->{mkfile} = $mkfile;
39 $self->output("#!gmake\n");
40 $self->output("################################################\n");
41 $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
42 $self->output("################################################\n");
45 if (!$self->{automatic_deps}) {
46 $self->output("ALL_PREDEP = proto\n");
49 $self->output("default: all\n\n");
51 $self->_prepare_path_vars();
52 $self->_prepare_compiler_linker();
59 my ($self, $text) = @_;
61 $self->{output} .= $text;
64 sub _prepare_path_vars($)
68 $self->output(<< "__EOD__"
69 prefix = $self->{config}->{prefix}
70 exec_prefix = $self->{config}->{exec_prefix}
71 selftest_prefix = $self->{config}->{selftest_prefix}
72 VPATH = $self->{config}->{srcdir}:heimdal/lib/asn1:heimdal/lib/krb5:heimdal/lib/gssapi:heimdal/lib/hdb
73 srcdir = $self->{config}->{srcdir}
74 builddir = $self->{config}->{builddir}
76 BASEDIR = $self->{config}->{prefix}
77 BINDIR = $self->{config}->{bindir}
78 SBINDIR = $self->{config}->{sbindir}
79 LIBDIR = $self->{config}->{libdir}
80 MODULESDIR = $self->{config}->{modulesdir}
81 INCLUDEDIR = $self->{config}->{includedir}
82 CONFIGDIR = $self->{config}->{sysconfdir}
83 DATADIR = $self->{config}->{datadir}
84 SWATDIR = $self->{config}->{datadir}/swat
85 JSDIR = $self->{config}->{datadir}/js
86 SETUPDIR = $self->{config}->{datadir}/setup
87 VARDIR = $self->{config}->{localstatedir}
88 LOGFILEBASE = $self->{config}->{logfilebase}
89 NCALRPCDIR = $self->{config}->{localstatedir}/ncalrpc
90 LOCKDIR = $self->{config}->{lockdir}
91 PIDDIR = $self->{config}->{piddir}
92 MANDIR = $self->{config}->{mandir}
93 PRIVATEDIR = $self->{config}->{privatedir}
94 WINBINDD_SOCKET_DIR = $self->{config}->{winbindd_socket_dir}
100 sub _prepare_compiler_linker($)
104 my $devld_local = "";
105 my $devld_install = "";
107 $self->{duplicate_build} = 0;
108 if ($self->{config}->{LIBRARY_OUTPUT_TYPE} eq "SHARED_LIBRARY") {
109 if ($self->{developer}) {
110 $self->{duplicate_build} = 1;
111 $devld_local = " -Wl,-rpath,\$(builddir)/bin";
113 $devld_install = " -Wl,-rpath-link,\$(builddir)/bin";
116 $self->output(<< "__EOD__"
117 SHELL=$self->{config}->{SHELL}
119 PERL=$self->{config}->{PERL}
121 CPP=$self->{config}->{CPP}
122 CPPFLAGS=$self->{config}->{CPPFLAGS}
124 CC=$self->{config}->{CC}
125 CFLAGS=-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -D_SAMBA_BUILD_ -DHAVE_CONFIG_H $self->{config}->{CFLAGS} \$(CPPFLAGS)
126 PICFLAG=$self->{config}->{PICFLAG}
127 HOSTCC=$self->{config}->{HOSTCC}
129 LOCAL_LINK_FLAGS=$devld_local
130 INSTALL_LINK_FLAGS=$devld_install
132 LD=$self->{config}->{LD}
133 LDFLAGS=$self->{config}->{LDFLAGS} -L\$(builddir)/bin
135 STLD=$self->{config}->{AR}
136 STLD_FLAGS=-rc -L\$(builddir)/bin
138 SHLD=$self->{config}->{CC}
139 SHLD_FLAGS=$self->{config}->{LDSHFLAGS} -L\$(builddir)/bin
140 SHLIBEXT=$self->{config}->{SHLIBEXT}
142 XSLTPROC=$self->{config}->{XSLTPROC}
144 LEX=$self->{config}->{LEX}
145 YACC=$self->{config}->{YACC}
146 YAPP=$self->{config}->{YAPP}
147 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
149 GCOV=$self->{config}->{GCOV}
151 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
157 sub _prepare_mk_files($)
163 foreach (@smb_build::config_mk::parsed_files) {
168 $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
171 sub array2oneperline($)
177 next unless defined($_);
179 $output .= " \\\n\t\t$_";
185 sub _prepare_list($$$)
187 my ($self,$ctx,$var) = @_;
189 my $tmplist = array2oneperline($ctx->{$var});
190 return if ($tmplist eq "");
192 $self->output("$ctx->{TYPE}\_$ctx->{NAME}_$var =$tmplist\n");
195 sub SharedLibrary($$)
197 my ($self,$ctx) = @_;
202 if ($self->{duplicate_build}) {
203 $installdir = $ctx->{RELEASEDIR};
205 $installdir = $ctx->{DEBUGDIR};
208 if ($ctx->{TYPE} eq "LIBRARY") {
209 push (@{$self->{shared_libs}}, "$ctx->{DEBUGDIR}/$ctx->{LIBRARY_REALNAME}");
210 push (@{$self->{installable_shared_libs}}, "$installdir/$ctx->{LIBRARY_REALNAME}") if (defined($ctx->{SO_VERSION}));
211 } elsif ($ctx->{TYPE} eq "MODULE") {
212 push (@{$self->{shared_modules}}, "$ctx->{DEBUGDIR}/$ctx->{LIBRARY_REALNAME}");
213 push (@{$self->{plugins}}, "$installdir/$ctx->{LIBRARY_REALNAME}");
215 my $fixedname = $ctx->{NAME};
217 $fixedname =~ s/^$ctx->{SUBSYSTEM}_//g;
219 $self->{install_plugins} .= "\t\@echo Installing $installdir/$ctx->{LIBRARY_REALNAME} as \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
220 $self->{install_plugins} .= "\t\@mkdir -p \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/\n";
221 $self->{install_plugins} .= "\t\@cp $installdir/$ctx->{LIBRARY_REALNAME} \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
222 $self->{uninstall_plugins} .= "\t\@echo Uninstalling \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
223 $self->{uninstall_plugins} .= "\t\@-rm \$(DESTDIR)\$(MODULESDIR)/$ctx->{SUBSYSTEM}/$fixedname.\$(SHLIBEXT)\n";
226 $self->_prepare_list($ctx, "OBJ_LIST");
227 $self->_prepare_list($ctx, "CFLAGS");
228 $self->_prepare_list($ctx, "DEPEND_LIST");
229 $self->_prepare_list($ctx, "LINK_LIST");
230 $self->_prepare_list($ctx, "LINK_FLAGS");
232 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
234 if ($ctx->{TYPE} eq "MODULE" and defined($ctx->{INIT_FUNCTION})) {
235 my $init_fn = $ctx->{INIT_FUNCTION_TYPE};
236 $init_fn =~ s/\(\*\)/init_module/;
237 my $proto_fn = $ctx->{INIT_FUNCTION_TYPE};
238 $proto_fn =~ s/\(\*\)/$ctx->{INIT_FUNCTION}/;
240 $self->output(<< "__EOD__"
241 bin/$ctx->{NAME}_init_module.c:
243 \@echo \"#include \\\"includes.h\\\"\" > \$\@
244 \@echo \"$proto_fn;\" >> \$\@
245 \@echo -e \"_PUBLIC_ $init_fn \\n{\\n\\treturn $ctx->{INIT_FUNCTION}();\\n}\\n\" >> \$\@
248 $init_obj = "bin/$ctx->{NAME}_init_module.o";
253 if ($self->{config}->{SONAMEFLAG} ne "" and
254 defined($ctx->{LIBRARY_SONAME})) {
255 $soarg = "$self->{config}->{SONAMEFLAG}$ctx->{LIBRARY_SONAME} ";
256 if ($ctx->{LIBRARY_REALNAME} ne $ctx->{LIBRARY_SONAME}) {
257 $soargdebug = "\t\@ln -fs $ctx->{LIBRARY_REALNAME} $ctx->{DEBUGDIR}/$ctx->{LIBRARY_SONAME}\n";
261 if ($self->{duplicate_build}) {
262 $self->output(<< "__EOD__"
265 $ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
267 \@mkdir -p $ctx->{DEBUGDIR}
268 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \\
269 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) $soarg \\
270 $init_obj \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
276 $self->output(<< "__EOD__"
279 $installdir/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
281 \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
282 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) $soarg \\
283 $init_obj \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
291 my ($self,$ctx) = @_;
293 return unless $ctx->{TARGET};
295 $self->_prepare_list($ctx, "OBJ_LIST");
296 $self->_prepare_list($ctx, "CFLAGS");
297 $self->_prepare_list($ctx, "DEPEND_LIST");
299 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
301 $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
303 $self->output("\t\@echo \"Pre-Linking $ctx->{TYPE} $ctx->{NAME}\"\n");
304 $self->output("\t@\$(LD) -r \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) -o $ctx->{TARGET}\n");
310 my ($self,$ctx) = @_;
312 return unless $ctx->{TARGET};
314 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
316 $self->_prepare_list($ctx, "OBJ_LIST");
317 $self->_prepare_list($ctx, "CFLAGS");
318 $self->_prepare_list($ctx, "DEPEND_LIST");
319 $self->output("$ctx->{TARGET}: ");
320 $self->output("\$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
321 $self->output("\t\@touch $ctx->{TARGET}\n");
324 sub StaticLibrary($$)
326 my ($self,$ctx) = @_;
328 push (@{$self->{static_libs}}, $ctx->{OUTPUT});
330 $self->_prepare_list($ctx, "OBJ_LIST");
331 $self->_prepare_list($ctx, "CFLAGS");
333 $self->_prepare_list($ctx, "DEPEND_LIST");
334 $self->_prepare_list($ctx, "LINK_LIST");
335 $self->_prepare_list($ctx, "LINK_FLAGS");
337 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
339 $self->output(<< "__EOD__"
341 $ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
343 \@\$(STLD) \$(STLD_FLAGS) \$@ \\
344 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
352 my ($self,$ctx) = @_;
354 foreach (@{$ctx->{PUBLIC_HEADERS}}) {
355 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
361 my ($self,$ctx) = @_;
365 if ($self->{duplicate_build}) {
366 $installdir = "bin/install";
371 push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
373 unless (defined($ctx->{INSTALLDIR})) {
374 } elsif ($ctx->{INSTALLDIR} eq "SBINDIR") {
375 push (@{$self->{sbin_progs}}, "$installdir/$ctx->{BINARY}");
376 } elsif ($ctx->{INSTALLDIR} eq "BINDIR") {
377 push (@{$self->{bin_progs}}, "$installdir/$ctx->{BINARY}");
380 push (@{$self->{binaries}}, "bin/$ctx->{BINARY}");
382 $self->_prepare_list($ctx, "OBJ_LIST");
383 $self->_prepare_list($ctx, "CFLAGS");
384 $self->_prepare_list($ctx, "DEPEND_LIST");
385 $self->_prepare_list($ctx, "LINK_LIST");
386 $self->_prepare_list($ctx, "LINK_FLAGS");
388 if ($self->{duplicate_build}) {
389 $self->output(<< "__EOD__"
391 bin/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
393 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(LOCAL_LINK_FLAGS) \$(INSTALL_LINK_FLAGS) \\
394 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
395 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS)
401 $self->output(<< "__EOD__"
402 $installdir/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)
404 \@\$(CC) \$(LDFLAGS) -o \$\@ \$(INSTALL_LINK_FLAGS) \\
405 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
406 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS)
414 my ($self,$ctx) = @_;
416 my $dir = $ctx->{BASEDIR};
420 push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
425 my ($self,$ctx) = @_;
427 my $link_name = $ctx->{NAME};
429 $link_name =~ s/^LIB//g;
430 $link_name = lc($link_name);
432 return if (not defined($ctx->{DESCRIPTION}));
434 my $path = "$ctx->{BASEDIR}/$link_name.pc";
436 push (@{$self->{pc_files}}, $path);
438 smb_build::env::PkgConfig($self,
451 my ($self,$ctx) = @_;
453 my $dir = $ctx->{BASEDIR};
459 my $comment = "Creating ";
460 if (defined($ctx->{PRIVATE_PROTO_HEADER})) {
461 $target.= "$dir/$ctx->{PRIVATE_PROTO_HEADER}";
462 $comment.= "$dir/$ctx->{PRIVATE_PROTO_HEADER}";
463 if (defined($ctx->{PUBLIC_PROTO_HEADER})) {
467 push (@{$self->{proto_headers}}, "$dir/$ctx->{PRIVATE_PROTO_HEADER}");
469 $ctx->{PRIVATE_PROTO_HEADER} = $ctx->{PUBLIC_PROTO_HEADER};
472 if (defined($ctx->{PUBLIC_PROTO_HEADER})) {
473 $comment.= "$dir/$ctx->{PUBLIC_PROTO_HEADER}";
474 $target .= "$dir/$ctx->{PUBLIC_PROTO_HEADER}";
475 push (@{$self->{proto_headers}}, "$dir/$ctx->{PUBLIC_PROTO_HEADER}");
477 $ctx->{PUBLIC_PROTO_HEADER} = $ctx->{PRIVATE_PROTO_HEADER};
480 $self->output("$dir/$ctx->{PUBLIC_PROTO_HEADER}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)\n");
481 $self->output("\t\@echo \"$comment\"\n");
483 $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");
488 my ($self,$file) = @_;
490 $self->output("MANPAGES = ".array2oneperline($self->{manpages})."\n");
491 $self->output("BIN_PROGS = " . array2oneperline($self->{bin_progs}) . "\n");
492 $self->output("SBIN_PROGS = " . array2oneperline($self->{sbin_progs}) . "\n");
493 $self->output("BINARIES = " . array2oneperline($self->{binaries}) . "\n");
494 $self->output("STATIC_LIBS = " . array2oneperline($self->{static_libs}) . "\n");
495 $self->output("SHARED_LIBS = " . array2oneperline($self->{shared_libs}) . "\n");
496 $self->output("INSTALLABLE_SHARED_LIBS = " . array2oneperline($self->{installable_shared_libs}) . "\n");
497 $self->output("PUBLIC_HEADERS = " . array2oneperline($self->{headers}) . "\n");
498 $self->output("PC_FILES = " . array2oneperline($self->{pc_files}) . "\n");
499 $self->output("ALL_OBJS = " . array2oneperline($self->{all_objs}) . "\n");
500 $self->output("PROTO_HEADERS = " . array2oneperline($self->{proto_headers}) . "\n");
501 $self->output("SHARED_MODULES = " . array2oneperline($self->{shared_modules}) . "\n");
502 $self->output("PLUGINS = " . array2oneperline($self->{plugins}) . "\n");
504 $self->output("\ninstallplugins: \$(PLUGINS)\n".$self->{install_plugins}."\n");
505 $self->output("\nuninstallplugins:\n".$self->{uninstall_plugins}."\n");
507 # nasty hack to allow running locally
508 if ($self->{duplicate_build}) {
509 $self->output("bin/libdynconfig.\$(SHLIBEXT): dynconfig-devel.o\n");
510 $self->output("bin/libdynconfig.\$(SHLIBEXT): LIBRARY_DYNCONFIG_OBJ_LIST=dynconfig-devel.o\n");
513 $self->_prepare_mk_files();
515 $self->output($self->{mkfile});
517 if ($self->{automatic_deps}) {
519 ifneq (\$(MAKECMDGOALS),clean)
520 ifneq (\$(MAKECMDGOALS),distclean)
521 ifneq (\$(MAKECMDGOALS),realdistclean)
522 -include \$(DEP_FILES)
528 $self->output("include static_deps.mk\n");
531 open(MAKEFILE,">$file") || die ("Can't open $file\n");
532 print MAKEFILE $self->{output};
535 print __FILE__.": creating $file\n";