r14332: Built in different paths when running locally (from ./bin/) in developer
[samba.git] / source4 / build / smb_build / makefile.pm
1 # Samba Build System
2 # - create output for Makefile
3 #
4 #  Copyright (C) Stefan (metze) Metzmacher 2004
5 #  Copyright (C) Jelmer Vernooij 2005
6 #  Released under the GNU GPL
7
8 package smb_build::makefile;
9 use smb_build::env;
10 use strict;
11
12 use base 'smb_build::env';
13
14 sub new($$$)
15 {
16         my ($myname, $config, $mkfile) = @_;
17         my $self = new smb_build::env($config);
18         
19         bless($self, $myname);
20
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} = [];
33         $self->{output} = "";
34
35         $self->{mkfile} = $mkfile;
36
37         $self->output("#!gmake\n");
38         $self->output("################################################\n");
39         $self->output("# Autogenerated by build/smb_build/makefile.pm #\n");
40         $self->output("################################################\n");
41         $self->output("\n");
42
43         $self->output("default: all\n\n");
44
45         $self->_prepare_path_vars();
46         $self->_prepare_compiler_linker();
47
48         return $self;
49 }
50
51 sub output($$)
52 {
53         my ($self, $text) = @_;
54
55         $self->{output} .= $text;
56 }
57
58 sub _prepare_path_vars($)
59 {
60         my ($self) = @_;
61
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}
69
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}
89
90 __EOD__
91 );
92 }
93
94 sub _prepare_compiler_linker($)
95 {
96         my ($self) = @_;
97
98         my $devld_local = "";
99         my $devld_install = "";
100
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";
106                 }
107                 $devld_install = " -Wl,-rpath-link,\$(builddir)/bin";
108         }
109
110         $self->output(<< "__EOD__"
111 SHELL=$self->{config}->{SHELL}
112
113 PERL=$self->{config}->{PERL}
114
115 CPP=$self->{config}->{CPP}
116 CPPFLAGS=$self->{config}->{CPPFLAGS}
117
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}
122
123 LOCAL_LINK_FLAGS=$devld_local
124 INSTALL_LINK_FLAGS=$devld_install
125
126 LD=$self->{config}->{LD} 
127 LDFLAGS=$self->{config}->{LDFLAGS} -L\$(builddir)/bin
128
129 STLD=$self->{config}->{AR}
130 STLD_FLAGS=-rc -L\$(builddir)/bin
131
132 SHLD=$self->{config}->{CC}
133 SHLD_FLAGS=$self->{config}->{LDSHFLAGS} -L\$(builddir)/bin
134 SHLIBEXT=$self->{config}->{SHLIBEXT}
135
136 XSLTPROC=$self->{config}->{XSLTPROC}
137
138 LEX=$self->{config}->{LEX}
139 YACC=$self->{config}->{YACC}
140 YAPP=$self->{config}->{YAPP}
141 PIDL_ARGS=$self->{config}->{PIDL_ARGS}
142
143 GCOV=$self->{config}->{GCOV}
144
145 DEFAULT_TEST_TARGET=$self->{config}->{DEFAULT_TEST_TARGET}
146
147 __EOD__
148 );
149 }
150
151 sub _prepare_mk_files($)
152 {
153         my $self = shift;
154         my @tmp = ();
155
156         
157         foreach (@smb_build::config_mk::parsed_files) {
158                 s/ .*$//g;
159                 push (@tmp, $_);
160         }
161
162         $self->output("MK_FILES = " . array2oneperline(\@tmp) . "\n");
163 }
164
165 sub array2oneperline($)
166 {
167         my $array = shift;
168         my $output = "";
169
170         foreach (@$array) {
171                 next unless defined($_);
172
173                 $output .= " \\\n\t\t$_";
174         }
175
176         return $output;
177 }
178
179 sub _prepare_list($$$)
180 {
181         my ($self,$ctx,$var) = @_;
182
183         my $tmplist = array2oneperline($ctx->{$var});
184         return if ($tmplist eq "");
185
186         $self->output("$ctx->{TYPE}\_$ctx->{NAME}_$var =$tmplist\n");
187 }
188
189 sub DependencyInfo($$)
190 {
191         my ($self,$ctx) = @_;
192
193         $self->output("bin/deps/$ctx->{TYPE}_$ctx->{NAME}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST:.o=.c)");
194         $self->output("\n");
195         $self->output("\t\@echo \"Generating dependency info for $ctx->{NAME}\"\n");
196         $self->output("\t\@./script/cdeps.pl \$^ > \$@\n");
197         $self->output("\n");
198         $self->output("-include bin/deps/$ctx->{TYPE}_$ctx->{NAME}\n\n");
199 }
200
201 sub SharedLibrary($$)
202 {
203         my ($self,$ctx) = @_;
204
205         my $installdir;
206         my $init_obj = "";
207         
208         if ($self->{duplicate_build}) {
209                 $installdir = "bin/install";
210         } else {
211                 $installdir = "bin";
212         }
213
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}");
219
220                 my $fixedname = $ctx->{NAME};
221
222                 $fixedname =~ s/^$ctx->{SUBSYSTEM}_//g;
223
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";
229         }
230
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");
236
237         push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
238
239         if ($ctx->{NOPROTO} eq "NO") {
240                 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
241         }
242
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}/;
248
249                 $self->output(<< "__EOD__"
250 bin/$ctx->{NAME}_init_module.c:
251         \@echo Creating \$\@
252         \@echo \"#include \\\"includes.h\\\"\" > \$\@
253         \@echo \"$proto_fn;\" >> \$\@
254         \@echo -e \"_PUBLIC_ $init_fn \\n{\\n\\treturn $ctx->{INIT_FUNCTION}();\\n}\\n\" >> \$\@
255 __EOD__
256 );
257                 $init_obj = "bin/$ctx->{NAME}_init_module.o";
258         }
259
260         my $soarg = "";
261         if ($self->{config}->{SONAMEFLAG} ne "" and 
262                 defined($ctx->{LIBRARY_SONAME})) {
263                 $soarg = "$self->{config}->{SONAMEFLAG}$ctx->{LIBRARY_SONAME} ";
264         }
265
266         if ($self->{duplicate_build}) {
267                 $self->output(<< "__EOD__"
268 #
269
270 bin/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
271         \@echo Linking \$\@
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)
275
276 __EOD__
277 );
278         }
279
280         $self->output(<< "__EOD__"
281 #
282
283 $installdir/$ctx->{LIBRARY_REALNAME}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) $init_obj
284         \@echo Linking \$\@
285         \@\$(SHLD) \$(SHLD_FLAGS) -o \$\@ \\
286                 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) $soarg \\
287                 $init_obj \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
288
289 __EOD__
290 );
291 }
292
293 sub MergedObj($$)
294 {
295         my ($self,$ctx) = @_;
296
297         return unless $ctx->{TARGET};
298
299         $self->_prepare_list($ctx, "OBJ_LIST");
300         $self->_prepare_list($ctx, "CFLAGS");
301         $self->_prepare_list($ctx, "DEPEND_LIST");
302
303         push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
304                 
305         if ($ctx->{NOPROTO} eq "NO") {
306                 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
307         }
308
309         $self->output("$ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)\n");
310
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");
313         $self->output("\n");
314 }
315
316 sub ObjList($$)
317 {
318         my ($self,$ctx) = @_;
319
320         return unless $ctx->{TARGET};
321
322         push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
323                 
324         if ($ctx->{NOPROTO} eq "NO") {
325                 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
326         }
327
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");
334 }
335
336 sub StaticLibrary($$)
337 {
338         my ($self,$ctx) = @_;
339
340         push (@{$self->{static_libs}}, $ctx->{OUTPUT});
341
342         $self->_prepare_list($ctx, "OBJ_LIST");
343         $self->_prepare_list($ctx, "CFLAGS");
344
345         $self->_prepare_list($ctx, "DEPEND_LIST");
346         $self->_prepare_list($ctx, "LINK_LIST");
347         $self->_prepare_list($ctx, "LINK_FLAGS");
348
349         push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
350                 
351         if ($ctx->{NOPROTO} eq "NO") {
352                 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
353         }
354
355         $self->output(<< "__EOD__"
356 #
357 $ctx->{TARGET}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) 
358         \@echo Linking \$@
359         \@\$(STLD) \$(STLD_FLAGS) \$@ \\
360                 \$($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST)
361
362 __EOD__
363 );
364 }
365
366 sub Header($$)
367 {
368         my ($self,$ctx) = @_;
369
370         foreach (@{$ctx->{PUBLIC_HEADERS}}) {
371                 push (@{$self->{headers}}, "$ctx->{BASEDIR}/$_");
372         }
373 }
374
375 sub Binary($$)
376 {
377         my ($self,$ctx) = @_;
378
379         my $installdir;
380         
381         if ($self->{duplicate_build}) {
382                 $installdir = "bin/install";
383         } else {
384                 $installdir = "bin";
385         }
386
387         push(@{$self->{all_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST)");
388                 
389         if ($ctx->{NOPROTO} eq "NO") {
390                 push(@{$self->{proto_objs}}, "\$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST\)");
391         }
392
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}");
398         }
399
400         push (@{$self->{binaries}}, "bin/$ctx->{BINARY}");
401
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");
407
408         if ($self->{duplicate_build}) {
409         $self->output(<< "__EOD__"
410 #
411 bin/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) \$(builddir)/dynconfig-devel.o
412         \@echo Linking \$\@
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
416
417 __EOD__
418 );
419         }
420
421 $self->output(<< "__EOD__"
422 $installdir/$ctx->{BINARY}: \$($ctx->{TYPE}_$ctx->{NAME}_DEPEND_LIST) \$($ctx->{TYPE}_$ctx->{NAME}_OBJ_LIST) \$(builddir)/dynconfig.o
423         \@echo Linking \$\@
424         \@\$(CC) \$(LDFLAGS) -o \$\@ \$(INSTALL_LINK_FLAGS) \\
425                 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_LIST) \\
426                 \$\($ctx->{TYPE}_$ctx->{NAME}_LINK_FLAGS) \$(builddir)/dynconfig.o
427
428 __EOD__
429 );
430 }
431
432 sub Manpage($$)
433 {
434         my ($self,$ctx) = @_;
435
436         my $dir = $ctx->{BASEDIR};
437         
438         $dir =~ s/^\.\///g;
439
440         push (@{$self->{manpages}}, "$dir/$ctx->{MANPAGE}");
441 }
442
443 sub PkgConfig($$)
444 {
445         my ($self,$ctx) = @_;
446         
447         my $link_name = $ctx->{NAME};
448
449         $link_name =~ s/^LIB//g;
450         $link_name = lc($link_name);
451
452         if (not defined($ctx->{DESCRIPTION})) {
453                 warn("$ctx->{NAME} has not DESCRIPTION set, not generating .pc file");
454                 return;
455         }
456
457         my $path = "$ctx->{BASEDIR}/$link_name.pc";
458
459         push (@{$self->{pc_files}}, $path);
460
461         smb_build::env::PkgConfig($self,
462                 $path,
463                 $link_name,
464                 $ctx->{OUTPUT},
465                 "",
466                 "$ctx->{VERSION}",
467                 $ctx->{DESCRIPTION}
468         ); 
469 }
470
471 sub ProtoHeader($$)
472 {
473         my ($self,$ctx) = @_;
474
475         my $dir = $ctx->{BASEDIR};
476
477         $dir =~ s/^\.\///g;
478
479         my $comment = "";
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}");
483         } else {
484                 $ctx->{PUBLIC_PROTO_HEADER} = $ctx->{PRIVATE_PROTO_HEADER};
485         }       
486         push (@{$self->{proto_headers}}, "$dir/$ctx->{PRIVATE_PROTO_HEADER}");
487
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");
490
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");
492 }
493
494 sub write($$)
495 {
496         my ($self,$file) = @_;
497
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");
511
512         $self->output("\ninstallplugins: \$(PLUGINS)\n".$self->{install_plugins}."\n");
513         $self->output("\nuninstallplugins:\n".$self->{uninstall_plugins}."\n");
514
515         $self->_prepare_mk_files();
516
517         if ($self->{developer}) {
518                 $self->output(<<__EOD__
519
520 #-include \$(ALL_OBJS:.o=.d)
521
522 __EOD__
523 );
524         }
525
526         $self->output($self->{mkfile});
527
528         open(MAKEFILE,">$file") || die ("Can't open $file\n");
529         print MAKEFILE $self->{output};
530         close(MAKEFILE);
531
532         print __FILE__.": creating $file\n";
533 }
534
535 1;