blob: d715eeac677ce99e03caf152048526f94a779c8b [file] [log] [blame]
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +00001:
2eval 'exec perl -wS $0 ${1+"$@"}'
3 if 0;
Andrew Rist3f5a46d2012-01-17 23:51:39 +00004#**************************************************************
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +00005#
Andrew Rist3f5a46d2012-01-17 23:51:39 +00006# Licensed to the Apache Software Foundation (ASF) under one
7# or more contributor license agreements. See the NOTICE file
8# distributed with this work for additional information
9# regarding copyright ownership. The ASF licenses this file
10# to you under the Apache License, Version 2.0 (the
11# "License"); you may not use this file except in compliance
12# with the License. You may obtain a copy of the License at
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +000013#
Andrew Rist3f5a46d2012-01-17 23:51:39 +000014# http://www.apache.org/licenses/LICENSE-2.0
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +000015#
Andrew Rist3f5a46d2012-01-17 23:51:39 +000016# Unless required by applicable law or agreed to in writing,
17# software distributed under the License is distributed on an
18# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19# KIND, either express or implied. See the License for the
20# specific language governing permissions and limitations
21# under the License.
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +000022#
Andrew Rist3f5a46d2012-01-17 23:51:39 +000023#**************************************************************
24
25
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +000026#
27use XML::Parser;
28# ------------------------------------------------------------------------
29# Other global stuff
30$is_debug=0;
31my $path = $ENV{'INPATH'} . "/";
32my $quot = '"';
33my %template_hash=();
34my %vcproj_hash=();
35# ------------------------------------------------------------------------
36# Global stuff for parsing the *.vcproj files (XML::Parser)
37#
38my $ConfigurationGlobal = 1; # Release = 1, Debug=0
39my $Configuration = undef;
40my %configelements = ();
41my %files = ();
42my %files2copy = ();
43my %files_special = ();
44my $Release = 1;
45 # Release = 1, Debug = 0, undef = 2
46my $file_tmp = ""; # temporary storage for file name
47my $CustomSection = 0;
48# ------------------------------------------------------------------------
49# ------------------------------------------------------------------------
50# e.g. %object_hash with Key = blabla.cpp
51# contains a Hash:
52# Header: "..\\common\\unicode\\utypes.h ..\\common\\unicode\\uset.h"
53# CFlags: Common (set in templates file) or special sequence
54# CDefs: Common (set in templates file) or special sequence
55# ------------------------------------------------------------------------
56my $configfile = shift;
57my $sourcePath = shift;
58if ( !$configfile ) {
59 $configfile = "createmak.cfg";
60}
61if ( !$sourcePath ) {
62 $inpath = $ENV{"INPATH"};
63 $sourcePath = $inpath . "\\misc\\build\\icu\\source";
64}
65$dir = "";
66$header = "";
67$sep = "\\\\";
68
69%project_by_id =();
70%project_by_name = ();
71%project_dependencies = ();
72my @builddeps = prepare_allinone_all_mak(\%project_by_id,\%project_by_name,\%project_dependencies,$sourcePath);
73
74fillTemplateHash($configfile);
75
76create_allinone_all_mak(\@builddeps,\%project_by_id,$sourcePath);
77my @dirs = ();
78foreach $projectname(keys %project_by_name)
79{
80 my $dir = $project_by_name{$projectname}[1];
81 $dir =~ /\.\.\\(.+)\\(.+)\.vcproj/;
82 my $dir1 = $1;
83 my $dir2 = $2;
84 if ( $dir1 !~ /$dir2$/ ) {
85 $dir1 .= "\.$dir2";
86 }
87 print "$dir1 - $dir2\n" if ($is_debug);
88 push @dirs, $dir1;
89}
90
91# set nonpro switch (linking against debug runtime if nonpro=1)
92my $nonpro = ($ENV{"PROEXT"} ne ".pro");
93print "Non Product Build" if ($nonpro);
94
95foreach $dir(@dirs)
96{
97 next if ($dir eq "data.makedata"); # very special don't overwrite this file
98 # ------------------------------------------------------------------------
99 # Reset global stuff for parsing the *.vcproj files (XML::Parser)
100 #
101 $Configuration = $ConfigurationGlobal; # Release = 1, Debug=0
102 %configelements = ();
103 %files = ();
104 # contains all relevant *.c,*.cpp,*.h,*.rc files
105 %files2copy = ();
106 %files_special = ();
107 $Release = 2;
108 # Release = 1, Debug = 0, undef = 2
109 $file_tmp = ""; # temporary storage for file name
110 $CustomSection = 0;
111 # ------------------------------------------------------------------------
112
113 my $extra_mak = "";
114 ($dir, $extra_mak) = handle_extra_mak_files($dir); # handle e.g. tools/genrb.derb entires
115
116 my @mak=(); # Array for make file *.mak
117 my %deps=();
118 my %object_hash=();
119 my %collected_header=();
120 my %collect_header_target_hash=();
121 my %collect_object_target_hash=();
122 my $vcproj_file = "";
123 my $resource_file = "";
124
125 # $dir : common,i18n,...
126 chomp $dir;
127 next if ( $dir eq "" );
128 my $fullpath = $sourcePath . "\\" . $dir;
129 if ( $extra_mak eq "" ) {
130 if ($dir =~ /(.+)+\\(.+)$/)
131 {
132 $vcproj_file = $fullpath ."\\$2.vcproj";
133 } else
134 {
135 $vcproj_file = $fullpath ."\\$dir.vcproj";
136 }
137 } else
138 {
139 $vcproj_file = $fullpath . "\\" . $extra_mak . ".vcproj";
140 }
141
142
143 # Parse the *.vcproj file
144 my $parser = new XML::Parser(ErrorContext => 2);
145 $parser->setHandlers(Start => \&start_handler,
146 Char => \&char_handler);
147 $parser->parsefile($vcproj_file);
148 if ( $file_tmp ) {
149 # save a file which hasn't been saved yet
150 $files{ $file_tmp } = 1; # save it now
151 $file_tmp = ""; # has been saved now reset it
152 }
153
154 # is there a resource file?
155 foreach $i (keys %files)
156 {
157 if ($i =~ /\.rc/)
158 {
159 $resource_file = $i;
160 }
161 }
162 # Fill hash %deps for dependencies for all files in directory ($testdir)
163 # %files contains all relevant files from *.vcproj
164
165 getAllFilesDeps($fullpath,\%deps,\%files);
166 my $includedir = $configelements{"Release"}{"OutputDirectory"}; # e.g. OutputDirectory = ..\..\lib
167 $includedir =~ s/lib/include/;
168 foreach $file( sort keys %deps)
169 {
170 $file =~ /(.+)\.(.+)/;
171 my $name = $1;
172 my $ext = $2;
173 next if (!defined $name);
174 $object = "\$(INTDIR)\\" . "$name.obj";
175 $collect_object_target_hash{$object}=1;
176
177 createMakDepSection($dir,$name,$ext,$deps{$file},\@mak,\%files_special);
178 }
179 my %all_target_hash=();
180 foreach $header(sort keys %files2copy)
181 {
182 my $dir;
183 my $file;
184 #$pathdepth = "..\\..";
185 $file = $header;
186 $header =~ s/^\.\\//;
187 $inputpath = $file;
188 $target = $includedir . "\\" . $header;
189 $target =~ /.+\\(.+)\\.+$/;
190 $targetpath = $configelements{"Release"}{"CommandLine"};
191 chomp $targetpath;
192 # set %all_target_hash and @mak
193 createCopySection($file,$inputpath,$target,$targetpath,\@mak,\%all_target_hash);
194 $collect_header_target_hash{$target}=1;
195 }
196 my $test = $configelements{"Release"}{"OutputFile"};
197 $all_target_hash{$test}=1;
198
199 # set name of the *.mak file
200 my $mak_file="";
201 if ( $extra_mak eq "" ) {
202 $mak_file = $vcproj_file;
203 $mak_file =~ s/vcproj/mak/;
204 } else
205 {
206 # extra_mak eg. derb, stringperf
207 $mak_file = $fullpath . "\\$extra_mak" . "\.mak";
208 }
209
210 # generate the content of the *.mak file
211 # in @mak array
212 print "extra_mak=$extra_mak\n" if ($is_debug);
213 print "mak_file=$mak_file\n" if ($is_debug);
214 open(MAKFILE, ">$mak_file") || die "Can't open $mak_file\n";
215 print_all_target($fullpath, \%all_target_hash);
216
217 # $extra_mak handles further *.mak files in a directory
218 print_flags($dir,$extra_mak,'CFlags',$nonpro); # depends on directory
219 print_simple_flag("Rules");
220 print_simple_flag("Link");
221 print_common_linkflags();
222# print_flags($fullpath,$extra_mak,'LinkFlags'); # depends on directory
223# print_lib32_objs($fullpath,$extra_mak,\%collect_object_target_hash,$resource_file);
224 print_flags($dir,$extra_mak,'LinkFlags'); # depends on directory
225 print_lib32_objs($dir,$extra_mak,\%collect_object_target_hash,$resource_file);
226
227 # write @mak array into the *.mak file
228 foreach $line(@mak)
229 {
230 print MAKFILE $line;
231 }
232 $|=1;
233 print "."; # user entertainment
234 $|=0;
235}
236print "\ndone\n";
237exit;
238
239############################################################################
240sub getKey #01.04.2008 09:46
241############################################################################
242 {
243 my $line = shift;
244 $line =~ /\[(.+)\]/;
245 return $1;
246} ##getKey
247
248############################################################################
249sub fillTemplateHash #01.04.2008 10:48
250############################################################################
251 {
252 my $file = shift;
253 open (TEMPLATE, "< $file") || die "Can't open template file $file\n";
254 my $key = "";
255 while ( $line=<TEMPLATE> ) {
256 if ( $line =~ /\[.+\]/ ) {
257 print $line if ($is_debug);
258 if ( $key ne "" ) {
259 $template_hash{$key}=[@cmdlines];
260 @cmdlines="";
261 $key="";
262 }
263 $key = getKey( $line );
264 } else
265 {
266 push @cmdlines, $line;
267 }
268 } # while
269} ##fillTemplateHash
270
271############################################################################
272sub createCopySection #01.04.2008 11:37
273############################################################################
274 {
275 my $header = shift;
276 my $inputpath = shift;
277 my $target = shift;
278 my $targetpath = shift;
279 my $ref_make_file = shift; # Array written later to make file *.mak
280 my $ref_all_target_hash = shift; # reference to fill all_target_hash;
281 if ( $target !~ /\\include/ && $target !~ /\\bin/) {
282 return; # $target contains nonsense
283 }
284 if ( !$targetpath ) {
285 # $targetpath is empty! (Due to missing entry in *.vcproj file)
286 # Generate $targetpath here from $target
287 my $t = $target;
288 $t =~ /(.+)\\(.+)$/;
289 $targetpath = "copy \"\$(InputPath)\" " . $1;
290 chomp $targetpath;
291 }
292 $targetpath =~ s/\r$//; # remove x0A from EOL if the is one
293 my @template = @{$template_hash{"Copy"}};
294 my $line = "";
295 foreach $line(@template)
296 {
297 $line =~ s/<HEADER>/$header/g;
298 $line =~ s/<INPUTPATH>/$inputpath/g;
299 $line =~ s/<TARGET>/$target/g;
300 $line =~ s/<TARGETPATH>/$targetpath/;
301 push @{$ref_make_file}, $line; # from template
302 $$ref_all_target_hash{$target} = 1; # "\"$target\" ";
303 # save for target ALL:
304 }
305} ##createCopySection
306
307############################################################################
308sub createMakDepSection #01.04.2008 13:36
309############################################################################
310 {
311 # creates the dependency section in the make file
312 my $dir = shift;
313 my $source = shift;
314 my $extension = shift;
315 my $ref_header_list = shift;
316 my $ref_make_file = shift; # Array written later to make file *.mak
317 my $ref_special_file = shift; # hash for special files (compiler flags, include paths)
318 my $header_list = "";
319 my $special_flag = 0;
320
321 return if ( !defined $source );
322 foreach $header(@{$ref_header_list})
323 {
324 if ( ($header =~ /^\.\.\\.+/) && (-e $header )) {
325 $header_list = $header_list . " " . $header; # this header is located in an other directory
326 } else
327 {
328 $header_list = $header_list . " .\\" . $header;
329 }
330 }
331
332 #special handling
333 # compile this file with other compiler switches
334 my $file = $source . "\." . $extension;
335 $dir =~ s/\\/_/;
336 my @template = @{$template_hash{"CFlags_$dir"}};
337 if ( defined $$ref_special_file{"AdditionalIncludeDirectories"}{$file} ) {
338 $special_flag = 1;
339 my $includepath = $$ref_special_file{"AdditionalIncludeDirectories"}{$file};
340 $includepath =~ s/\;/\/I /g; # subst ; with /I for multiple paths
341 $line = "CPP_SWITCH_INCLUDE=/I $includepath\n";
342 push @{$ref_make_file}, $line;
343 foreach $line(@template)
344 {
345 if ( $line =~ /CPP_PROJ/)
346 {
347 $line =~ s/CPP_PROJ=/CPPX_PROJ=/;
348 $line =~ s/\$\(CDEFS\)/\$\(CDEFS\) \$\(CPP_SWITCH_INCLUDE\)/; # include $(CPP_SWITCH_INCLUDE)
349 push @{$ref_make_file}, $line;
350 }
351 }
352 }
353 if ( $$ref_special_file{"DisableLanguageExtensions"}{$file} )
354 {
355 # FALSE = /Ze
356 $special_flag = 1;
357 foreach $line(@template)
358 {
359 if ( $line =~ /CPP_PROJ/)
360 {
361 $line =~ s/CPP_PROJ=/CPPX_PROJ=/;
362 $line =~ s/-Za/-Ze/;
363 if ( $nonpro )
364 {
365 # if non product link against debug libraries
366 $line =~ s/-MD/-MDd/;
367 $line =~ s/-MT/-MTd/;
368 }
369 push @{$ref_make_file}, $line;
370 }
371 }
372 }
373
374 @template = @{$template_hash{"Deps"}};
375 my $line = "";
376 foreach $line(@template)
377 {
378 $line =~ s/<SOURCEFILE>/$source/g;
379 $line =~ s/<EXT>/$extension/g;
380 $line =~ s/<HEADER_LIST>/$header_list/g;
381 push @{$ref_make_file}, $line;
382 }
383
384 if ( $special_flag )
385 {
386 pop @{$ref_make_file}; # remove empty line
387 push @{$ref_make_file},"\t\$(CPP) @<<\n";
388 push @{$ref_make_file},"\t\$(CPPX_PROJ) \$(SOURCE)\n";
389 push @{$ref_make_file},"<<\n\n";
390 $special_flag = 0;
391 }
392
393} ##createMakDepSection
394
395
396############################################################################
397sub getFilenameFromPath #10.04.2008 13:03
398############################################################################
399{
400 my $path = shift;
401 $path =~ /.+\\(.+)$/;
402 return $1;
403} ##getFilenameFromPath
404
405############################################################################
406sub getAllFilesDeps #08.04.2008 09:39
407############################################################################
408{
409 my $path = shift;
410 my $ref_deps = shift;
411 my $ref_allfiles = shift; # contains all relevant files from *.vcproj
412 my %local_header_hash=(); # contains all local header
413
414 my @all_files = keys %{$ref_allfiles};
415
416 # collect lokal header names in %header_hash
417 foreach $file(@all_files)
418 {
419 if ( $file =~ /.+\.h/ ) {
420 chomp $file;
421 $local_header_hash{$file} = 1;
422 }
423 }
424
425 foreach $file(@all_files)
426 {
427 my @header_deps=();
428 my $skip = 0;
429
430 $file =~ s/^\.\\//; # remove leading .\
431
432 # exclude sub directories and several file extensions
433 # *.dep,*.h,*.in,*.mak,*.pl,*.txt,*.vcproj.*.rc and origs of patch files (*.*~) and
434 # .cvsignore (files beginning with .)
435 next if ( (-d "$path$sep$file") || ($file =~ /.+(_|\~|dep|h|in|mak|pl|txt|vcproj|rc)$/) || ($file =~ /^\.+./));
436 parse_header_deps($path,$file,\@header_deps,\%local_header_hash);
437 handle_dep_to_other_directory($path,$file,\@header_deps,$$ref_vcproj{$file}) if ($$ref_vcproj{$file});
438 $$ref_deps{$file}=[@header_deps];
439 }
440} ##getAllFilesDeps
441
442 ############################################################################
443 sub parse_header_deps #14.06.2006 18:04
444 ############################################################################
445 {
446 # get includes from c/cpp file
447 # call create_deps(path,file,\$link_obj)
448 #
449 my $path = shift;
450 my $cfile = shift;
451 my $ref_header_deps = shift;
452 my $ref_local_header_hash = shift;
453
454 my $fullpath = $path . $sep . $cfile;
455 my $unicodedep="";
456 open(IN, "<$fullpath") || die "can't open $fullpath\n";
457 while ( $line = <IN> ) {
458 next if ($line !~ /^.?\#include.+/); # handle include lines only
459 if ($line =~ /.+?\s(.+)/)
460 {
461 $header = $1;
462 if ( ($header !~ /^<.+/) && ($header !~ /.+\.c.+$/) ) {
463 # no <stdio> etc. header
464 $header =~ s/\s+\/\*.+\*\///; # delete <blanks>/* ... */
465 $header =~ s/\s+\/\/.+//; # delete <blanks>//......
466 $header =~ s/\//\\/; # subst. / with \
467 $header =~ s/^\"/\".\\/;
468 $header =~ s/\"//g;
469 $header =~ s/\.\\//;
470 my $test = $$ref_local_header_hash{$header};
471 my $header_fullpath = $path . "\\" . $header;
472 if ( $test || (($header =~ /\\/) && (-e $header_fullpath))) {
473 push @{$ref_header_deps}, $header;
474 }
475 }
476 }
477 }
478 } ##parse_header_deps
479
480############################################################################
481sub handle_dep_to_other_directory #16.04.2008 15:11
482############################################################################
483{
484 # there has been an additional include directoy detected
485 # now try to find out which header (parsed from c/cpp-file)
486 # comes from this directory by checking: does it exist there?
487 my $path = shift;
488 my $file = shift;
489 my $ref_header_deps = shift;
490 my $path_additional = shift;
491 my $search_path = $path . "\\" . $path_additional;
492 my $counter = 0;
493 foreach $header(@{$ref_header_deps})
494 {
495 my $full_path = $search_path . "\\" . $header;
496 if ( -e "$full_path" )
497 {
498 $$ref_header_deps[$counter] = $path_additional . "\\" . $header;
499 }
500 $counter++
501 }
502} ##handle_dep_to_other_directory
503
504############################################################################
505sub print_lib32_objs #18.04.2008 12:54
506############################################################################
507 {
508 # generate Link section
509 my $path = shift;
510 my $extra_mak = shift;
511 my $ref_objecthash = shift;
512 my $resource_file = shift;
513 # output link objects
514 print MAKFILE "LINK32_OBJS= \\\n";
515 # print objects
516 foreach $object(sort keys %{$ref_objecthash})
517 {
518 print MAKFILE "\t$object \\\n";
519 }
520
521 # print *.res if *.rc exists
522 if ( $resource_file ne "" ) {
523 my $res_file = $resource_file;
524 $res_file =~ s/\.rc/\.res/;
525 $res_file =~ /(.+)\\(.+)$/;
526 $res_file = $2;
527 print MAKFILE "\t\$(INTDIR)\\$res_file \\\n";
528 }
529
530 # add import libs and res files
531 print_flags($path,$extra_mak,"AdditionalLinkObjects");
532 my $outfile = $configelements{"Release"}{"OutputFile"};
533
534 # section for linking
535 print_link_template($path,$outfile);
536
537 # section for creating res files
538 # setting for rsc, res target etc.
539 print "resource_file=$resource_file\n" if ($is_debug);
540 print_rsc_template($resource_file) if ($resource_file);
541 print_simple_flag("Special_extra_uconv") if ($outfile =~ /uconv/);
542} ##print_lib32_objs
543
544############################################################################
545sub print_all_target #26.06.2008 13:27
546############################################################################
547 {
548 my $path = shift;
549 my $ref_all_target_hash = shift;
550 my $filename = getFilenameFromPath($path);
551 my $outdir = $configelements{"Release"}{"OutputDirectory"};
552 print MAKFILE "NULL=\n";
553 print MAKFILE "OUTDIR=$outdir\n";
554 print MAKFILE "OutDir=$outdir\n";
555 print MAKFILE "INTDIR=.\\Release\n\n";
556 print MAKFILE "ALL: ";
557 foreach $target(sort keys %{$ref_all_target_hash})
558 {
559 if ( $target =~ /\.exe/ ) {
560 my $out = $target;
561 $out =~ s/.\\Release/\.\.\\\.\.\\\.\.\\bin/;
562 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/;
563 $out =~ s/\//\\/; # convert / to \
564 $target = $out;
565 }
566 print MAKFILE "\"$target\" ";
567 }
568
569 # Append [Target_<dir>] item e.g. ../../icuxy36.dll
570 my $targetkey = "Target_" . $filename;
571 my @target = ();
572 if ( exists $template_hash{$targetkey} ) {
573 @target = @{$template_hash{$targetkey}};
574 }
575 my $additional_target="";
576 foreach $additional_target(@target)
577 {
578 print MAKFILE $additional_target if ($additional_target ne "");
579 }
580 print MAKFILE "\n\n";
581 print MAKFILE "\"\$(OUTDIR)\" : \n";
582 print MAKFILE "\tif not exist \"\$(OUTDIR)/\$(NULL)\" mkdir \"\$(OUTDIR)\"\n\n";
583 print MAKFILE "!IF \"\$(OUTDIR)\" != \"\$(INTDIR)\"\n";
584 print MAKFILE "\"\$(INTDIR)\" : \n";
585 print MAKFILE "\tif not exist \"\$(INTDIR)/\$(NULL)\" mkdir \"\$(INTDIR)\"\n";
586 print MAKFILE "!ENDIF\n";
587 print MAKFILE "\n\n";
588} ##print_all_target
589
590############################################################################
591sub print_simple_flag #18.04.2008 13:39
592############################################################################
593{
594 my $simple_flag = shift;
595 my @template = @{$template_hash{$simple_flag}};
596 foreach $line(@template)
597 {
598 print MAKFILE $line;
599 }
600} ##print_rules
601
602############################################################################
603sub print_link_template #18.04.2008 13:39
604############################################################################
605{
606 my $dir = shift;
607 my $outfile = shift;
608 my $manifest;
609 # set resource id for manifest file
610 if ( $outfile =~ /\.exe/ ) {
611 $manifest = 1;
612 } else
613 {
614 $manifest = 2;
615 }
616 my @template = ();
617 if ($dir =~ /stubdata/ ) {
618 @template = @{$template_hash{"Special_stubdata"}};
619 } else
620 {
621 @template = @{$template_hash{"LinkTemplate"}};
622 }
623
624 print MAKFILE "\n"; # insert blank line
625 foreach $line(@template)
626 {
627 $line =~ s/<OUTFILE>/$outfile/;
628 $line =~ s/<MANIFEST>/$manifest/;
629 print MAKFILE $line;
630 }
631
632 # insert special stuff for
633 # extras/uconv/uconv.mak
634 if ( $dir =~ /uconv/ ) {
635 print_flags($dir,"","Special");
636 }
637
638 # for *.exe files an additional
639 # copy section is required to get
640 # the stuff into the global bin directory
641 my %dummy = ();
642 my @mak = ();
643 if( $manifest ==1 )
644 {
645 # source,inputpath,target,action
646 my $out = $outfile;
647 $out =~ s/.\\.*Release/\.\.\\\.\.\\\.\.\\bin/;
648 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/;
649 $out =~ s/\//\\/; # subst / with \
650 $outfile =~ s/\//\\/; # subst / with \
651 createCopySection($outfile,$outfile,$out,"copy \"\$(InputPath)\" .\\..\\..\\..\\bin",\@mak,\%dummy);
652 foreach $line(@mak)
653 {
654 print MAKFILE $line;
655 }
656 }
657} ##print_rules
658
659############################################################################
660sub print_rsc_template #04.11.2008 14:48
661############################################################################
662 {
663 # print resource compiler setting + resource target
664 my $resourcefile = shift;
665 # skip this if no res file required
666
667 return if (!$resourcefile);
668 $resfile = $resourcefile;
669 #remove file extension (.res)
670 $resfile =~ /(.+)\\(.+)\.(.+)/;
671 $resfile = $2;
672
673 my @template = @{$template_hash{"RSC_Template"}};
674 print MAKFILE "\n"; # insert blank line
675 foreach $line(@template)
676 {
677 $line =~ s/<FILE>/$resourcefile/;
678 $line =~ s/<FILEOUT>/$resfile/;
679 print MAKFILE $line;
680 }
681} ##print_rsc_template
682
683############################################################################
684sub print_flags #18.04.2008 14:19
685############################################################################
686{
687 # CFlags, LinkFlags
688 my $dir = shift;
689 my $extra_mak = shift; # eg. derb.mak, stringperf.mak
690 my $flag = shift;
691 my $nonpro = shift;
692 my @template = ();
693 my $switch = "";
694 $dir =~ s/\\/_/g if ($dir); # change \ to _
695 $switch = "$flag" . "_" . "$dir" if ($dir);
696 handle_CFlags() if ($flag eq "CFlags"); # get and print Preprocessor defines
697 $switch .= "\." . $extra_mak if ( $extra_mak ne "" ) ;
698 if ( exists $template_hash{$switch} ) {
699 @template = @{$template_hash{$switch}};
700 foreach $line(@template)
701 {
702 if ( $nonpro )
703 {
704 # if non product link against debug libraries
705 $line =~ s/-MD/-MDd/;
706 $line =~ s/-MT/-MTd/;
707 }
708 print MAKFILE $line;
709 }
710 }
711} ##print_flags
712
713############################################################################
714sub handle_CFlags #28.01.2009 11:20
715############################################################################
716 {
717
718 my $ppdefs = $configelements{"Release"}{"PreprocessorDefinitions"};
719 my $ppinc = $configelements{"Release"}{"AdditionalIncludeDirectories"};
720 my @template = @{$template_hash{"General_CFlags"}};
721 $ppdefs =~ s/;/ -D/g; # subst ; with -D switch
722 $ppdefs = "-D" . $ppdefs;
723 $ppinc =~ s/(;|,)/ -I/g; # subst ; with -I switch
724 $ppinc = "-I" . $ppinc;
725 print "ppdefs=$ppdefs\n" if ($is_debug);
726 print "ppinc =$ppinc\n" if ($is_debug);
727 foreach $line(@template)
728 {
729 $line =~ s/<AddIncDirs>/$ppinc/;
730 $line =~ s/<PreProcDefs>/$ppdefs/;
731 print MAKFILE $line;
732 }
733} ##handle_CFlags
734
735############################################################################
736sub print_common_linkflags #21.11.2008 11:47
737############################################################################
738 {
739 my @template = @{$template_hash{"CommonLinkFlags"}};
740 my $outfile = $configelements{"Release"}{"OutputFile"};
741 my $pdbfile = $configelements{"Release"}{"ProgramDatabaseFile"};
742 $pdbfile =~ s/\//\\/; # subst / with \
743 $outfile =~ s/\//\\/; # subst / with \
744 print "PATH=$path OUTFILE=$outfile\n" if ($is_debug);
745 foreach $line(@template)
746 {
747 $line =~ s/<OUTFILE>/$outfile/;
748 $line =~ s/<PDBFILE>/$pdbfile/;
749 print MAKFILE $line;
750 }
751} ##print_common_linkflags
752
753############################################################################
754sub handle_extra_mak_files #25.08.2008 14:32
755############################################################################
756{
757 # extract extra filename for *.mak file
758 # e.g input: tools\genrb.derb
759 # output: derb
760 my $direntry = shift;
761 my $out = "";
762 my $dir = "";
763 if ( $direntry =~ /(.+)\.(.+)$/ ) {
764 $dir = $1;
765 $out = $2;
766 } else
767 {
768 $dir = $direntry;
769 }
770 return ($dir,$out);
771} ##handle_extra_mak_files
772
773############################################################################
774sub prepare_allinone_all_mak
775############################################################################
776{
777 # Read in allinone.sln
778 # Fills hashes and returns an array with build order
779 # uses topographical sorting
780
781 my $href_project_by_id = shift;
782 my $href_project_by_name = shift;
783 my $href_project_dependencies = shift;
784 my $sourcePath = shift;
785
786 my $allslnfile = $sourcePath . "\\allinone\\allinone.sln";
787 my @projectdeps;
788 my $projectname;
789 my $projectpath;
790 my $projectid;
791
792 # fill hash tables
793 open (SLN, "< $allslnfile") || die "Can't open $allslnfile\n";
794 while ($line = <SLN>)
795 {
796 my @project = ();
797 if ( $line =~ /^Project\(/ ) {
798 @project = split( /,/, $line);
799 if ( $#project ) {
800 $projectname = "";
801 $projectpath = "";
802 $projectid = "";
803 @projectdeps = ();
804 my @subarray = ();
805 @subarray = split( /=/, $project[0]);
806 $projectname = $subarray[1];
807 $projectname =~ s/\"//g; # remove "
808 $projectpath = $project[1];
809 $projectid = $project[2];
810 $projectid =~ s/\"//g; # remove "
811 $projectid =~ s/.+\{//g; # remove til {
812 $projectid =~ s/\}\n//g; # remove }<CR>
813 my @pnp = ($projectname,$projectpath);
814 my @pip = ($projectid,$projectpath);
815 $$href_project_by_id{$projectid}=[@pnp];
816 $$href_project_by_name{$projectname} =[@pip];
817 }
818 } # $line =~ /^Project\(/
819 if ( $line =~ /ProjectSection\(/ ) {
820 $psect = 1;
821 next;
822 }
823 if ( $line =~ /EndProjectSection/ ) {
824 $psect = 0;
825 $$href_project_dependencies{$projectid}=[@projectdeps];
826 next;
827 }
828 if ( $psect ) {
829 my @tarray = split(/=/, $line);
830 $depends_on_id = $tarray[0];
831 $depends_on_id =~ s/.+\{//g;
832 $depends_on_id =~ s/\}.+//g;
833 print "+$depends_on_id-\n" if ($is_debug);
834
835 push @projectdeps, $depends_on_id;
836 }
837 }
838 ########################################
839 # sort here and generate build order
840 ########################################
841 $objektzahl=0;
842 %hashindex=();
843
844 foreach $projectid(keys %{$href_project_by_id})
845 {
846 if ( $$href_project_dependencies{$projectid} )
847 {
848 @deps = @{$$href_project_dependencies{$projectid}};
849 } else
850 {
851 @deps = ();
852 }
853 for $counter(0..$#deps)
854 {
855 $v = find_or_create_element($deps[$counter]);
856 $n = find_or_create_element($projectid);
857 push @{$nachfolgerliste[$v]},$n;
858 }
859 }
860
861 for $n (0..$objektzahl-1)
862 {
863 $vorgaengerzahl[$n]=0;
864 }
865 for $v (0..$objektzahl-1)
866 {
867 for $n (@{$nachfolgerliste[$v]})
868 {
869 ++$vorgaengerzahl[$n];
870 }
871 }
872
873 @hilfsliste=();
874 for $n (0..$objektzahl-1)
875 {
876 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0)
877 }
878
879 $ausgabe=0;
880 @builddep =();
881 while (defined($v=pop(@hilfsliste)))
882 {
883 push @builddep, $name[$v]; # save build order by project_id;
884 ++$ausgabe;
885 for $n (@{$nachfolgerliste[$v]})
886 {
887 --$vorgaengerzahl[$n];
888 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0);
889 }
890 } # while
891 die "Cyclic dependencies found! Stopping now.\n" if $ausgabe<$objektzahl;
892 ##############################################################
893 # End of sorting stuff
894 ##############################################################
895
896 return @builddep;
897 ###############################################################
898 ###########################
899 # sub for sorting only
900 ###########################
901 sub find_or_create_element
902 {
903 my ($str)=@_;
904 my ($idx)=$hashindex{$str};
905 if (!defined($idx)) { # new element ...
906 $idx=$objektzahl++;
907 $hashindex{$str}=$idx;
908 $name[$idx]=$str;
909 @{$nachfolgerliste[$idx]}=();
910 }
911 return $idx;
912 } # find_or_create_element
913} # prepare_allinone_all_mak
914
915############################################################################
916sub create_allinone_all_mak #09.02.2009 09:22
917############################################################################
918{
919 my $ref_buildorder = shift;
920 my $href_project_by_id = shift;
921 my $sourcePath = shift;
922 my $allmakfile = $sourcePath . "\\allinone\\all.mak";
923 open (ALLMAK, ">$allmakfile") || die "Can't write to $allmakfile \n";
924 print ALLMAK "ALL: ";
925 foreach $proj(@{$ref_buildorder})
926 {
927 print ALLMAK $$href_project_by_id{$proj}[0];
928 }
929 print ALLMAK "\n\n";
930
931 foreach $proj( @{$ref_buildorder} )
932 {
933 print "$proj $$href_project_by_id{$proj}[0] $$href_project_by_id{$proj}[1]\n";
934 my $prjdir = $$href_project_by_id{$proj}[1];
935 $prjdir =~ /(.+)\\(.+)$/;
936 $prjdir = $1;
937 $prjname = $2;
938 $prjdir =~ s/^.+\"//;
939 $prjname =~ s/\"$//;
940 $prjname =~ s/vcproj/mak/;
941 $allinonehelpstring = $prjdir;
942 $allinonehelpstring =~ s/^\.+\\//; # remove ..\
943 my $backcount = "";
Armin Le Grand3c1d4742014-07-14 19:09:11 +0000944 while ($allinonehelpstring=~ /.+\\/g) # counts the occurring \
Hans-Joachim Lankenau7e997022009-03-24 11:56:29 +0000945 {
946 $backcount .= "..\\";
947 }
948 $allinonedir = $backcount . "..\\allinone";
949
950 # write all.mak
951 $$href_project_by_id{$proj}[0] =~ s/^\s+//;
952 if ( $$href_project_by_id{$proj}[0] ne "makedata" )
953 {
954 my @template = @{$template_hash{"AllInOnePrj"}};
955 foreach $line(@template)
956 {
957 $line =~ s/<PRJ>/$$href_project_by_id{$proj}[0]/;
958 $line =~ s/<PRJDIR>/$prjdir/;
959 $line =~ s/<PRJMAK>/$prjname/;
960 $line =~ s/<ALLINONEDIR>/$allinonedir/;
961 print ALLMAK $line;
962 }
963 } else
964 {
965 #special code snippet
966 print ALLMAK "makedata : \n";
967 print ALLMAK " cd \"..\\data\"\n";
968 print ALLMAK " nmake /f makedata.mak icumake=\$(MAKEDIR)\\..\\data cfg=Release\n";
969 print ALLMAK " cd \"..\\allinone\"\n\n";
970 }
971 }
972 close ALLMAK;
973} ##create_allinone_all_mak
974
975############################################################################
976
977# ------------------------------------------------------------------------
978# XML parser handling
979# ------------------------------------------------------------------------
980
981############################################################################
982sub start_handler
983############################################################################
984{
985 my $p = shift; # pointer to parser
986 my $el = shift; # element
987
988 # Deal with attributes
989
990 my $CompilerSection = 0;
991 my $LinkerSection = 0;
992 my $ConfigSection = ($el eq "Configuration");
993
994 while (@_)
995 {
996 # shift if ( $el eq "FileConfiguration" );
997 my $att = shift;
998 my $val = shift;
999 $CustomSection = 0;
1000 if ($special_file && defined $att & $att ne "Name")
1001 {
1002 print "$special_file - $att - $val\n";
1003 my @param = ($att,$val);
1004 $files_special{ $special_file } = [@param]; # files with special compiler switch
1005 @test = @{$files_special{ $special_file }};
1006 print "test=@test\n";
1007 $special_file="";
1008 }
1009 if ( $ConfigSection && $att eq "Name" && $val eq "Release|Win32" ) {
1010 $Release = 1;
1011 $config = "Release"; # Release
1012 }
1013 if ( $ConfigSection && $att eq "Name" && $val eq "Debug|Win32" ) {
1014 $Release = 0; # Debug
1015 $config = "Debug";
1016 }
1017 if ( $att eq "Name" && $val eq "VCCLCompilerTool" ) {
1018 $CompilerSection = 1;
1019 }
1020 if ( $att eq "Name" && $val eq "VCLinkerTool" ) {
1021 $LinkerSection = 1;
1022 }
1023 if ( $att eq "Name" && $val eq "VCCustomBuildTool" ) {
1024 $CustomSection = 1;
1025 }
1026
1027 # For Configuration Infos like compiler defines etc.
1028 if ( $att eq "PreprocessorDefinitions" && $CompilerSection ) {
1029 $configelements{$config}{$att} = $val;
1030 }
1031 if ( $att eq "AdditionalIncludeDirectories" && $CompilerSection ) {
1032 #$configelements{$config}{$att} = $val;
1033 if ( ($file_tmp ne "") && ($val ne "") ) {
1034 $files{ $file_tmp } = 1; # save it now
1035 $file_tmp =~ s/^\.\\//; # remove leading .\
1036 $files_special{"AdditionalIncludeDirectories"}{$file_tmp} = $val;
1037 print "Include $val: $file_tmp\n" if ($is_debug);
1038 $file_tmp = ""; # has been saved now reset it
1039 } else
1040 {
1041 $configelements{$config}{$att} = $val;
1042 }
1043 }
1044 if ( ($att eq "DisableLanguageExtensions") && $CompilerSection ) {
1045 #$configelements{$config}{$att} = $val;
1046 if ( ($file_tmp ne "") && ($val ne "")) {
1047 $files{ $file_tmp } = 1; # save it now
1048 $file_tmp =~ s/^\.\\//; # remove leading .\
1049 $files_special{"DisableLanguageExtensions"}{$file_tmp} = $val;
1050 print "-Ze: $file_tmp\n" if ($is_debug);
1051 $file_tmp = ""; # has been saved now reset it
1052 }
1053 }
1054 if ( $att eq "OutputDirectory" ) {
1055 $configelements{$config}{$att} = $val;
1056 }
1057 if ( $att eq "OutputFile" && $LinkerSection ) {
1058 $configelements{$config}{$att} = $val;
1059 }
1060 if ( $att eq "ProgramDatabaseFile" ) {
1061 $configelements{$config}{$att} = $val;
1062 }
1063 if ( $att eq "ImportLibrary" && $LinkerSection ) {
1064 $configelements{$config}{$att} = $val;
1065 }
1066 if ($att eq "CommandLine") {
1067 $configelements{$config}{$att} = $val;
1068 }
1069 if (($att eq "PreprocessorDefinitions") && $ConfigSection) {
1070 $configelements{$config}{$att} = $val;
1071 }
1072
1073 # Is the file in the step before a header
1074 # which has to be copied into the global
1075 # include path?
1076 if ( $file_tmp ne "" )
1077 {
1078 $config = "Release";
1079 if ( ($att eq "CommandLine") && ($el eq "Tool") )
1080 {
1081 if ( $file_tmp =~ /.+\.h$/ ) {
1082 $files2copy{ $file_tmp } = $val; # unicode + layout header to copy
1083 $file_tmp = ""; # has been saved now reset it
1084 }
1085 }
1086 } # if $file_tmp
1087
1088 # For files
1089 if ( $att eq "RelativePath" ) {
1090 if ( $file_tmp ) {
1091 # no special file (include dir / compiler switch)
1092 $files{ $file_tmp } = 1; # save it now
1093 $file_tmp = ""; # has been saved now reset it
1094 }
1095 # store temporary the file name
1096 $file_tmp = $val if ($val !~ /\.mk$/); # no *.mk files
1097 }
1098 } # while @_
1099} # End start_handler
1100
1101############################################################################
1102sub char_handler
1103############################################################################
1104{
1105} # End char_handler