r11382: Require number of required M4 macros
[samba.git] / source / build / smb_build / output.pm
1 ###########################################################
2 ### SMB Build System                                    ###
3 ### - the output generating functions                   ###
4 ###                                                     ###
5 ###  Copyright (C) Stefan (metze) Metzmacher 2004       ###
6 ###  Copyright (C) Jelmer Vernooij 2004 ###
7 ###  Released under the GNU GPL                         ###
8 ###########################################################
9
10 package output;
11 use strict;
12
13 sub add_dir($$)
14 {
15         my ($dir,$files) = @_;
16         my @ret = ();
17
18         $dir =~ s/^\.\///g;
19         
20         foreach (@$files) {
21                 $_ = "$dir/$_";
22                 s/([^\/\.]+)\/\.\.\///g;
23                 push (@ret, $_);
24         }
25         
26         return @ret;
27 }
28
29 sub generate_mergedobj($)
30 {
31         my $subsys = shift;
32
33         $subsys->{OUTPUT} = $subsys->{TARGET} = "bin/subsystems/$subsys->{TYPE}_$subsys->{NAME}.o";
34 }
35
36 sub generate_objlist($)
37 {
38         my $subsys = shift;
39
40         $subsys->{TARGET} = "bin/.$subsys->{TYPE}_$subsys->{NAME}";
41         $subsys->{OUTPUT} = "\$($subsys->{TYPE}_$subsys->{NAME}_OBJS)";
42 }
43
44 sub generate_shared_library($)
45 {
46         my $lib = shift;
47         my $link_name;
48
49         @{$lib->{DEPEND_LIST}} = ();
50         @{$lib->{LINK_LIST}} = ("\$($lib->{TYPE}_$lib->{NAME}\_OBJS)");
51
52         $link_name = $lib->{NAME};
53         $link_name =~ s/^LIB//;
54         $link_name = lc($link_name);
55
56         $lib->{LIBRARY_NAME} = "lib$link_name.\$(SHLIBEXT)";
57         $lib->{TARGET} = "bin/$lib->{LIBRARY_NAME}";
58         if (defined($lib->{MAJOR_VERSION})) {
59                 $lib->{LIBRARY_SONAME} = $lib->{LIBRARY_NAME}.".$lib->{MAJOR_VERSION}";
60                 $lib->{LIBRARY_REALNAME} = $lib->{LIBRARY_SONAME}.".$lib->{MINOR_VERSION}.$lib->{RELEASE_VERSION}";
61                 $lib->{TARGET} = "bin/$lib->{LIBRARY_REALNAME}";
62                 @{$lib->{LINK_FLAGS}} = ("\$(SONAMEFLAG)$lib->{LIBRARY_SONAME}");
63         }
64         $lib->{OUTPUT} = "-l$link_name";
65 }
66
67 sub generate_static_library($)
68 {
69         my $lib = shift;
70         my $link_name;
71
72         @{$lib->{DEPEND_LIST}} = ();
73
74         $link_name = $lib->{NAME};
75         $link_name =~ s/^LIB//;
76
77         $lib->{LIBRARY_NAME} = "lib".lc($link_name).".a";
78         @{$lib->{LINK_LIST}} = ("\$($lib->{TYPE}_$lib->{NAME}\_OBJS)");
79         @{$lib->{LINK_FLAGS}} = ();
80
81         $lib->{TARGET} = "bin/$lib->{LIBRARY_NAME}";
82         $lib->{OUTPUT} = "-l".lc($link_name);
83 }
84
85 sub generate_binary($)
86 {
87         my $bin = shift;
88
89         @{$bin->{DEPEND_LIST}} = ();
90         @{$bin->{LINK_LIST}} = ("\$($bin->{TYPE}_$bin->{NAME}\_OBJS)");
91         @{$bin->{LINK_FLAGS}} = ();
92
93         $bin->{TARGET} = $bin->{OUTPUT} = "bin/$bin->{NAME}";
94         $bin->{BINARY} = $bin->{NAME};
95 }
96
97 sub create_output($)
98 {
99         my $depend = shift;
100         my $part;
101
102         $depend->{PROTO} = {
103                 OUTPUT_TYPE => "OBJLIST",
104                 TYPE => "PROTO",
105                 NAME => "PROTO",
106                 OBJ_LIST => []
107         };
108
109         $depend->{ALL_OBJS} = {
110                 OUTPUT_TYPE => "OBJLIST",
111                 TYPE => "",
112                 NAME => "ALL_OBJS",
113                 OBJ_LIST => []
114         };
115
116         foreach $part (values %{$depend}) {
117                 next if $part->{NAME} eq "PROTO";
118                 next if $part->{NAME} eq "ALL_OBJS";
119                 next if not defined($part->{OUTPUT_TYPE});
120
121                 # Combine object lists
122                 push(@{$part->{OBJ_LIST}}, add_dir($part->{BASEDIR}, $part->{INIT_OBJ_FILES})) if defined($part->{INIT_OBJ_FILES});
123                 push(@{$part->{OBJ_LIST}}, add_dir($part->{BASEDIR}, $part->{ADD_OBJ_FILES})) if defined($part->{ADD_OBJ_FILES});
124                 push(@{$part->{OBJ_LIST}}, add_dir($part->{BASEDIR}, $part->{OBJ_FILES})) if defined($part->{OBJ_FILES});
125
126                 if ((not defined($part->{OBJ_LIST}) or 
127                         scalar(@{$part->{OBJ_LIST}}) == 0) and 
128                         $part->{OUTPUT_TYPE} eq "MERGEDOBJ") {
129                         $part->{OUTPUT_TYPE} = "OBJLIST";
130                 }
131
132                 generate_binary($part) if $part->{OUTPUT_TYPE} eq "BINARY";
133                 generate_mergedobj($part) if $part->{OUTPUT_TYPE} eq "MERGEDOBJ";
134                 generate_objlist($part) if $part->{OUTPUT_TYPE} eq "OBJLIST";
135                 generate_shared_library($part) if $part->{OUTPUT_TYPE} eq "SHARED_LIBRARY";
136                 generate_static_library($part) if $part->{OUTPUT_TYPE} eq "STATIC_LIBRARY";
137
138
139                 push(@{$depend->{ALL_OBJS}->{OBJ_LIST}}, @{$part->{OBJ_LIST}}) if (defined(@{$part->{OBJ_LIST}}));
140                 
141                 if ((not defined ($part->{NOPROTO})) or ($part->{NOPROTO} eq "NO")) {
142                         push(@{$depend->{PROTO}->{OBJ_LIST}}, @{$part->{OBJ_LIST}}) if (defined(@{$part->{OBJ_LIST}}));
143                 }
144         }
145
146         foreach $part (values %{$depend}) {
147                 next if not defined($part->{OUTPUT_TYPE});
148
149                 # Always import the CFLAGS and CPPFLAGS of the unique dependencies
150                 foreach my $elem (values %{$part->{UNIQUE_DEPENDENCIES}}) {
151                         next if $elem == $part;
152
153                         push(@{$part->{CPPFLAGS}}, @{$elem->{CPPFLAGS}}) if defined(@{$elem->{CPPFLAGS}});
154                         push(@{$part->{CFLAGS}}, @{$elem->{CFLAGS}}) if defined(@{$elem->{CFLAGS}});
155                         push(@{$part->{LINK_LIST}}, $elem->{OUTPUT}) if defined($elem->{OUTPUT});
156                         push(@{$part->{LINK_FLAGS}}, @{$elem->{LIBS}}) if defined($elem->{LIBS});
157                         push(@{$part->{LINK_FLAGS}},@{$elem->{LDFLAGS}}) if defined($elem->{LDFLAGS});
158                         if (defined($elem->{OUTPUT_TYPE}) and ($elem->{OUTPUT_TYPE} eq "SHARED_LIBRARY")) {
159                             push(@{$part->{DEPEND_LIST}}, "bin/$elem->{LIBRARY_NAME}");                     
160                         } else { 
161                             push(@{$part->{DEPEND_LIST}}, $elem->{TARGET}) if defined($elem->{TARGET});
162                         }
163                         push(@{$part->{SUBSYSTEM_INIT_FUNCTIONS}}, $elem->{INIT_FUNCTION}) if 
164                         #$part->{OUTPUT_TYPE} eq "BINARY" and 
165                                 defined($elem->{INIT_FUNCTION}) and 
166                                 $part->{OUTPUT_TYPE} ne "SHARED_LIBRARY";
167                 }
168         }
169
170         return $depend;
171 }
172
173 1;