~ubuntu-branches/ubuntu/oneiric/kdesdk/oneiric-updates

1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
1
#!/usr/bin/perl
1.1.46 by Alessandro Ghersi
Import upstream version 4.4.92
2
# Copyright (C) 2006-2010 Thomas Zander <zander@kde.org>
1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
3
$COMMAND = "unsercmake";
1.1.46 by Alessandro Ghersi
Import upstream version 4.4.92
4
$VERSION = "$COMMAND 0.32";
1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
5
# This script allows you to build a target library including dependency checking, but it
6
# limits the dependency checking to the current dir and its subdirs meaning a lot of
7
# unwanted steps are skipped.
8
9
10
# user settings...
11
# if we assume the user has something like:  /kde/project as a sourcedir and /kde/current/project
12
# as a build dir then we can auto-switch between those dirs
13
# Please alter the variable to set the basedir and the builddir.  Like this:
14
#  BASE=BUILD
15
# Examples:
16
#  $buildDirType = "/kde=/kde/current";
17
#  $buildDirType = "kde/{project}=kde/{project}/build";
18
$buildDirType = "";
19
20
##########################
1.1.46 by Alessandro Ghersi
Import upstream version 4.4.92
21
# Copyright (c) 2006-2010 Thomas Zander <zander@kde.org>
1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
22
#
23
# This program is free software; you can redistribute it and/or modify
24
# it under the terms of the GNU General Public License as published by
25
# the Free Software Foundation; either version 2 of the License,
26
# or (at your option) any later version.
27
#
28
# This program is distributed in the hope that it will be useful,
29
# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
# GNU General Public License for more details.
32
#
33
# You should have received a copy of the GNU General Public License
34
# along with this program; if not, write to the Free Software
35
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
36
37
if ($buildDirType eq "") {
38
    print "Not setup!\n";
39
    print "  This tool can automatically switch from your source dir to the builddir.\n";
40
    print "  To do this correctly you have to alter the $COMMAND using your editor\n";
41
    print "  and alter the buildDirType variable according to the comments.\n";
42
    exit;
43
}
44
45
#argument options
46
$argMap{"C"}="directory";
47
$argMap{"j"}="jobs";
48
$argMap{"n"}="just-print";
49
$argMap{"v"}="verbose";
50
$argMap{"k"}="keep-going";
51
$argMap{"p"}="projecthelp";
52
$argMap{"h"}="help";
53
$argMap{"e"}="exclude";
54
$argMap{"q"}="quiet";
55
@options=split(" ", "help directory jobs just-print verbose keep-going version projecthelp exclude quiet");
56
@argCommands=split(" ","directory jobs exclude");
57
58
&parseArguments(@ARGV);
59
if(defined $help) {
60
    print "Usage: $COMMAND [OPTION] ...\n";
61
    print "Available options:\n\n";
62
    print "  -h,	--help     	This help.\n";
63
    print "  -p 	--projecthelp	print project help information\n";
64
    print "  -j,	--jobs=N	Allow N parallel jobs.\n";
65
    print "  -k,	--keep-going	Keep going when some targets can't be made.\n";
66
    print "  -C,	--directory=dir	Change to directory dir before doing anything.\n";
67
    print "  -v,	--verbose	Show verbose output.\n";
68
    print "     	--version	Show version information and copyright notice.\n";
69
    print "  -n 	--just-print	Only print out the commands to call.\n";
70
    print "  -q 	--quiet     	Don't print details\n";
71
    print "  -e 	--exclude=RegEx	Exclude libraries and subdirs based on a regular expression\n";
72
    exit;
73
}
74
75
if(defined $version) {
76
    print "$VERSION\nWritten by Thomas Zander\n\nThis is free software see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
77
    exit;
78
}
79
80
if(defined $directory) {
81
    chdir $directory || die "Failed to change directory to '$directory'\n";
82
}
83
84
while(! -f "CMakeFiles" && ! -f "CMakeLists.txt") {
85
    # for the case where there is a subdir but that subdir does not have a cmakefile
86
    chdir ".." || die "Error: Can not find a cmake based basedir\nPlease start from the source dir\n";
87
    if(`pwd` eq "/\n") {
88
        die "Error: Can not find a cmake based basedir\nPlease start from the source dir\n";
89
    }
90
}
91
92
$dir=`pwd`;
93
chomp($dir);
94
$builddir = "$dir/";
95
96
# find the build-dir where the Makefile lives
97
@bd = split("=", $buildDirType);
98
if($#bd > 0) {
99
    # make sure slashes are all round
100
    $bd[0]="/$bd[0]/";
101
    $bd[1]="/$bd[1]/";
102
    $bd[0]=~s/\/\//\//g;
103
    $bd[1]=~s/\/\//\//g;
104
    my $wildcard="";
105
    if($bd[0]=~/(\{.*\})/) { # used {project} wildcard
106
        $wildcard=$1;
107
        if($bd[1]=~/$wildcard/) {
108
            $bd[0]=~s/$wildcard/(.*?)/;
109
        }
110
    }
111
    if($builddir=~/$bd[0]/ && $builddir=~/$bd[1]/ == false) {
112
        my $project=$wildcard;
113
        $builddir=~/$bd[0]/;
114
        if($builddir=~m/$bd[0]/) {
115
            $project=$1;
116
        }
117
        $builddir=~s/$bd[0]/$bd[1]/;
118
        if($wildcard ne "" && $project ne "") {
119
            $builddir=~s/$wildcard/$project/;
120
        }
121
        #print "$dir => $builddir\n";
122
    }
123
}
124
125
$makeDependNeeded = 0;
126
&readCmakeFile(".");
127
128
if(defined $projecthelp) {
129
    print "\nLibraries:\n\n";
130
    foreach $key (sort {uc($a) cmp uc($b)} @libraries) {
131
        print " $key";
132
        if(defined $exclude && $key=~/$exclude/) {
133
            print "  [excluded]";
134
        }
135
        print "\n";
136
    }
137
    exit;
138
}
139
140
$doInstall = 0;
141
if($#userArgs >= 0) { # limit to user request
142
    foreach $lib (@userArgs) {
143
        if($lib eq "install") {
144
            $doInstall = 1;
145
            if($#userArgs == 0) {
146
                @targets = @libraries;
147
            }
148
            next;
149
        }
150
151
        my $pureLib = $lib;
152
        $pureLib=~s/^[\/ \\]*//;
153
        $pureLib=~s/[\/ \\]*$//;
154
        if(&contains($pureLib, @libraries)) {
155
            push @targets, $pureLib;
156
        }
157
        else {
158
            push @nonLibTargets, $lib;
159
        }
160
    }
161
}
162
else {
163
    @targets=@libraries;
164
}
165
166
foreach $lib (@targets) { # add dependencies
167
    @deps = &dependencies(0, $lib);
168
    LIB: foreach $l (@deps) {
169
        if($l eq "ERROR") {
170
            exit 1;
171
        }
172
        if(defined $exclude && $l=~/$exclude/) {
173
            next;
174
        }
175
        foreach $x (@maketargets) {
176
            if($l eq $x) {
177
                next LIB;
178
            }
179
        }
180
        push @maketargets, $l;
181
    }
182
}
183
184
# cd to builddir
185
chdir $builddir || die "Can't find builddir '$builddir'\n";
186
if($makeDependNeeded) {
187
    system ("make depend") == 0 or exit 1;
188
}
189
190
@actualTargets=`make help`;
191
foreach $target (@nonLibTargets) {
192
    foreach $h (@actualTargets) {
193
        if($h=~/\b$target\b/) {
194
            push @maketargets, $target;
195
        }
196
    }
197
}
198
199
if($doInstall == 0 && $#maketargets < 0) {
200
    print "No targets\n";
201
    exit;
202
}
203
204
if(defined $jobs) {
205
    $jobs="-j $jobs";
206
}
207
if(defined $verbose) {
208
    $verbose="VERBOSE=0";
209
}
210
foreach $lib (@maketargets) {
211
    chdir "$builddir/$locations{$lib}";
212
    $dir = $locations{$lib};
213
    $dir=~s/^\.\///;
214
    if(&checkTargetAvail($lib) == 1) {
215
        if(! defined $quiet) {
216
            print "Building lib: $lib (in $dir)\n";
217
        }
218
        if(defined $just_print) {
219
            next;
220
        }
1.1.46 by Alessandro Ghersi
Import upstream version 4.4.92
221
        foreach $h (@actualTargets) {
222
            if($h=~/(\b$lib\_automoc)/) {
223
                system ("make $jobs $verbose $1");
224
                last;
225
            }
226
        }
227
1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
228
        my $rc = system ("make $jobs $verbose $lib/fast");
229
        if(!(defined $keep_going) && $rc != 0) {
230
            exit 1;
231
        }
232
    }
233
    elsif(! defined $quiet) {
234
        print "Skipping lib: $lib (in $dir)\n";
235
    }
236
}
237
238
# install!
239
if($doInstall == 1) {
240
    if(! defined $quiet) {
241
        print "Installing changed files";
242
        #if($dir ne ".") { print " in '$dir'"; }
243
        print "\n";
244
    }
245
    if(! defined $just_print) {
1.1.46 by Alessandro Ghersi
Import upstream version 4.4.92
246
        @output=`(cd $builddir && make install/fast)`;
247
        my $line;
248
        foreach $line (@output) {
249
            if ($line=~/^-- (Installing: .*)$/) {
250
                print "$1\n";
251
            }
252
        }
1.1.13 by Jonathan Riddell
Import upstream version 4.0.80
253
    }
254
}
255
256
###############
257
sub readCmakeFile {
258
    my $dir=shift(@_);
259
    my $file="CMakeLists.txt";
260
261
    if($makeDependNeeded == 0) {
262
        my $buildAge = (stat("$builddir/$dir/CMakeFiles/CMakeDirectoryInformation.cmake"))[9];
263
        my $fileAge = (stat("$dir/$file"))[9];
264
        if($fileAge > $buildAge) {
265
            $makeDependNeeded = 1;
266
            print "makeDepend needed due to $dir\n";
267
        }
268
    }
269
270
    my @subdirs;
271
    open FILE, "$dir/$file";
272
    my $inLink=0;
273
    my $lib = "";
274
    foreach $line (<FILE>) {
275
        if($inLink == 0 && $line=~/^\s*add_subdirectory\s*\((.*)\)/i) {
276
            my $d=$1;
277
            $d=~s/^\s*//;  #chomp
278
            $d=~s/\s*$//;
279
            push @subdirs, $d;
280
        }
281
282
        my $libs = "";
283
        if($inLink == 1) {
284
            $libs = $line;
285
        }
286
        if($line=~/^\s*target_link_libraries\s*\((.*)/) {
287
            $libs = $1;
288
            $inLink=1;
289
        }
290
        if($inLink == 1 && $libs ne "") {
291
            foreach $i (split(" ", $libs)) {
292
                if($i=~/\)$/) {  # incase no space was used
293
                    $i=~s/\)$//;
294
                    $inLink = 0;
295
                }
296
                if($i eq ")") { #incase a space was used
297
                    $inLink = 0;
298
                }
299
                elsif($inLink==1 && $lib eq "") { # a library is defined in this file
300
                    $lib = $i;
301
                    push @libraries, $lib;
302
#print "found lib: $lib\n";
303
                    $locations{$lib} = "$dir";
304
                }
305
                else { # and that libraries dependencies
306
                    $$lib .= "$i ";
307
#print "   supportlib $i\n";
308
                }
309
            }
310
            $libs ="";
311
        }
312
        if($inLink == 0) {
313
            $lib = "";
314
        }
315
    }
316
    close FILE;
317
318
    # only go into subdir when the DartTestfile lists the subdir.
319
    open FILE, "$builddir/$dir/DartTestfile.txt";
320
    foreach $line (<FILE>) {
321
        if($line=~/^SUBDIRS\s*\((.*)\)/) {
322
            my $subdir;
323
            foreach $subdir (@subdirs) {
324
                if(defined $exclude && "/$subdir/"=~/$exclude/) {
325
                    next;
326
                }
327
                if($line=~/\b$subdir\b/) {
328
                    &readCmakeFile("$dir/$subdir");
329
                }
330
            }
331
            last;
332
        }
333
    }
334
    close FILE;
335
}
336
337
sub dependencies() {
338
    my $level=shift(@_);
339
    my $target=shift(@_);
340
    if($level > 12) {
341
        print "ERROR; dependency checking hit 12 levels deep, probably a circular dependency, baling out\n";
342
        print " dependencies traceback (bottom depends on top):\n";
343
        print " $target\n";
344
        return "ERROR";
345
    }
346
#my $inset ="";
347
#for($i=0; $i < $level; $i++) { $inset .="  "; }
348
#print "$inset |dependencies of '$target'\n";
349
350
    my @depend;
351
    my $lib;
352
#print "$inset depsLine='$$target'\n";
353
    foreach $lib (split(" ", $$target)) {
354
        my $found=0;
355
        my $l;
356
        # if not in our libraries, skip it.
357
        foreach $l (@libraries) {
358
            if($l eq $lib) {
359
                $found=1;
360
                last;
361
            }
362
        }
363
        if($found == 0) {
364
            next;
365
        }
366
#print "$inset has dependency $lib\n";
367
368
        if(&contains($lib, @depend) == 0) {
369
#print "$inset  $lib not yet present in: \"";
370
#foreach $dslf (@depend) {
371
#    print  " $dslf";
372
#}
373
#print "\"\n";
374
            # before we add it, lets find the dependencies of that library
375
            foreach $l (&dependencies($level+1, $lib)) {
376
                if($l eq "ERROR") {
377
                    print " $target\n";
378
                    return "ERROR";
379
                }
380
                if(&contains($l, @depend) == 0) {
381
                    push @depend, $l;
382
                }
383
            }
384
            push @depend, $lib;
385
        }
386
    }
387
    if(&contains($target, @depend) == 0) {
388
        push @depend, $target;
389
    }
390
391
#foreach $dslf (@depend) {
392
#    print  "$inset  += '$dslf'\n";
393
#}
394
395
    return @depend;
396
}
397
398
## Returns 1 if the first arg is already present in the rest of the array, 0 otherwise
399
sub contains() {
400
    my $new=shift(@_);
401
    @array = @_;
402
    my $item;
403
    foreach $item (@array) {
404
        if($item eq $new) {
405
            return 1;
406
        }
407
    }
408
    return 0;
409
}
410
411
sub parseArguments() {
412
    @arguments=@_;
413
    for($i=0; $i<=$#arguments; $i++) {
414
        if($arguments[$i]=~/(-{1,2}\S+?)(=\S+|)$/) {
415
            $command=$1;
416
            $param=$2;
417
            if($command=~/^-\b(.)(.*)/) {
418
                my $char=$1;
419
                $param=$2;
420
                $command=$argMap{$char};
421
            }
422
            $command=~s/^--//;
423
            if(&contains($command, @options) == 0) {
424
                print "unrecognized option '$arguments[$i]'\n";
425
                print "Try `$COMMAND --help' for more information.\n";
426
                exit 1;
427
            }
428
            if($param eq "" && &contains($command, @argCommands) == 1) {
429
                $i++;
430
                if($arguments[$i]=~/^-/ || $#arguments < $i) {
431
                    print "Missing argument: $arguments[$i-1]\n";
432
                    exit 1;
433
                }
434
                $param = $arguments[$i];
435
            }
436
            if($param eq "") {
437
                $param =1;
438
            }
439
            $command=~s/\W/_/g;
440
            # print "setting param $command\n";
441
            $$command=$param;
442
        }
443
        else {
444
            push @userArgs, $arguments[$i];
445
        }
446
    }
447
}
448
449
sub checkTargetAvail() {
450
    my $target=shift(@_);
451
    open FILE, "Makefile";
452
    foreach $line (<FILE>) {
453
        if($line=~/^$target:/) {
454
            close FILE;
455
            return 1;
456
        }
457
    }
458
    close FILE;
459
    return 0;
460
}
461