r11244: Relative path names in .mk files
[jelmer/samba4-debian.git] / source / build / smb_build / config_mk.pm
1 ###########################################################
2 ### SMB Build System                                    ###
3 ### - config.mk parsing functions                       ###
4 ###                                                     ###
5 ###  Copyright (C) Stefan (metze) Metzmacher 2004       ###
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                 "INIT_FUNCTION"         => "string",
24                 "INIT_OBJ_FILES"        => "list",
25                 "ADD_OBJ_FILES"         => "list",
26                 "OBJ_FILES"             => "list",
27
28                 "REQUIRED_SUBSYSTEMS"   => "list",
29                 "TARGET_DEPS"           => "list",
30
31                 "ENABLE"                => "bool",
32                 "NOPROTO"               => "bool",
33
34                 "MANPAGE"               => "string",
35                 },
36         "MODULE" => {
37                 "SUBSYSTEM"             => "string",
38
39                 "INIT_FUNCTION"         => "string",
40                 "INIT_OBJ_FILES"        => "list",
41                 "ADD_OBJ_FILES"         => "list",
42                 "OBJ_FILES"             => "list",
43
44                 "REQUIRED_SUBSYSTEMS"   => "list",
45                 "TARGET_DEPS"           => "list",
46
47                 "ENABLE"                => "bool",
48                 "NOPROTO"               => "bool",
49
50                 "MANPAGE"               => "string",
51                 },
52         "BINARY" => {
53                 "OBJ_FILES"             => "list",
54
55                 "REQUIRED_SUBSYSTEMS"   => "list",
56                 "TARGET_DEPS"           => "list",
57
58                 "ENABLE"                => "bool",
59                 "NOPROTO"               => "bool",
60
61                 "MANPAGE"               => "string",
62                 "INSTALLDIR"            => "string",
63                 },
64         "LIBRARY" => {
65                 "MAJOR_VERSION"         => "string",
66                 "MINOR_VERSION"         => "string",
67                 "RELEASE_VERSION"       => "string",
68
69                 "OBJ_FILES"             => "list",
70
71                 "REQUIRED_SUBSYSTEMS"   => "list",
72                 "TARGET_DEPS"           => "list",
73
74                 "ENABLE"                => "bool",
75                 "NOPROTO"               => "bool",
76
77                 "MANPAGE"               => "string",
78                 "INSTALLDIR"            => "string",
79                 }
80 };
81
82 use vars qw(@parsed_files);
83
84 @parsed_files = ();
85
86 ###########################################################
87 # The parsing function which parses the file
88 #
89 # $result = _parse_config_mk($filename)
90 #
91 # $filename -   the path of the config.mk file
92 #               which should be parsed
93 sub run_config_mk($$)
94 {
95         sub run_config_mk($$);
96         my ($input, $filename) = @_;
97         my $result;
98         my $linenum = -1;
99         my $infragment = 0;
100         my $section = "GLOBAL";
101         my $makefile = "";
102
103         push (@parsed_files, $filename);
104         
105         open(CONFIG_MK, $filename) or die("Can't open `$filename'\n");
106         my @lines = <CONFIG_MK>;
107         close(CONFIG_MK);
108
109         my $line = "";
110         my $prev = "";
111
112         foreach (@lines) {
113                 $linenum++;
114
115                 # lines beginning with '#' are ignored
116                 next if (/^\#.*$/);
117                 
118                 if (/^(.*)\\$/) {
119                         $prev .= $1;
120                         next;
121                 } else {
122                         $line = "$prev$_";
123                         $prev = "";
124                 }
125
126                 if ($line =~ /^\[([a-zA-Z0-9_:]+)\][\t ]*$/) 
127                 {
128                         $section = $1;
129                         $infragment = 0;
130                         next;
131                 }
132
133                 # include
134                 if ($line =~ /^include (.*)$/) {
135                         $makefile .= run_config_mk($input, dirname($filename)."/$1");
136                         next;
137                 }
138
139                 # empty line
140                 if ($line =~ /^[ \t]*$/) {
141                         $section = "GLOBAL";
142                         if ($infragment) { $makefile.="\n"; }
143                         next;
144                 }
145
146                 # global stuff is considered part of the makefile
147                 if ($section eq "GLOBAL") {
148                         $makefile .= $line;
149                         $infragment = 1;
150                         next;
151                 }
152
153                 
154                 # Assignment
155                 if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) {
156                         $result->{$section}{$1}{VAL} = $2;
157                         $result->{$section}{$1}{KEY} = $1;
158                 
159                         next;
160                 }
161
162                 die("$filename:$linenum: Bad line while parsing $filename");
163         }
164
165         foreach my $section (keys %{$result}) {
166                 my ($type, $name) = split(/::/, $section, 2);
167
168                 my $sectype = $section_types->{$type};
169                 if (not defined($sectype)) {
170                         die($filename.":[".$section."] unknown section type \"".$type."\"!");
171                 }
172
173                 $input->{$name}{NAME} = $name;
174                 $input->{$name}{TYPE} = $type;
175                 $input->{$name}{BASEDIR} = dirname($filename);
176
177                 foreach my $key (values %{$result->{$section}}) {
178                         $key->{VAL} = smb_build::input::strtrim($key->{VAL});
179                         my $vartype = $sectype->{$key->{KEY}};
180                         if (not defined($vartype)) {
181                                 die($filename.":[".$section."]: unknown attribute type \"$key->{KEY}\"!");
182                         }
183                         if ($vartype eq "string") {
184                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
185                         } elsif ($vartype eq "list") {
186                                 $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})];
187                         } elsif ($vartype eq "bool") {
188                                 if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) {
189                                         die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section");
190                                 }
191                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
192                         }
193                 }
194         }
195
196         return $makefile;
197 }
198
199 1;