r8936: Use incremental linking. This appeared to be supported on
[samba.git] / source4 / 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 generate_mergedobj($)
14 {
15         my $subsys = shift;
16
17         $subsys->{OUTPUT} = $subsys->{TARGET} = "bin/$subsys->{TYPE}_$subsys->{NAME}.o";
18 }
19
20 sub generate_objlist($)
21 {
22         my $subsys = shift;
23
24         $subsys->{TARGET} = "bin/.$subsys->{TYPE}_$subsys->{NAME}";
25         $subsys->{OUTPUT} = "\$($subsys->{TYPE}_$subsys->{NAME}_OBJS)";
26 }
27
28 sub generate_shared_library($)
29 {
30         my $lib = shift;
31
32         @{$lib->{DEPEND_LIST}} = ();
33         @{$lib->{LINK_LIST}} = ("\$($lib->{TYPE}_$lib->{NAME}\_OBJS)");
34         $lib->{LIBRARY_NAME} = lc($lib->{NAME}).".so";
35         $lib->{TARGET} = "bin/lib$lib->{LIBRARY_NAME}";
36         if (defined($lib->{MAJOR_VERSION})) {
37                 $lib->{LIBRARY_SONAME} = $lib->{LIBRARY_NAME}.".$lib->{MAJOR_VERSION}";
38                 $lib->{LIBRARY_REALNAME} = $lib->{LIBRARY_SONAME}.".$lib->{MINOR_VERSION}.$lib->{RELEASE_VERSION}";
39                 $lib->{TARGET} = "bin/lib$lib->{LIBRARY_REALNAME}";
40                 @{$lib->{LINK_FLAGS}} = ("\@SONAMEFLAG\@$lib->{LIBRARY_SONAME}");
41         }
42         $lib->{OUTPUT} = "-l".lc($lib->{NAME});
43 }
44
45 sub generate_static_library($)
46 {
47         my $lib = shift;
48
49         @{$lib->{DEPEND_LIST}} = ();
50
51         $lib->{LIBRARY_NAME} = lc($lib->{NAME}).".a";
52         @{$lib->{LINK_LIST}} = ("\$($lib->{TYPE}_$lib->{NAME}\_OBJS)");
53         @{$lib->{LINK_FLAGS}} = ();
54
55         $lib->{TARGET} = "bin/lib$lib->{LIBRARY_NAME}";
56         $lib->{OUTPUT} = "-l".lc($lib->{NAME});
57 }
58
59 sub generate_binary($)
60 {
61         my $bin = shift;
62
63         @{$bin->{DEPEND_LIST}} = ();
64         @{$bin->{LINK_LIST}} = ("\$($bin->{TYPE}_$bin->{NAME}\_OBJS)");
65         @{$bin->{LINK_FLAGS}} = ();
66
67         $bin->{TARGET} = $bin->{OUTPUT} = "bin/$bin->{NAME}";
68         $bin->{BINARY} = $bin->{NAME};
69 }
70
71 sub create_output($)
72 {
73         my $depend = shift;
74         my $part;
75
76         $depend->{PROTO} = {
77                 OUTPUT_TYPE => "OBJLIST",
78                 TYPE => "PROTO",
79                 NAME => "PROTO",
80                 OBJ_LIST => []
81         };
82
83         $depend->{ALL_OBJS} = {
84                 OUTPUT_TYPE => "OBJLIST",
85                 TYPE => "",
86                 NAME => "ALL_OBJS",
87                 OBJ_LIST => []
88         };
89
90         foreach $part (values %{$depend}) {
91                 next if $part->{NAME} eq "PROTO";
92                 next if $part->{NAME} eq "ALL_OBJS";
93                 next if not defined($part->{OUTPUT_TYPE});
94
95                 # Combine object lists
96                 push(@{$part->{OBJ_LIST}}, @{$part->{INIT_OBJ_FILES}}) if defined($part->{INIT_OBJ_FILES});
97                 push(@{$part->{OBJ_LIST}}, @{$part->{ADD_OBJ_FILES}}) if defined($part->{ADD_OBJ_FILES});
98                 push(@{$part->{OBJ_LIST}}, @{$part->{OBJ_FILES}}) if defined($part->{OBJ_FILES});
99
100                 if ((not defined($part->{OBJ_LIST}) or 
101                         scalar(@{$part->{OBJ_LIST}}) == 0) and 
102                         $part->{OUTPUT_TYPE} eq "MERGEDOBJ") {
103                         $part->{OUTPUT_TYPE} = "OBJLIST";
104                 }
105
106                 generate_binary($part) if $part->{OUTPUT_TYPE} eq "BINARY";
107                 generate_mergedobj($part) if $part->{OUTPUT_TYPE} eq "MERGEDOBJ";
108                 generate_objlist($part) if $part->{OUTPUT_TYPE} eq "OBJLIST";
109                 generate_shared_library($part) if $part->{OUTPUT_TYPE} eq "SHARED_LIBRARY";
110                 generate_static_library($part) if $part->{OUTPUT_TYPE} eq "STATIC_LIBRARY";
111
112
113                 push(@{$depend->{ALL_OBJS}->{OBJ_LIST}}, @{$part->{OBJ_LIST}}) if (defined(@{$part->{OBJ_LIST}}));
114                 
115                 if ((not defined ($part->{NOPROTO})) or ($part->{NOPROTO} eq "NO")) {
116                         push(@{$depend->{PROTO}->{OBJ_LIST}}, @{$part->{OBJ_LIST}}) if (defined(@{$part->{OBJ_LIST}}));
117                 }
118         }
119
120         foreach $part (values %{$depend}) {
121                 next if not defined($part->{OUTPUT_TYPE});
122
123                 foreach (@{$part->{DEPENDENCIES}}) {
124                         my $elem = $$_;
125                         push(@{$part->{DEPEND_LIST}}, $elem->{TARGET}) if defined($elem->{TARGET});
126                 }
127
128                 # Always import the CFLAGS and CPPFLAGS of the unique dependencies
129                 foreach my $elem (values %{$part->{UNIQUE_DEPENDENCIES}}) {
130                         next if $elem == $part;
131
132                         push(@{$part->{CPPFLAGS}}, @{$elem->{CPPFLAGS}}) if defined(@{$elem->{CPPFLAGS}});
133                         push(@{$part->{CFLAGS}}, @{$elem->{CFLAGS}}) if defined(@{$elem->{CFLAGS}});
134                         push(@{$part->{LINK_LIST}}, $elem->{OUTPUT}) if defined($elem->{OUTPUT});
135                         push(@{$part->{LINK_FLAGS}}, @{$elem->{LIBS}}) if defined($elem->{LIBS});
136                         push(@{$part->{LINK_FLAGS}},@{$elem->{LDFLAGS}}) if defined($elem->{LDFLAGS});
137
138                         push(@{$part->{SUBSYSTEM_INIT_FUNCTIONS}}, $elem->{INIT_FUNCTION}) if 
139                                 $part->{OUTPUT_TYPE} eq "BINARY" and 
140                                 defined($elem->{INIT_FUNCTION}) and 
141                                 $elem->{INIT_FUNCTION} ne "" and
142                                 $part->{OUTPUT_TYPE} ne "SHARED_LIBRARY";
143                 }
144         }
145
146         return $depend;
147 }
148
149 1;