r15207: Introduce PRIVATE_DEPENDENCIES and PUBLIC_DEPENDENCIES as replacement
[samba.git] / source / build / smb_build / config_mk.pm
1 # Samba Build System
2 # - config.mk parsing functions
3 #
4 #  Copyright (C) Stefan (metze) Metzmacher 2004
5 #  Copyright (C) Jelmer Vernooij 2005
6 #  Released under the GNU GPL
7 #
8
9 package smb_build::config_mk;
10 use smb_build::input;
11 use File::Basename;
12
13 use strict;
14
15 my $section_types = {
16         "EXT_LIB" => {
17                 "LIBS"                  => "list",
18                 "CFLAGS"                => "list",
19                 "CPPFLAGS"              => "list",
20                 "LDFLAGS"               => "list",
21                 },
22         "SUBSYSTEM" => {
23                 "OBJ_FILES"             => "list",
24
25                 "PRIVATE_DEPENDENCIES"  => "list",
26                 "PUBLIC_DEPENDENCIES"   => "list",
27
28                 "ENABLE"                => "bool",
29
30                 "MANPAGE"               => "string",
31
32                 "PUBLIC_PROTO_HEADER"   => "string",
33                 "PRIVATE_PROTO_HEADER"  => "string",
34
35                 "PUBLIC_HEADERS"        => "list",
36
37                 "EXTRA_CFLAGS"          => "string",
38                 "STANDARD_VISIBILITY"   => "string"
39                 },
40         "MODULE" => {
41                 "SUBSYSTEM"             => "string",
42
43                 "INIT_FUNCTION"         => "string",
44                 "OBJ_FILES"             => "list",
45
46                 "PUBLIC_DEPENDENCIES"   => "list",
47                 "PRIVATE_DEPENDENCIES"  => "list",
48
49                 "ALIASES" => "list",
50
51                 "ENABLE"                => "bool",
52
53                 "OUTPUT_TYPE"           => "string",
54
55                 "MANPAGE"               => "string",
56                 "PRIVATE_PROTO_HEADER"  => "string",
57
58                 "EXTRA_CFLAGS"          => "string"
59                 },
60         "BINARY" => {
61                 "OBJ_FILES"             => "list",
62
63                 "PRIVATE_DEPENDENCIES"  => "list",
64
65                 "ENABLE"                => "bool",
66
67                 "MANPAGE"               => "string",
68                 "INSTALLDIR"            => "string",
69                 "PRIVATE_PROTO_HEADER"  => "string",
70                 "PUBLIC_PROTO_HEADER"   => "string",
71                 "PUBLIC_HEADERS"        => "list", 
72
73                 "EXTRA_CFLAGS"          => "string",
74                 "STANDARD_VISIBILITY"   => "string"
75                 },
76         "LIBRARY" => {
77                 "VERSION"               => "string",
78                 "SO_VERSION"            => "string",
79                 "LIBRARY_REALNAME" => "string",
80                 
81                 "INIT_FUNCTION_TYPE"    => "string",
82
83                 "OBJ_FILES"             => "list",
84
85                 "DESCRIPTION"           => "string",
86
87                 "PRIVATE_DEPENDENCIES"  => "list",
88                 "PUBLIC_DEPENDENCIES"   => "list",
89
90                 "ENABLE"                => "bool",
91
92                 "MANPAGE"               => "string",
93
94                 "PUBLIC_HEADERS"        => "list",
95
96                 "PUBLIC_PROTO_HEADER"   => "string",
97                 "PRIVATE_PROTO_HEADER"  => "string",
98
99                 "EXTRA_CFLAGS"          => "string",
100                 "STANDARD_VISIBILITY"   => "string"
101                 }
102 };
103
104 use vars qw(@parsed_files);
105
106 @parsed_files = ();
107
108 ###########################################################
109 # The parsing function which parses the file
110 #
111 # $result = _parse_config_mk($filename)
112 #
113 # $filename -   the path of the config.mk file
114 #               which should be parsed
115 sub run_config_mk($$$$)
116 {
117         sub run_config_mk($$$$);
118         my ($input, $srcdir, $builddir, $filename) = @_;
119         my $result;
120         my $linenum = -1;
121         my $infragment = 0;
122         my $section = "GLOBAL";
123         my $makefile = "";
124
125         my $parsing_file = $builddir."/".$filename;
126
127         $ENV{samba_builddir} = $builddir;
128         $ENV{samba_srcdir} = $srcdir;
129         
130         if (!open(CONFIG_MK, $parsing_file)) { 
131                 $parsing_file = $srcdir."/".$filename;
132                 open(CONFIG_MK, $parsing_file) or 
133                     die("Can't open neither `$builddir."/".$filename' nor `$srcdir/$filename'\n");
134         }
135         
136         push (@parsed_files, $parsing_file);
137         
138         
139         my @lines = <CONFIG_MK>;
140         close(CONFIG_MK);
141
142         my $line = "";
143         my $prev = "";
144
145         foreach (@lines) {
146                 $linenum++;
147
148                 # lines beginning with '#' are ignored
149                 next if (/^\#.*$/);
150                 
151                 if (/^(.*)\\$/) {
152                         $prev .= $1;
153                         next;
154                 } else {
155                         $line = "$prev$_";
156                         $prev = "";
157                 }
158
159                 if ($line =~ /^\[([-a-zA-Z0-9_:]+)\][\t ]*$/) 
160                 {
161                         $section = $1;
162                         $infragment = 0;
163                         next;
164                 }
165
166                 # include
167                 if ($line =~ /^include (.*)$/) {
168                         $makefile .= run_config_mk($input, $srcdir, $builddir, dirname($filename)."/$1");
169                         next;
170                 }
171
172                 # empty line
173                 if ($line =~ /^[ \t]*$/) {
174                         $section = "GLOBAL";
175                         if ($infragment) { $makefile.="\n"; }
176                         next;
177                 }
178
179                 # global stuff is considered part of the makefile
180                 if ($section eq "GLOBAL") {
181                         if (!$infragment) { $makefile.="\n"; }
182                         $makefile .= $line;
183                         $infragment = 1;
184                         next;
185                 }
186
187                 
188                 # Assignment
189                 if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) {
190                         $result->{$section}{$1}{VAL} = $2;
191                         $result->{$section}{$1}{KEY} = $1;
192                 
193                         next;
194                 }
195
196                 die("$srcdir."/".$filename:$linenum: Bad line while parsing $srcdir."/".$filename");
197         }
198
199         foreach my $section (keys %{$result}) {
200                 my ($type, $name) = split(/::/, $section, 2);
201
202                 my $sectype = $section_types->{$type};
203                 if (not defined($sectype)) {
204                         die($srcdir."/".$filename.":[".$section."] unknown section type \"".$type."\"!");
205                 }
206
207                 $input->{$name}{NAME} = $name;
208                 $input->{$name}{TYPE} = $type;
209                 $input->{$name}{MK_FILE} = $srcdir."/".$filename;
210                 $input->{$name}{BASEDIR} = dirname($filename);
211
212                 foreach my $key (values %{$result->{$section}}) {
213                         $key->{VAL} = smb_build::input::strtrim($key->{VAL});
214                         my $vartype = $sectype->{$key->{KEY}};
215                         if (not defined($vartype)) {
216                                 die($srcdir."/".$filename.":[".$section."]: unknown attribute type \"$key->{KEY}\"!");
217                         }
218                         if ($vartype eq "string") {
219                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
220                         } elsif ($vartype eq "list") {
221                                 $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})];
222                         } elsif ($vartype eq "bool") {
223                                 if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) {
224                                         die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section");
225                                 }
226                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
227                         }
228                 }
229         }
230
231         return $makefile;
232 }
233
234 1;