fix typo
[LibreOffice.git] / icu / createmak.pl
blob891c5e33a778fcc517993122c07a1911e24b4afa
2 eval 'exec perl -wS $0 ${1+"$@"}'
3 if 0;
4 #*************************************************************************
6 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 # Copyright 2000, 2010 Oracle and/or its affiliates.
10 # OpenOffice.org - a multi-platform office productivity suite
12 # This file is part of OpenOffice.org.
14 # OpenOffice.org is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU Lesser General Public License version 3
16 # only, as published by the Free Software Foundation.
18 # OpenOffice.org is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU Lesser General Public License version 3 for more details
22 # (a copy is included in the LICENSE file that accompanied this code).
24 # You should have received a copy of the GNU Lesser General Public License
25 # version 3 along with OpenOffice.org. If not, see
26 # <http://www.openoffice.org/license.html>
27 # for a copy of the LGPLv3 License.
29 #*************************************************************************
31 use XML::Parser;
32 # ------------------------------------------------------------------------
33 # Other global stuff
34 $is_debug=0;
35 my $path = $ENV{'INPATH'} . "/";
36 my $quot = '"';
37 my %template_hash=();
38 my %vcproj_hash=();
39 # ------------------------------------------------------------------------
40 # Global stuff for parsing the *.vcproj files (XML::Parser)
42 my $ConfigurationGlobal = 1; # Release = 1, Debug=0
43 my $Configuration = undef;
44 my %configelements = ();
45 my %files = ();
46 my %files2copy = ();
47 my %files_special = ();
48 my $Release = 1;
49 # Release = 1, Debug = 0, undef = 2
50 my $file_tmp = ""; # temporary storage for file name
51 my $CustomSection = 0;
52 # ------------------------------------------------------------------------
53 # ------------------------------------------------------------------------
54 # e.g. %object_hash with Key = blabla.cpp
55 # contains a Hash:
56 # Header: "..\\common\\unicode\\utypes.h ..\\common\\unicode\\uset.h"
57 # CFlags: Common (set in templates file) or special sequence
58 # CDefs: Common (set in templates file) or special sequence
59 # ------------------------------------------------------------------------
60 my $configfile = shift;
61 my $sourcePath = shift;
62 if ( !$configfile ) {
63 $configfile = "createmak.cfg";
65 if ( !$sourcePath ) {
66 $inpath = $ENV{"INPATH"};
67 $sourcePath = $inpath . "\\misc\\build\\icu\\source";
69 $dir = "";
70 $header = "";
71 $sep = "\\\\";
73 %project_by_id =();
74 %project_by_name = ();
75 %project_dependencies = ();
76 my @builddeps = prepare_allinone_all_mak(\%project_by_id,\%project_by_name,\%project_dependencies,$sourcePath);
78 fillTemplateHash($configfile);
80 create_allinone_all_mak(\@builddeps,\%project_by_id,$sourcePath);
81 my @dirs = ();
82 foreach $projectname(keys %project_by_name)
84 my $dir = $project_by_name{$projectname}[1];
85 $dir =~ /\.\.\\(.+)\\(.+)\.vcproj/;
86 my $dir1 = $1;
87 my $dir2 = $2;
88 if ( $dir1 !~ /$dir2$/ ) {
89 $dir1 .= "\.$dir2";
91 print "$dir1 - $dir2\n" if ($is_debug);
92 push @dirs, $dir1;
95 # set nonpro switch (linking against debug runtime if nonpro=1)
96 my $nonpro = ($ENV{"PROEXT"} ne ".pro");
97 print "Non Product Build" if ($nonpro);
99 foreach $dir(@dirs)
101 next if ($dir eq "data.makedata"); # very special don't overwrite this file
102 # ------------------------------------------------------------------------
103 # Reset global stuff for parsing the *.vcproj files (XML::Parser)
105 $Configuration = $ConfigurationGlobal; # Release = 1, Debug=0
106 %configelements = ();
107 %files = ();
108 # contains all relevant *.c,*.cpp,*.h,*.rc files
109 %files2copy = ();
110 %files_special = ();
111 $Release = 2;
112 # Release = 1, Debug = 0, undef = 2
113 $file_tmp = ""; # temporary storage for file name
114 $CustomSection = 0;
115 # ------------------------------------------------------------------------
117 my $extra_mak = "";
118 ($dir, $extra_mak) = handle_extra_mak_files($dir); # handle e.g. tools/genrb.derb entires
120 my @mak=(); # Array for make file *.mak
121 my %deps=();
122 my %object_hash=();
123 my %collected_header=();
124 my %collect_header_target_hash=();
125 my %collect_object_target_hash=();
126 my $vcproj_file = "";
127 my $resource_file = "";
129 # $dir : common,i18n,...
130 chomp $dir;
131 next if ( $dir eq "" );
132 my $fullpath = $sourcePath . "\\" . $dir;
133 if ( $extra_mak eq "" ) {
134 if ($dir =~ /(.+)+\\(.+)$/)
136 $vcproj_file = $fullpath ."\\$2.vcproj";
137 } else
139 $vcproj_file = $fullpath ."\\$dir.vcproj";
141 } else
143 $vcproj_file = $fullpath . "\\" . $extra_mak . ".vcproj";
147 # Parse the *.vcproj file
148 my $parser = new XML::Parser(ErrorContext => 2);
149 $parser->setHandlers(Start => \&start_handler,
150 Char => \&char_handler);
151 $parser->parsefile($vcproj_file);
152 if ( $file_tmp ) {
153 # save a file which hasn't been saved yet
154 $files{ $file_tmp } = 1; # save it now
155 $file_tmp = ""; # has been saved now reset it
158 # is there a resource file?
159 foreach $i (keys %files)
161 if ($i =~ /\.rc/)
163 $resource_file = $i;
166 # Fill hash %deps for dependencies for all files in directory ($testdir)
167 # %files contains all relevant files from *.vcproj
169 getAllFilesDeps($fullpath,\%deps,\%files);
170 my $includedir = $configelements{"Release"}{"OutputDirectory"}; # e.g. OutputDirectory = ..\..\lib
171 $includedir =~ s/lib/include/;
172 foreach $file( sort keys %deps)
174 $file =~ /(.+)\.(.+)/;
175 my $name = $1;
176 my $ext = $2;
177 next if (!defined $name);
178 $object = "\$(INTDIR)\\" . "$name.obj";
179 $collect_object_target_hash{$object}=1;
181 createMakDepSection($dir,$name,$ext,$deps{$file},\@mak,\%files_special);
183 my %all_target_hash=();
184 foreach $header(sort keys %files2copy)
186 my $dir;
187 my $file;
188 #$pathdepth = "..\\..";
189 $file = $header;
190 $header =~ s/^\.\\//;
191 $inputpath = $file;
192 $target = $includedir . "\\" . $header;
193 $target =~ /.+\\(.+)\\.+$/;
194 $targetpath = $configelements{"Release"}{"CommandLine"};
195 chomp $targetpath;
196 # set %all_target_hash and @mak
197 createCopySection($file,$inputpath,$target,$targetpath,\@mak,\%all_target_hash);
198 $collect_header_target_hash{$target}=1;
200 my $test = $configelements{"Release"}{"OutputFile"};
201 $all_target_hash{$test}=1;
203 # set name of the *.mak file
204 my $mak_file="";
205 if ( $extra_mak eq "" ) {
206 $mak_file = $vcproj_file;
207 $mak_file =~ s/vcproj/mak/;
208 } else
210 # extra_mak eg. derb, stringperf
211 $mak_file = $fullpath . "\\$extra_mak" . "\.mak";
214 # generate the content of the *.mak file
215 # in @mak array
216 print "extra_mak=$extra_mak\n" if ($is_debug);
217 print "mak_file=$mak_file\n" if ($is_debug);
218 open(MAKFILE, ">$mak_file") || die "Can't open $mak_file\n";
219 print_all_target($fullpath, \%all_target_hash);
221 # $extra_mak handles further *.mak files in a directory
222 print_flags($dir,$extra_mak,'CFlags',$nonpro); # depends on directory
223 print_simple_flag("Rules");
224 print_simple_flag("Link");
225 print_common_linkflags();
226 # print_flags($fullpath,$extra_mak,'LinkFlags'); # depends on directory
227 # print_lib32_objs($fullpath,$extra_mak,\%collect_object_target_hash,$resource_file);
228 print_flags($dir,$extra_mak,'LinkFlags'); # depends on directory
229 print_lib32_objs($dir,$extra_mak,\%collect_object_target_hash,$resource_file);
231 # write @mak array into the *.mak file
232 foreach $line(@mak)
234 print MAKFILE $line;
236 $|=1;
237 print "."; # user entertainment
238 $|=0;
240 print "\ndone\n";
241 exit;
243 ############################################################################
244 sub getKey #01.04.2008 09:46
245 ############################################################################
247 my $line = shift;
248 $line =~ /\[(.+)\]/;
249 return $1;
250 } ##getKey
252 ############################################################################
253 sub fillTemplateHash #01.04.2008 10:48
254 ############################################################################
256 my $file = shift;
257 open (TEMPLATE, "< $file") || die "Can't open template file $file\n";
258 my $key = "";
259 while ( $line=<TEMPLATE> ) {
260 if ( $line =~ /\[.+\]/ ) {
261 print $line if ($is_debug);
262 if ( $key ne "" ) {
263 $template_hash{$key}=[@cmdlines];
264 @cmdlines="";
265 $key="";
267 $key = getKey( $line );
268 } else
270 push @cmdlines, $line;
272 } # while
273 } ##fillTemplateHash
275 ############################################################################
276 sub createCopySection #01.04.2008 11:37
277 ############################################################################
279 my $header = shift;
280 my $inputpath = shift;
281 my $target = shift;
282 my $targetpath = shift;
283 my $ref_make_file = shift; # Array written later to make file *.mak
284 my $ref_all_target_hash = shift; # reference to fill all_target_hash;
285 if ( $target !~ /\\include/ && $target !~ /\\bin/) {
286 return; # $target contains nonsense
288 if ( !$targetpath ) {
289 # $targetpath is empty! (Due to missing entry in *.vcproj file)
290 # Generate $targetpath here from $target
291 my $t = $target;
292 $t =~ /(.+)\\(.+)$/;
293 $targetpath = "copy \"\$(InputPath)\" " . $1;
294 chomp $targetpath;
296 $targetpath =~ s/\r$//; # remove x0A from EOL if the is one
297 my @template = @{$template_hash{"Copy"}};
298 my $line = "";
299 foreach $line(@template)
301 $line =~ s/<HEADER>/$header/g;
302 $line =~ s/<INPUTPATH>/$inputpath/g;
303 $line =~ s/<TARGET>/$target/g;
304 $line =~ s/<TARGETPATH>/$targetpath/;
305 push @{$ref_make_file}, $line; # from template
306 $$ref_all_target_hash{$target} = 1; # "\"$target\" ";
307 # save for target ALL:
309 } ##createCopySection
311 ############################################################################
312 sub createMakDepSection #01.04.2008 13:36
313 ############################################################################
315 # creates the dependency section in the make file
316 my $dir = shift;
317 my $source = shift;
318 my $extension = shift;
319 my $ref_header_list = shift;
320 my $ref_make_file = shift; # Array written later to make file *.mak
321 my $ref_special_file = shift; # hash for special files (compiler flags, include paths)
322 my $header_list = "";
323 my $special_flag = 0;
325 return if ( !defined $source );
326 foreach $header(@{$ref_header_list})
328 if ( ($header =~ /^\.\.\\.+/) && (-e $header )) {
329 $header_list = $header_list . " " . $header; # this header is located in an other directory
330 } else
332 $header_list = $header_list . " .\\" . $header;
336 #special handling
337 # compile this file with other compiler switches
338 my $file = $source . "\." . $extension;
339 $dir =~ s/\\/_/;
340 my @template = @{$template_hash{"CFlags_$dir"}};
341 if ( defined $$ref_special_file{"AdditionalIncludeDirectories"}{$file} ) {
342 $special_flag = 1;
343 my $includepath = $$ref_special_file{"AdditionalIncludeDirectories"}{$file};
344 $includepath =~ s/\;/\/I /g; # subst ; with /I for multiple paths
345 $line = "CPP_SWITCH_INCLUDE=/I $includepath\n";
346 push @{$ref_make_file}, $line;
347 foreach $line(@template)
349 if ( $line =~ /CPP_PROJ/)
351 $line =~ s/CPP_PROJ=/CPPX_PROJ=/;
352 $line =~ s/\$\(CDEFS\)/\$\(CDEFS\) \$\(CPP_SWITCH_INCLUDE\)/; # include $(CPP_SWITCH_INCLUDE)
353 push @{$ref_make_file}, $line;
357 if ( $$ref_special_file{"DisableLanguageExtensions"}{$file} )
359 # FALSE = /Ze
360 $special_flag = 1;
361 foreach $line(@template)
363 if ( $line =~ /CPP_PROJ/)
365 $line =~ s/CPP_PROJ=/CPPX_PROJ=/;
366 $line =~ s/-Za/-Ze/;
367 if ( $nonpro )
369 # if non product link against debug libraries
370 $line =~ s/-MD/-MDd/;
371 $line =~ s/-MT/-MTd/;
373 push @{$ref_make_file}, $line;
378 @template = @{$template_hash{"Deps"}};
379 my $line = "";
380 foreach $line(@template)
382 $line =~ s/<SOURCEFILE>/$source/g;
383 $line =~ s/<EXT>/$extension/g;
384 $line =~ s/<HEADER_LIST>/$header_list/g;
385 push @{$ref_make_file}, $line;
388 if ( $special_flag )
390 pop @{$ref_make_file}; # remove empty line
391 push @{$ref_make_file},"\t\$(CPP) @<<\n";
392 push @{$ref_make_file},"\t\$(CPPX_PROJ) \$(SOURCE)\n";
393 push @{$ref_make_file},"<<\n\n";
394 $special_flag = 0;
397 } ##createMakDepSection
400 ############################################################################
401 sub getFilenameFromPath #10.04.2008 13:03
402 ############################################################################
404 my $path = shift;
405 $path =~ /.+\\(.+)$/;
406 return $1;
407 } ##getFilenameFromPath
409 ############################################################################
410 sub getAllFilesDeps #08.04.2008 09:39
411 ############################################################################
413 my $path = shift;
414 my $ref_deps = shift;
415 my $ref_allfiles = shift; # contains all relevant files from *.vcproj
416 my %local_header_hash=(); # contains all local header
418 my @all_files = keys %{$ref_allfiles};
420 # collect lokal header names in %header_hash
421 foreach $file(@all_files)
423 if ( $file =~ /.+\.h/ ) {
424 chomp $file;
425 $local_header_hash{$file} = 1;
429 foreach $file(@all_files)
431 my @header_deps=();
432 my $skip = 0;
434 $file =~ s/^\.\\//; # remove leading .\
436 # exclude sub directories and several file extensions
437 # *.dep,*.h,*.in,*.mak,*.pl,*.txt,*.vcproj.*.rc and origs of patch files (*.*~) and
438 # .cvsignore (files beginning with .)
439 next if ( (-d "$path$sep$file") || ($file =~ /.+(_|\~|dep|h|in|mak|pl|txt|vcproj|rc)$/) || ($file =~ /^\.+./));
440 parse_header_deps($path,$file,\@header_deps,\%local_header_hash);
441 handle_dep_to_other_directory($path,$file,\@header_deps,$$ref_vcproj{$file}) if ($$ref_vcproj{$file});
442 $$ref_deps{$file}=[@header_deps];
444 } ##getAllFilesDeps
446 ############################################################################
447 sub parse_header_deps #14.06.2006 18:04
448 ############################################################################
450 # get includes from c/cpp file
451 # call create_deps(path,file,\$link_obj)
453 my $path = shift;
454 my $cfile = shift;
455 my $ref_header_deps = shift;
456 my $ref_local_header_hash = shift;
458 my $fullpath = $path . $sep . $cfile;
459 my $unicodedep="";
460 open(IN, "<$fullpath") || die "can't open $fullpath\n";
461 while ( $line = <IN> ) {
462 next if ($line !~ /^.?\#include.+/); # handle include lines only
463 if ($line =~ /.+?\s(.+)/)
465 $header = $1;
466 if ( ($header !~ /^<.+/) && ($header !~ /.+\.c.+$/) ) {
467 # no <stdio> etc. header
468 $header =~ s/\s+\/\*.+\*\///; # delete <blanks>/* ... */
469 $header =~ s/\s+\/\/.+//; # delete <blanks>//......
470 $header =~ s/\//\\/; # subst. / with \
471 $header =~ s/^\"/\".\\/;
472 $header =~ s/\"//g;
473 $header =~ s/\.\\//;
474 my $test = $$ref_local_header_hash{$header};
475 my $header_fullpath = $path . "\\" . $header;
476 if ( $test || (($header =~ /\\/) && (-e $header_fullpath))) {
477 push @{$ref_header_deps}, $header;
482 } ##parse_header_deps
484 ############################################################################
485 sub handle_dep_to_other_directory #16.04.2008 15:11
486 ############################################################################
488 # there has been an additional include directoy detected
489 # now try to find out which header (parsed from c/cpp-file)
490 # comes from this directory by checking: does it exist there?
491 my $path = shift;
492 my $file = shift;
493 my $ref_header_deps = shift;
494 my $path_additional = shift;
495 my $search_path = $path . "\\" . $path_additional;
496 my $counter = 0;
497 foreach $header(@{$ref_header_deps})
499 my $full_path = $search_path . "\\" . $header;
500 if ( -e "$full_path" )
502 $$ref_header_deps[$counter] = $path_additional . "\\" . $header;
504 $counter++
506 } ##handle_dep_to_other_directory
508 ############################################################################
509 sub print_lib32_objs #18.04.2008 12:54
510 ############################################################################
512 # generate Link section
513 my $path = shift;
514 my $extra_mak = shift;
515 my $ref_objecthash = shift;
516 my $resource_file = shift;
517 # output link objects
518 print MAKFILE "LINK32_OBJS= \\\n";
519 # print objects
520 foreach $object(sort keys %{$ref_objecthash})
522 print MAKFILE "\t$object \\\n";
525 # print *.res if *.rc exists
526 if ( $resource_file ne "" ) {
527 my $res_file = $resource_file;
528 $res_file =~ s/\.rc/\.res/;
529 $res_file =~ /(.+)\\(.+)$/;
530 $res_file = $2;
531 print MAKFILE "\t\$(INTDIR)\\$res_file \\\n";
534 # add import libs and res files
535 print_flags($path,$extra_mak,"AdditionalLinkObjects");
536 my $outfile = $configelements{"Release"}{"OutputFile"};
538 # section for linking
539 print_link_template($path,$outfile);
541 # section for creating res files
542 # setting for rsc, res target etc.
543 print "resource_file=$resource_file\n" if ($is_debug);
544 print_rsc_template($resource_file) if ($resource_file);
545 print_simple_flag("Special_extra_uconv") if ($outfile =~ /uconv/);
546 } ##print_lib32_objs
548 ############################################################################
549 sub print_all_target #26.06.2008 13:27
550 ############################################################################
552 my $path = shift;
553 my $ref_all_target_hash = shift;
554 my $filename = getFilenameFromPath($path);
555 my $outdir = $configelements{"Release"}{"OutputDirectory"};
556 print MAKFILE "NULL=\n";
557 print MAKFILE "OUTDIR=$outdir\n";
558 print MAKFILE "OutDir=$outdir\n";
559 print MAKFILE "INTDIR=.\\Release\n\n";
560 print MAKFILE "ALL: ";
561 foreach $target(sort keys %{$ref_all_target_hash})
563 if ( $target =~ /\.exe/ ) {
564 my $out = $target;
565 $out =~ s/.\\Release/\.\.\\\.\.\\\.\.\\bin/;
566 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/;
567 $out =~ s/\//\\/; # convert / to \
568 $target = $out;
570 print MAKFILE "\"$target\" ";
573 # Append [Target_<dir>] item e.g. ../../icuxy36.dll
574 my $targetkey = "Target_" . $filename;
575 my @target = ();
576 if ( exists $template_hash{$targetkey} ) {
577 @target = @{$template_hash{$targetkey}};
579 my $additional_target="";
580 foreach $additional_target(@target)
582 print MAKFILE $additional_target if ($additional_target ne "");
584 print MAKFILE "\n\n";
585 print MAKFILE "\"\$(OUTDIR)\" : \n";
586 print MAKFILE "\tif not exist \"\$(OUTDIR)/\$(NULL)\" mkdir \"\$(OUTDIR)\"\n\n";
587 print MAKFILE "!IF \"\$(OUTDIR)\" != \"\$(INTDIR)\"\n";
588 print MAKFILE "\"\$(INTDIR)\" : \n";
589 print MAKFILE "\tif not exist \"\$(INTDIR)/\$(NULL)\" mkdir \"\$(INTDIR)\"\n";
590 print MAKFILE "!ENDIF\n";
591 print MAKFILE "\n\n";
592 } ##print_all_target
594 ############################################################################
595 sub print_simple_flag #18.04.2008 13:39
596 ############################################################################
598 my $simple_flag = shift;
599 my @template = @{$template_hash{$simple_flag}};
600 foreach $line(@template)
602 print MAKFILE $line;
604 } ##print_rules
606 ############################################################################
607 sub print_link_template #18.04.2008 13:39
608 ############################################################################
610 my $dir = shift;
611 my $outfile = shift;
612 my $manifest;
613 # set resource id for manifest file
614 if ( $outfile =~ /\.exe/ ) {
615 $manifest = 1;
616 } else
618 $manifest = 2;
620 my @template = ();
621 if ($dir =~ /stubdata/ ) {
622 @template = @{$template_hash{"Special_stubdata"}};
623 } else
625 @template = @{$template_hash{"LinkTemplate"}};
628 print MAKFILE "\n"; # insert blank line
629 foreach $line(@template)
631 $line =~ s/<OUTFILE>/$outfile/;
632 $line =~ s/<MANIFEST>/$manifest/;
633 print MAKFILE $line;
636 # insert special stuff for
637 # extras/uconv/uconv.mak
638 if ( $dir =~ /uconv/ ) {
639 print_flags($dir,"","Special");
642 # for *.exe files an additional
643 # copy section is required to get
644 # the stuff into the global bin directory
645 my %dummy = ();
646 my @mak = ();
647 if( $manifest ==1 )
649 # source,inputpath,target,action
650 my $out = $outfile;
651 $out =~ s/.\\.*Release/\.\.\\\.\.\\\.\.\\bin/;
652 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/;
653 $out =~ s/\//\\/; # subst / with \
654 $outfile =~ s/\//\\/; # subst / with \
655 createCopySection($outfile,$outfile,$out,"copy \"\$(InputPath)\" .\\..\\..\\..\\bin",\@mak,\%dummy);
656 foreach $line(@mak)
658 print MAKFILE $line;
661 } ##print_rules
663 ############################################################################
664 sub print_rsc_template #04.11.2008 14:48
665 ############################################################################
667 # print resource compiler setting + resource target
668 my $resourcefile = shift;
669 # skip this if no res file required
671 return if (!$resourcefile);
672 $resfile = $resourcefile;
673 #remove file extension (.res)
674 $resfile =~ /(.+)\\(.+)\.(.+)/;
675 $resfile = $2;
677 my @template = @{$template_hash{"RSC_Template"}};
678 print MAKFILE "\n"; # insert blank line
679 foreach $line(@template)
681 $line =~ s/<FILE>/$resourcefile/;
682 $line =~ s/<FILEOUT>/$resfile/;
683 print MAKFILE $line;
685 } ##print_rsc_template
687 ############################################################################
688 sub print_flags #18.04.2008 14:19
689 ############################################################################
691 # CFlags, LinkFlags
692 my $dir = shift;
693 my $extra_mak = shift; # eg. derb.mak, stringperf.mak
694 my $flag = shift;
695 my $nonpro = shift;
696 my @template = ();
697 my $switch = "";
698 $dir =~ s/\\/_/g if ($dir); # change \ to _
699 $switch = "$flag" . "_" . "$dir" if ($dir);
700 handle_CFlags() if ($flag eq "CFlags"); # get and print Preprocessor defines
701 $switch .= "\." . $extra_mak if ( $extra_mak ne "" ) ;
702 if ( exists $template_hash{$switch} ) {
703 @template = @{$template_hash{$switch}};
704 foreach $line(@template)
706 if ( $nonpro )
708 # if non product link against debug libraries
709 $line =~ s/-MD/-MDd/;
710 $line =~ s/-MT/-MTd/;
712 print MAKFILE $line;
715 } ##print_flags
717 ############################################################################
718 sub handle_CFlags #28.01.2009 11:20
719 ############################################################################
722 my $ppdefs = $configelements{"Release"}{"PreprocessorDefinitions"};
723 my $ppinc = $configelements{"Release"}{"AdditionalIncludeDirectories"};
724 my @template = @{$template_hash{"General_CFlags"}};
725 $ppdefs =~ s/;/ -D/g; # subst ; with -D switch
726 $ppdefs = "-D" . $ppdefs;
727 $ppinc =~ s/(;|,)/ -I/g; # subst ; with -I switch
728 $ppinc = "-I" . $ppinc;
729 print "ppdefs=$ppdefs\n" if ($is_debug);
730 print "ppinc =$ppinc\n" if ($is_debug);
731 foreach $line(@template)
733 $line =~ s/<AddIncDirs>/$ppinc/;
734 $line =~ s/<PreProcDefs>/$ppdefs/;
735 print MAKFILE $line;
737 } ##handle_CFlags
739 ############################################################################
740 sub print_common_linkflags #21.11.2008 11:47
741 ############################################################################
743 my @template = @{$template_hash{"CommonLinkFlags"}};
744 my $outfile = $configelements{"Release"}{"OutputFile"};
745 my $pdbfile = $configelements{"Release"}{"ProgramDatabaseFile"};
746 $pdbfile =~ s/\//\\/; # subst / with \
747 $outfile =~ s/\//\\/; # subst / with \
748 print "PATH=$path OUTFILE=$outfile\n" if ($is_debug);
749 foreach $line(@template)
751 $line =~ s/<OUTFILE>/$outfile/;
752 $line =~ s/<PDBFILE>/$pdbfile/;
753 print MAKFILE $line;
755 } ##print_common_linkflags
757 ############################################################################
758 sub handle_extra_mak_files #25.08.2008 14:32
759 ############################################################################
761 # extract extra filename for *.mak file
762 # e.g input: tools\genrb.derb
763 # output: derb
764 my $direntry = shift;
765 my $out = "";
766 my $dir = "";
767 if ( $direntry =~ /(.+)\.(.+)$/ ) {
768 $dir = $1;
769 $out = $2;
770 } else
772 $dir = $direntry;
774 return ($dir,$out);
775 } ##handle_extra_mak_files
777 ############################################################################
778 sub prepare_allinone_all_mak
779 ############################################################################
781 # Read in allinone.sln
782 # Fills hashes and returns an array with build order
783 # uses topographical sorting
785 my $href_project_by_id = shift;
786 my $href_project_by_name = shift;
787 my $href_project_dependencies = shift;
788 my $sourcePath = shift;
790 my $allslnfile = $sourcePath . "\\allinone\\allinone.sln";
791 my @projectdeps;
792 my $projectname;
793 my $projectpath;
794 my $projectid;
796 # fill hash tables
797 open (SLN, "< $allslnfile") || die "Can't open $allslnfile\n";
798 while ($line = <SLN>)
800 my @project = ();
801 if ( $line =~ /^Project\(/ ) {
802 @project = split( /,/, $line);
803 if ( $#project ) {
804 $projectname = "";
805 $projectpath = "";
806 $projectid = "";
807 @projectdeps = ();
808 my @subarray = ();
809 @subarray = split( /=/, $project[0]);
810 $projectname = $subarray[1];
811 $projectname =~ s/\"//g; # remove "
812 $projectpath = $project[1];
813 $projectid = $project[2];
814 $projectid =~ s/\"//g; # remove "
815 $projectid =~ s/.+\{//g; # remove til {
816 $projectid =~ s/\}\n//g; # remove }<CR>
817 my @pnp = ($projectname,$projectpath);
818 my @pip = ($projectid,$projectpath);
819 $$href_project_by_id{$projectid}=[@pnp];
820 $$href_project_by_name{$projectname} =[@pip];
822 } # $line =~ /^Project\(/
823 if ( $line =~ /ProjectSection\(/ ) {
824 $psect = 1;
825 next;
827 if ( $line =~ /EndProjectSection/ ) {
828 $psect = 0;
829 $$href_project_dependencies{$projectid}=[@projectdeps];
830 next;
832 if ( $psect ) {
833 my @tarray = split(/=/, $line);
834 $depends_on_id = $tarray[0];
835 $depends_on_id =~ s/.+\{//g;
836 $depends_on_id =~ s/\}.+//g;
837 print "+$depends_on_id-\n" if ($is_debug);
839 push @projectdeps, $depends_on_id;
842 ########################################
843 # sort here and generate build order
844 ########################################
845 $objektzahl=0;
846 %hashindex=();
848 foreach $projectid(keys %{$href_project_by_id})
850 if ( $$href_project_dependencies{$projectid} )
852 @deps = @{$$href_project_dependencies{$projectid}};
853 } else
855 @deps = ();
857 for $counter(0..$#deps)
859 $v = find_or_create_element($deps[$counter]);
860 $n = find_or_create_element($projectid);
861 push @{$nachfolgerliste[$v]},$n;
865 for $n (0..$objektzahl-1)
867 $vorgaengerzahl[$n]=0;
869 for $v (0..$objektzahl-1)
871 for $n (@{$nachfolgerliste[$v]})
873 ++$vorgaengerzahl[$n];
877 @hilfsliste=();
878 for $n (0..$objektzahl-1)
880 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0)
883 $ausgabe=0;
884 @builddep =();
885 while (defined($v=pop(@hilfsliste)))
887 push @builddep, $name[$v]; # save build order by project_id;
888 ++$ausgabe;
889 for $n (@{$nachfolgerliste[$v]})
891 --$vorgaengerzahl[$n];
892 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0);
894 } # while
895 die "Cyclic dependencies found! Stopping now.\n" if $ausgabe<$objektzahl;
896 ##############################################################
897 # End of sorting stuff
898 ##############################################################
900 return @builddep;
901 ###############################################################
902 ###########################
903 # sub for sorting only
904 ###########################
905 sub find_or_create_element
907 my ($str)=@_;
908 my ($idx)=$hashindex{$str};
909 if (!defined($idx)) { # new element ...
910 $idx=$objektzahl++;
911 $hashindex{$str}=$idx;
912 $name[$idx]=$str;
913 @{$nachfolgerliste[$idx]}=();
915 return $idx;
916 } # find_or_create_element
917 } # prepare_allinone_all_mak
919 ############################################################################
920 sub create_allinone_all_mak #09.02.2009 09:22
921 ############################################################################
923 my $ref_buildorder = shift;
924 my $href_project_by_id = shift;
925 my $sourcePath = shift;
926 my $allmakfile = $sourcePath . "\\allinone\\all.mak";
927 open (ALLMAK, ">$allmakfile") || die "Can't write to $allmakfile \n";
928 print ALLMAK "ALL: ";
929 foreach $proj(@{$ref_buildorder})
931 print ALLMAK $$href_project_by_id{$proj}[0];
933 print ALLMAK "\n\n";
935 foreach $proj( @{$ref_buildorder} )
937 print "$proj $$href_project_by_id{$proj}[0] $$href_project_by_id{$proj}[1]\n";
938 my $prjdir = $$href_project_by_id{$proj}[1];
939 $prjdir =~ /(.+)\\(.+)$/;
940 $prjdir = $1;
941 $prjname = $2;
942 $prjdir =~ s/^.+\"//;
943 $prjname =~ s/\"$//;
944 $prjname =~ s/vcproj/mak/;
945 $allinonehelpstring = $prjdir;
946 $allinonehelpstring =~ s/^\.+\\//; # remove ..\
947 my $backcount = "";
948 while ($allinonehelpstring=~ /.+\\/g) # counts the occuring \
950 $backcount .= "..\\";
952 $allinonedir = $backcount . "..\\allinone";
954 # write all.mak
955 $$href_project_by_id{$proj}[0] =~ s/^\s+//;
956 if ( $$href_project_by_id{$proj}[0] ne "makedata" )
958 my @template = @{$template_hash{"AllInOnePrj"}};
959 foreach $line(@template)
961 $line =~ s/<PRJ>/$$href_project_by_id{$proj}[0]/;
962 $line =~ s/<PRJDIR>/$prjdir/;
963 $line =~ s/<PRJMAK>/$prjname/;
964 $line =~ s/<ALLINONEDIR>/$allinonedir/;
965 print ALLMAK $line;
967 } else
969 #special code snippet
970 print ALLMAK "makedata : \n";
971 print ALLMAK " cd \"..\\data\"\n";
972 print ALLMAK " nmake /f makedata.mak icumake=\$(MAKEDIR)\\..\\data cfg=Release\n";
973 print ALLMAK " cd \"..\\allinone\"\n\n";
976 close ALLMAK;
977 } ##create_allinone_all_mak
979 ############################################################################
981 # ------------------------------------------------------------------------
982 # XML parser handling
983 # ------------------------------------------------------------------------
985 ############################################################################
986 sub start_handler
987 ############################################################################
989 my $p = shift; # pointer to parser
990 my $el = shift; # element
992 # Deal with attributes
994 my $CompilerSection = 0;
995 my $LinkerSection = 0;
996 my $ConfigSection = ($el eq "Configuration");
998 while (@_)
1000 # shift if ( $el eq "FileConfiguration" );
1001 my $att = shift;
1002 my $val = shift;
1003 $CustomSection = 0;
1004 if ($special_file && defined $att & $att ne "Name")
1006 print "$special_file - $att - $val\n";
1007 my @param = ($att,$val);
1008 $files_special{ $special_file } = [@param]; # files with special compiler switch
1009 @test = @{$files_special{ $special_file }};
1010 print "test=@test\n";
1011 $special_file="";
1013 if ( $ConfigSection && $att eq "Name" && $val eq "Release|Win32" ) {
1014 $Release = 1;
1015 $config = "Release"; # Release
1017 if ( $ConfigSection && $att eq "Name" && $val eq "Debug|Win32" ) {
1018 $Release = 0; # Debug
1019 $config = "Debug";
1021 if ( $att eq "Name" && $val eq "VCCLCompilerTool" ) {
1022 $CompilerSection = 1;
1024 if ( $att eq "Name" && $val eq "VCLinkerTool" ) {
1025 $LinkerSection = 1;
1027 if ( $att eq "Name" && $val eq "VCCustomBuildTool" ) {
1028 $CustomSection = 1;
1031 # For Configuration Infos like compiler defines etc.
1032 if ( $att eq "PreprocessorDefinitions" && $CompilerSection ) {
1033 $configelements{$config}{$att} = $val;
1035 if ( $att eq "AdditionalIncludeDirectories" && $CompilerSection ) {
1036 #$configelements{$config}{$att} = $val;
1037 if ( ($file_tmp ne "") && ($val ne "") ) {
1038 $files{ $file_tmp } = 1; # save it now
1039 $file_tmp =~ s/^\.\\//; # remove leading .\
1040 $files_special{"AdditionalIncludeDirectories"}{$file_tmp} = $val;
1041 print "Include $val: $file_tmp\n" if ($is_debug);
1042 $file_tmp = ""; # has been saved now reset it
1043 } else
1045 $configelements{$config}{$att} = $val;
1048 if ( ($att eq "DisableLanguageExtensions") && $CompilerSection ) {
1049 #$configelements{$config}{$att} = $val;
1050 if ( ($file_tmp ne "") && ($val ne "")) {
1051 $files{ $file_tmp } = 1; # save it now
1052 $file_tmp =~ s/^\.\\//; # remove leading .\
1053 $files_special{"DisableLanguageExtensions"}{$file_tmp} = $val;
1054 print "-Ze: $file_tmp\n" if ($is_debug);
1055 $file_tmp = ""; # has been saved now reset it
1058 if ( $att eq "OutputDirectory" ) {
1059 $configelements{$config}{$att} = $val;
1061 if ( $att eq "OutputFile" && $LinkerSection ) {
1062 $configelements{$config}{$att} = $val;
1064 if ( $att eq "ProgramDatabaseFile" ) {
1065 $configelements{$config}{$att} = $val;
1067 if ( $att eq "ImportLibrary" && $LinkerSection ) {
1068 $configelements{$config}{$att} = $val;
1070 if ($att eq "CommandLine") {
1071 $configelements{$config}{$att} = $val;
1073 if (($att eq "PreprocessorDefinitions") && $ConfigSection) {
1074 $configelements{$config}{$att} = $val;
1077 # Is the file in the step before a header
1078 # which has to be copied into the global
1079 # include path?
1080 if ( $file_tmp ne "" )
1082 $config = "Release";
1083 if ( ($att eq "CommandLine") && ($el eq "Tool") )
1085 if ( $file_tmp =~ /.+\.h$/ ) {
1086 $files2copy{ $file_tmp } = $val; # unicode + layout header to copy
1087 $file_tmp = ""; # has been saved now reset it
1090 } # if $file_tmp
1092 # For files
1093 if ( $att eq "RelativePath" ) {
1094 if ( $file_tmp ) {
1095 # no special file (include dir / compiler switch)
1096 $files{ $file_tmp } = 1; # save it now
1097 $file_tmp = ""; # has been saved now reset it
1099 # store temporary the file name
1100 $file_tmp = $val if ($val !~ /\.mk$/); # no *.mk files
1102 } # while @_
1103 } # End start_handler
1105 ############################################################################
1106 sub char_handler
1107 ############################################################################
1109 } # End char_handler