msvcmaker 36.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#! /usr/bin/perl -w

# Copyright 2002 Patrik Stridvall

use strict;

BEGIN {
    $0 =~ m%^(.*?/?tools)/winapi/msvcmaker$%;
    require "$1/winapi/setup.pm";
}

Martin Fuchs's avatar
Martin Fuchs committed
12 13
use setup qw($current_dir $wine_dir);
use lib $setup::winapi_dir;
14
use config qw(get_spec_files get_makefile_in_files);
15
use output qw($output);
16
use util qw(replace_file);
17

18
use msvcmaker_options qw($options);
19

20 21 22 23
if($options->progress) {
    $output->enable_progress;
} else {
    $output->disable_progress;
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
}

########################################################################
# main

my @spec_files = get_spec_files("winelib");
my @makefile_in_files = get_makefile_in_files("winelib");

my $wine = 1;

my $output_prefix_dir = "Output";
my $no_release = 1;

my %modules;

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
# These DLLs don't have a hope of compiling properly
my @unix_dependent_dlls = qw(iphlpapi mountmgr.sys ntdll mswsock opengl32
                             secur32 winex11 wnaspi32 ws2_32);

sub is_unix_dependent_dll($) {
    my $dll = shift;

    foreach my $unix_only_dll (@unix_dependent_dlls) {
	if($dll eq $unix_only_dll) {
	    return 1;
	}
    }

    return 0;
}

55
sub read_spec_file($) {
56 57
    my $spec_file = shift;

58 59 60 61 62 63
    my $module = $spec_file;
    $module =~ s%^.*?([^/]+)\.spec$%$1%;
    $module .= ".dll" if $module !~ /\./;

    my $type = "win32";

64
    open(IN, "< $wine_dir/$spec_file") || die "Error: Can't open $wine_dir/$spec_file: $!\n";
65 66 67 68 69 70

    my $header = 1;
    my $lookahead = 0;
    while($lookahead || defined($_ = <IN>)) {
	$lookahead = 0;

71
	s/^\s*?(.*?)\s*$/$1/; # remove whitespace at beginning and end of line
72 73 74 75
	s/^(.*?)\s*#.*$/$1/;  # remove comments
	/^$/ && next;         # skip empty lines

	if($header)  {
76
	    if(/^(?:\d+|@)/) {
77 78 79 80 81 82 83 84 85 86 87 88 89 90
		$header = 0;
		$lookahead = 1;
	    }
	    next;
	}

	if(/^(\d+|@)\s+pascal(?:16)?/) {
	    $type = "win16";
	    last;
	}
    }
    close(IN);

    # FIXME: Kludge
91
    if($module =~ /^(?:(?:imm|ole2conv|ole2prox|ole2thk|rasapi16|msacm|windebug)\.dll|comm\.drv)$/) {
92 93 94 95 96 97 98 99 100 101
	$type = "win16";
    }

    if($type eq "win32") {
	$modules{$module}{module} = $module;
	$modules{$module}{type} = $type;
	$modules{$module}{spec_file} = $spec_file;
    }
}

102 103
if ($options->wine || $options->winetest) {
    foreach my $spec_file (@spec_files) {
104 105 106 107 108
	my $dll = $spec_file;
        $dll =~ s%dlls/([^/]+)/[^/]+\.spec%$1%;
	if(!is_unix_dependent_dll($dll)) {
	    read_spec_file($spec_file);
	}
109 110 111
    }
}

112
my @gdi32_dirs = qw(dlls/gdi32/enhmfdrv dlls/gdi32/mfdrv);
113

114
push @makefile_in_files, "libs/wine/Makefile.in";
115 116
push @makefile_in_files, "tools/winebuild/Makefile.in";

117
sub filter_files($$) {
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    my $files = shift;
    my $filter = shift;

    my $filtered_files = [];
    my $rest_of_files = [];
    foreach my $file (@$files) {
	if($file =~ /$filter/) {
	    $file =~ s%.*?([^/]+)$%./$1%; # FIXME: Kludge
	    push @$filtered_files, $file;
	} else {
	    push @$rest_of_files, $file;
	}
    }
    return ($rest_of_files, $filtered_files);
}

134 135
my %wine_test_dsp_files;

136
MAKEFILE_IN: foreach my $makefile_in_file (@makefile_in_files) {
137
    open(IN, "< $wine_dir/$makefile_in_file") || die "Error: Can't open $wine_dir/$makefile_in_file: $!\n";
138 139 140

    my $topobjdir;
    my $module;
141 142
    my $testdll;
    my @imports;
143
    my $type;
144
    my $dll;
145 146 147 148 149

    my %vars;

    my $again = 0;
    my $lookahead = 0;
150

151 152 153 154 155
    $dll = $makefile_in_file;
    $dll =~ s%dlls/([^/]+)/Makefile\.in%$1%;

    if($makefile_in_file eq "loader/Makefile.in" ||
       is_unix_dependent_dll($dll)) {
156 157 158
        next;
    }

159 160 161 162 163
    while($again || defined(my $line = <IN>)) {
	if(!$again) {
	    chomp $line;
	    if($lookahead) {
		$lookahead = 0;
164
		$_ .= " " . $line;
165 166 167 168 169 170 171
	    } else {
		$_ = $line;
	    }
	} else {
	    $again = 0;
	}

172
	s/^\s*?(.*?)\s*$/$1/; # remove whitespace at beginning and end of line
173 174 175 176 177 178 179 180 181 182 183 184
	s/^(.*?)\s*#.*$/$1/;  # remove comments
	/^$/ && next;         # skip empty lines

	if(s/\\$/ /s) {
	    $lookahead = 1;
	    next;
	}

	if(/^MODULE\s*=\s*([\w\.]+)$/) {
	    $module = $1;

	    if($module eq "none") {
185
		if($makefile_in_file eq "tools/winebuild/Makefile.in") {
186
		    $module = "winebuild.exe";
187 188
		} elsif ($makefile_in_file eq "include/Makefile.in") {
		    $module = "include.lib";
189 190 191 192
		} else {
		    next MAKEFILE_IN;
		}
	    }
193 194
	} elsif (/^\@MAKE_IMPLIB_RULES\@/) {
	    $type = "lib";
195 196
	} elsif(/^TOPOBJDIR\s*=\s*(\S+)\s*$/) {
	    $topobjdir = $1;
197 198 199
	} elsif (/^TESTDLL\s*=\s*(\S+)\s*$/) {
	    $testdll = $1;
	} elsif (/^IMPORTS\s*=\s*/) {
200
            push @imports, grep !/^ntdll$/, split /\s+/s, $';
201 202
	} elsif (/^DELAYIMPORTS\s*=\s*/) {
            push @imports, $;
203 204
	} elsif (/^EXTRALIBS\s*=\s*/) {
            push @imports, map { /^-l(dxerr8|dxerr9|dxguid|strmiids|uuid)$/ ? $1 : () } split /\s+/s, $';
205
	} elsif (/^CTESTS\s*=\s*/ || ( ($makefile_in_file =~ /\/tests\/Makefile\.in$/) && /^C_SRCS\s*=\s*/ ) ) {
206 207 208 209
	    my @files = split /\s+/s, $';

	    my $dir = $makefile_in_file;
	    $dir =~ s/\/Makefile\.in$//;
210

211
	    my $dsp_file = $testdll;
212
	    $dsp_file =~ s/\.(dll|drv)$/_test.dsp/;
213 214 215 216
	    $dsp_file = "$dir/$dsp_file";

	    $wine_test_dsp_files{$dsp_file}{files} = [@files, "testlist.c"];
	    $wine_test_dsp_files{$dsp_file}{imports} = [@imports];
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
	} elsif(/^(\w+)\s*=\s*/) {
	    my $var = $1;
	    my @files = split /\s+/s, $';

	    @files = map {
		if(/^\$\((\w+):\%=(.*?)\%(.*?)\)$/) {
		    my @list = @{$vars{$1}};
		    my $prefix = $2;
		    my $suffix = $3;
		    foreach my $item (@list) {
			$item = "$prefix$item$suffix";
		    }
		    @list;
		} elsif(/^\$\(TOPOBJDIR\)(.*?)$/) {
		    "$topobjdir$1";
		} elsif(/^\$/) {
		    print STDERR "unknown variable '$_'\n" if 0;
		    ();
		} else {
		    $_;
		}
	    } @files;

	    $vars{$var} = \@files;
	}
    }

    close(IN);

246 247 248 249
    if (!$module && $makefile_in_file eq "libs/wine/Makefile.in") {
	$module = "wine.lib";
    }

250 251
    next if !$module;

252
    my $c_srcs = [];
253 254
    my $source_files = [];
    if(exists($vars{C_SRCS})) {
255
	$c_srcs = [sort(@{$vars{C_SRCS}})];
256 257 258 259 260 261 262 263 264 265 266 267 268
	$source_files = [sort(@{$vars{C_SRCS}})];
    }

    my $header_files = [];
    if(exists($vars{H_SRCS})) {
	$header_files = [sort(@{$vars{H_SRCS}})];
    }

    my $resource_files = [];
    if(exists($vars{RC_SRCS})) {
	$resource_files = [sort(@{$vars{RC_SRCS}})];
    }

269 270 271 272 273
    my $idl_h_files = [];
    if(exists($vars{IDL_H_SRCS})) {
	$idl_h_files = [sort(@{$vars{IDL_H_SRCS}})];
    }

274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
    my $idl_c_files = [];
    if(exists($vars{IDL_C_SRCS})) {
	$idl_c_files = [sort(@{$vars{IDL_C_SRCS}})];
    }

    my $idl_s_files = [];
    if(exists($vars{IDL_S_SRCS})) {
	$idl_s_files = [sort(@{$vars{IDL_S_SRCS}})];
    }

    my $idl_p_files = [];
    if(exists($vars{IDL_P_SRCS})) {
	$idl_p_files = [sort(@{$vars{IDL_P_SRCS}})];
    }

    my $idl_tlb_files = [];
    if(exists($vars{IDL_TLB_SRCS})) {
	$idl_tlb_files = [sort(@{$vars{IDL_TLB_SRCS}})];
    }

294 295 296 297 298
    my $extradefs;
    if(exists($vars{EXTRADEFS})) {
	$extradefs = $vars{EXTRADEFS};
    }

299 300 301 302 303 304 305 306
    my $project = $module;
    $project =~ s/\.(?:dll|exe|lib)$//;
    $project =~ y/./_/;

    if($module =~ /\.exe$/) {
	$type = "exe";
    } elsif($module =~ /\.lib$/) {
	$type = "lib";
307
    } elsif(!$type) {
308 309 310 311 312 313
	$type = "dll";
    }

    my $dsp_file = $makefile_in_file;
    $dsp_file =~ s/Makefile.in$/$project.dsp/;

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
    if($module eq "gdi32.dll") {
	foreach my $dir (@gdi32_dirs) {
	    my $dir2 = $dir;
	    $dir2 =~ s%^.*?/([^/]+)$%$1%;

	    my $module = "gdi32_$dir2.lib";
	    $module =~ s%/%_%g;

	    my $project = "gdi32_$dir2";
	    $project =~ s%/%_%g;

	    my $type = "lib";
	    my $dsp_file = "$dir/$project.dsp";

	    ($source_files, my $local_source_files) = filter_files($source_files, "$dir2/");
	    ($header_files, my $local_header_files) = filter_files($header_files, "$dir2/");
	    ($resource_files, my $local_resource_files) = filter_files($resource_files, "$dir2/");
331
	    ($idl_h_files, my $local_idl_h_files) = filter_files($idl_h_files, "$dir2/");
332

333 334
	    $modules{$module}{wine} = 1;
	    $modules{$module}{winetest} = 0;
335 336 337
	    $modules{$module}{project} = $project;
	    $modules{$module}{type} = $type;
	    $modules{$module}{dsp_file} = $dsp_file;
338
	    $modules{$module}{c_srcs} = $c_srcs;
339 340 341
	    $modules{$module}{source_files} = $local_source_files;
	    $modules{$module}{header_files} = $local_header_files;
	    $modules{$module}{resource_files} = $local_resource_files;
342
	    $modules{$module}{imports} = [];
343
	    $modules{$module}{idl_h_files} = $local_idl_h_files;
344 345 346 347
	    $modules{$module}{idl_c_files} = [];
	    $modules{$module}{idl_s_files} = [];
	    $modules{$module}{idl_p_files} = [];
	    $modules{$module}{idl_tlb_files} = [];
348
	    $modules{$module}{extradefs} = $extradefs if $extradefs;
349 350 351
	}
    }

352 353
    $modules{$module}{wine} = 1;
    $modules{$module}{winetest} = 0;
354 355 356
    $modules{$module}{project} = $project;
    $modules{$module}{type} = $type;
    $modules{$module}{dsp_file} = $dsp_file;
357
    $modules{$module}{c_srcs} = $c_srcs;
358 359 360
    $modules{$module}{source_files} = $source_files;
    $modules{$module}{header_files} = $header_files;
    $modules{$module}{resource_files} = $resource_files;
361
    $modules{$module}{imports} = [@imports];
362
    $modules{$module}{idl_h_files} = $idl_h_files;
363 364 365 366
    $modules{$module}{idl_c_files} = $idl_c_files;
    $modules{$module}{idl_s_files} = $idl_s_files;
    $modules{$module}{idl_p_files} = $idl_p_files;
    $modules{$module}{idl_tlb_files} = $idl_tlb_files;
367
    $modules{$module}{extradefs} = $extradefs if $extradefs;
368 369
}

370 371 372 373 374 375
$wine_test_dsp_files{"wineruntests.dsp"}{files} = ["runtests.c"];
$wine_test_dsp_files{"wineruntests.dsp"}{imports} = [];

$wine_test_dsp_files{"winetest.dsp"}{files} = [
  'include/wine/exception.h',
  'include/wine/test.h',
376 377
  'include/wine/unicode.h',
  'winetest.c'
378
];
379 380 381
$wine_test_dsp_files{"winetest.dsp"}{imports} = [];

my %runtests = ();
382

383
foreach my $dsp_file (keys(%wine_test_dsp_files)) {
384
    my $project = $dsp_file;
385
    $project =~ s%^(?:.*?/)?([^/]+)\.dsp$%$1%;
386

387 388 389
    my @files = @{$wine_test_dsp_files{$dsp_file}{files}};
    my @imports = @{$wine_test_dsp_files{$dsp_file}{imports}};

390 391 392 393 394
    my $type;
    my $c_srcs = [];
    my $source_files = [];
    my $header_files = [];
    my $resource_files = [];
395
    my $idl_h_files = [];
396

397 398
    my @tests = ();

399 400
    if ($project eq "winetest") {
	$type = "lib";
401 402
	$c_srcs = [@files];
	$source_files = [@files];
403 404
	$header_files = [];
	$resource_files = [];
405 406 407 408 409 410
    } elsif ($project eq "wineruntests") {
	$type = "exe";
	$c_srcs = [@files];
	$source_files = [@files];
	$header_files = [];
	$resource_files = [];
411 412
    } else {
	$type = "exe";
413 414
	$c_srcs = [@files];
	$source_files = [@files];
415 416
	$header_files = [];
	$resource_files = [];
417 418 419 420 421 422 423 424 425
	
	@tests = map {
	    if (/^testlist\.c$/) {
		();
	    } else {
		s/\.c$//;
		$_;
	    }
	} @files;
426 427

	$runtests{$dsp_file} = [@tests];
428 429 430
    }
    my $module = "$project.$type";

431 432 433
    $modules{$module}{wine} = 0;
    $modules{$module}{winetest} = 1;

434 435 436 437 438 439 440
    $modules{$module}{project} = $project;
    $modules{$module}{type} = $type;
    $modules{$module}{dsp_file} = $dsp_file;
    $modules{$module}{c_srcs} = $c_srcs;
    $modules{$module}{source_files} = $source_files;
    $modules{$module}{header_files} = $header_files;
    $modules{$module}{resource_files} = $resource_files;
441
    $modules{$module}{imports} = [@imports];
442
    $modules{$module}{idl_h_files} = [];
443 444 445 446
    $modules{$module}{idl_c_files} = [];
    $modules{$module}{idl_s_files} = [];
    $modules{$module}{idl_p_files} = [];
    $modules{$module}{idl_tlb_files} = [];
447 448

    $modules{$module}{tests} = [@tests];
449 450
}

451 452 453 454 455 456
foreach my $module (sort(keys(%modules))) {
    if($module =~ /^(?:ttydrv.dll|x11drv.dll)$/) {
	delete $modules{$module};
    }
}

457 458 459 460 461 462 463 464 465
my @modules = ();
foreach my $module (sort(keys(%modules))) {
    if (($options->wine && $modules{$module}{wine}) ||
	($options->winetest && $modules{$module}{winetest}))
    {
	push @modules, $module;
    }
}

466 467
my $progress_output;
my $progress_current = 0;
468
my $progress_max = scalar(@modules);
469

470
foreach my $module (@modules) {
471 472 473 474
    my $dsp_file = $modules{$module}{dsp_file};
    replace_file("$wine_dir/$dsp_file", \&_generate_dsp, $module);
}

475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
sub output_dsp_idl_rules($$$) {
    my $wine_include_dir = shift;
    my $ext = shift;
    my @idl_src_files = @{(shift)};

    foreach my $idl_src_file (@idl_src_files) {
	$idl_src_file =~ s%/%\\%g;
	if($idl_src_file !~ /^\./) {
	    $idl_src_file = ".\\$idl_src_file";
	}

	print OUT "# Begin Source File\r\n";
	print OUT "\r\n";

	print OUT "SOURCE=$idl_src_file\r\n";

	my $basename = $idl_src_file;
	$basename =~ s/\.idl$//;

	print OUT "# PROP Ignore_Default_Tool 1\r\n";
	print OUT "# Begin Custom Build\r\n";
	print OUT "InputPath=$idl_src_file\r\n";
	print OUT "\r\n";
	print OUT "BuildCmds= \\\r\n";
	print OUT "\tmidl /nologo /I $wine_include_dir $idl_src_file ";
	if ($ext eq ".h") {
	    print OUT "/client none /server none /notlb /h ";
	} elsif ($ext eq "_c.c") {
	    print OUT "/server none /notlb /cstub ";
	} elsif ($ext eq "_s.c") {
	    print OUT "/client none /notlb /sstub ";
	} elsif ($ext eq "_p.c") {
	    print OUT "/client none /server none /notlb /proxy ";
	} elsif ($ext eq ".tlb") {
	    print OUT "/client none /server none /tlb ";
	}
        print OUT "$basename$ext\r\n";
	print OUT "\r\n";
	print OUT "\"$basename$ext\" : \$(SOURCE) \"\$(INTDIR)\" \"\$(OUTDIR)\"\r\n";
	print OUT "   \$(BuildCmds)\r\n";
	print OUT "# End Custom Build\r\n";

	print OUT "# End Source File\r\n";
    }
}

521
sub _generate_dsp($$) {
522 523 524 525 526 527
    local *OUT = shift;

    my $module = shift;

    my $dsp_file = $modules{$module}{dsp_file};
    my $project = $modules{$module}{project};
528
    my @imports = @{$modules{$module}{imports}};
529 530 531 532 533

    my $lib = ($modules{$module}{type} eq "lib");
    my $dll = ($modules{$module}{type} eq "dll");
    my $exe = ($modules{$module}{type} eq "exe");

534
    my $console = $exe; # FIXME: Not always correct
535

536
    my $msvc_wine_dir = do {
537 538
	my @parts = split(m%/%, $dsp_file);
	if($#parts == 1) {
539
	    "..";
540
	} elsif($#parts == 2) {
541
	    "..\\..";
542
	} else {
543
	    "..\\..\\..";
544 545
	}
    };
546
    my $wine_include_dir = "$msvc_wine_dir\\include";
547 548 549 550

    $progress_current++;
    $output->progress("$dsp_file (file $progress_current of $progress_max)");

551 552 553
    my $base_module = $module;
	$base_module =~ s/\.(?:dll)$//;

554
    my @c_srcs = @{$modules{$module}{c_srcs}};
555 556 557
    my @source_files = @{$modules{$module}{source_files}};
    my @header_files = @{$modules{$module}{header_files}};
    my @resource_files = @{$modules{$module}{resource_files}};
558
    my @idl_h_files = @{$modules{$module}{idl_h_files}};
559 560 561 562
    my @idl_c_files = @{$modules{$module}{idl_c_files}};
    my @idl_s_files = @{$modules{$module}{idl_s_files}};
    my @idl_p_files = @{$modules{$module}{idl_p_files}};
    my @idl_tlb_files = @{$modules{$module}{idl_tlb_files}};
563

564
    if ($project !~ /^wine(?:build|runtests|test)?$/ &&
565
        $project !~ /^(?:gdi32)_.+?$/ &&
566 567
        $project !~ /_test$/ &&
        !$lib)
568
    {
569
	push @source_files, "$base_module.spec";
570 571 572
	@source_files = sort(@source_files);
    }

573
    my $no_cpp = 1;
574
    my $no_msvc_headers = 1;
575
    if ($project =~ /^wine(?:runtests|test)$/ || $project =~ /_test$/) {
576 577 578
	$no_msvc_headers = 0;
    }

579
    my @cfgs;
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598

    push @cfgs, "$project - Win32";

    if (!$no_cpp) {
	my @_cfgs;
	foreach my $cfg (@cfgs) {
	    push @_cfgs, "$cfg C";
	    push @_cfgs, "$cfg C++";
	}
	@cfgs = @_cfgs;
    }

    if (!$no_release) {
	my @_cfgs;
	foreach my $cfg (@cfgs) {
	    push @_cfgs, "$cfg Debug";
	    push @_cfgs, "$cfg Release";
	}
	@cfgs = @_cfgs;
599 600 601 602 603 604
    } else {
	my @_cfgs;
	foreach my $cfg (@cfgs) {
	    push @_cfgs, "$cfg Debug";
	}
	@cfgs = @_cfgs;
605 606 607 608 609 610 611 612 613
    }

    if (!$no_msvc_headers) {
	my @_cfgs;
	foreach my $cfg (@cfgs) {
	    push @_cfgs, "$cfg MSVC Headers";
	    push @_cfgs, "$cfg Wine Headers";
	}
	@cfgs = @_cfgs;
614
    }
615

616 617 618 619 620 621 622
    my $default_cfg = $cfgs[$#cfgs];

    print OUT "# Microsoft Developer Studio Project File - Name=\"$project\" - Package Owner=<4>\r\n";
    print OUT "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n";
    print OUT "# ** DO NOT EDIT **\r\n";
    print OUT "\r\n";

623
    if ($lib) {
624
	print OUT "# TARGTYPE \"Win32 (x86) Static Library\" 0x0104\r\n";
625
    } elsif ($dll) {
626
	print OUT "# TARGTYPE \"Win32 (x86) Dynamic-Link Library\" 0x0102\r\n";
627 628
    } else {
	print OUT "# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\r\n";
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
    }
    print OUT "\r\n";

    print OUT "CFG=$default_cfg\r\n";
    print OUT "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n";
    print OUT "!MESSAGE use the Export Makefile command and run\r\n";
    print OUT "!MESSAGE \r\n";
    print OUT "!MESSAGE NMAKE /f \"$project.mak\".\r\n";
    print OUT "!MESSAGE \r\n";
    print OUT "!MESSAGE You can specify a configuration when running NMAKE\r\n";
    print OUT "!MESSAGE by defining the macro CFG on the command line. For example:\r\n";
    print OUT "!MESSAGE \r\n";
    print OUT "!MESSAGE NMAKE /f \"$project.mak\" CFG=\"$default_cfg\"\r\n";
    print OUT "!MESSAGE \r\n";
    print OUT "!MESSAGE Possible choices for configuration are:\r\n";
    print OUT "!MESSAGE \r\n";
    foreach my $cfg (@cfgs) {
646
	if ($lib) {
647
	    print OUT "!MESSAGE \"$cfg\" (based on \"Win32 (x86) Static Library\")\r\n";
648
	} elsif ($dll) {
649
	    print OUT "!MESSAGE \"$cfg\" (based on \"Win32 (x86) Dynamic-Link Library\")\r\n";
650 651
	} else {
	    print OUT "!MESSAGE \"$cfg\" (based on \"Win32 (x86) Console Application\")\r\n";
652 653 654 655 656 657 658 659 660 661
	}
    }
    print OUT "!MESSAGE \r\n";
    print OUT "\r\n";

    print OUT "# Begin Project\r\n";
    print OUT "# PROP AllowPerConfigDependencies 0\r\n";
    print OUT "# PROP Scc_ProjName \"\"\r\n";
    print OUT "# PROP Scc_LocalPath \"\"\r\n";
    print OUT "CPP=cl.exe\r\n";
662
    print OUT "MTL=midl.exe\r\n" if !$lib && !$exe;
663
    print OUT "RSC=rc.exe\r\n";
664
    print OUT "\r\n";
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681

    my $n = 0;

    my $output_dir;
    foreach my $cfg (@cfgs) {
	if($#cfgs == 0) {
	    # Nothing
	} elsif($n == 0) {
	    print OUT "!IF  \"\$(CFG)\" == \"$cfg\"\r\n";
	    print OUT "\r\n";
	} else {
	    print OUT "\r\n";
	    print OUT "!ELSEIF  \"\$(CFG)\" == \"$cfg\"\r\n";
	    print OUT "\r\n";
	}

	my $debug = ($cfg !~ /Release/);
682
	my $msvc_headers = ($cfg =~ /MSVC Headers/);
683 684 685 686 687 688 689 690 691 692

	print OUT "# PROP BASE Use_MFC 0\r\n";

	if($debug) {
	    print OUT "# PROP BASE Use_Debug_Libraries 1\r\n";
	} else {
	    print OUT "# PROP BASE Use_Debug_Libraries 0\r\n";
	}

	$output_dir = $cfg;
693 694
	$output_dir =~ s/^$project - //;
	$output_dir =~ s/ /_/g;
695
	$output_dir =~ s/C\+\+/Cxx/g;
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
	if($output_prefix_dir) {
	    $output_dir = "$output_prefix_dir\\$output_dir";
	}

	print OUT "# PROP BASE Output_Dir \"$output_dir\"\r\n";
	print OUT "# PROP BASE Intermediate_Dir \"$output_dir\"\r\n";

	print OUT "# PROP BASE Target_Dir \"\"\r\n";

	print OUT "# PROP Use_MFC 0\r\n";
	if($debug) {
	    print OUT "# PROP Use_Debug_Libraries 1\r\n";
	} else {
	    print OUT "# PROP Use_Debug_Libraries 0\r\n";
	}
	print OUT "# PROP Output_Dir \"$output_dir\"\r\n";
	print OUT "# PROP Intermediate_Dir \"$output_dir\"\r\n";

714
	print OUT "# PROP Ignore_Export_Lib 0\r\n" if $dll;
715 716
	print OUT "# PROP Target_Dir \"\"\r\n";

717 718
	print OUT "# ADD BASE CPP /nologo ";
	my @defines = qw(WINVER=0x0600 _WIN32_WINNT=0x0600 _WIN32_IE=0x0700 WIN32);
719
	if($debug) {
720
	    if($lib || $exe) {
721
		push @defines, qw(_DEBUG _MBCS _LIB);
722
	    } else {
723
		print OUT "/MDd ";
724
		push @defines, qw(_DEBUG _WINDOWS _MBCS _USRDLL);
725
	    }
726
	    print OUT "/W3 /Gm /GX /Zi /Od";
727
	} else {
728
	    if($lib || $exe) {
729
		push @defines, qw(NDEBUG _MBCS _LIB);
730
	    } else {
731
		print OUT "/MD ";
732
		push @defines, qw(NDEBUG _WINDOWS _MBCS _USRDLL);
733
	    }
734
	    print OUT "/W3 /GX /O2";
735 736 737
	}

	foreach my $define (@defines) {
738 739 740 741 742
	    if ($define !~ /=/) {
		print OUT " /D \"$define\"";
	    } else {
		print OUT " /D $define";
	    }
743
	}
744
	print OUT " /YX" if $lib || $exe;
745 746 747 748 749
	print OUT " /FD";
	print OUT " /GZ" if $debug;
	print OUT " /c";
	print OUT "\r\n";

750 751 752
	my @defines2 = qw(_CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE
                          USE_COMPILER_EXCEPTIONS _USE_MATH_DEFINES
                          WINVER=0x0600 _WIN32_WINNT=0x0600 _WIN32_IE=0x0700);
753 754
	if($debug) {
	    if($lib) {
755
		print OUT "# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od";
756
		push @defines2, qw(WIN32 _DEBUG _WINDOWS _MBCS _LIB);
757
	    } else {
758
		print OUT "# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od";
759
		push @defines2, qw(_DEBUG WIN32 _WINDOWS _MBCS _USRDLL);
760 761 762
	    }
	} else {
	    if($lib) {
763
		print OUT "# ADD CPP /nologo /MD /W3 /GX /O2";
764
		push @defines2, qw(WIN32 NDEBUG _WINDOWS _MBCS _LIB);
765
	    } else {
766
		print OUT "# ADD CPP /nologo /MD /W3 /GX /O2";
767
		push @defines2, qw(NDEBUG WIN32 _WINDOWS _MBCS _USRDLL);
768 769 770
	    }
	}

771
	my @includes = ();
772
	if($wine) {
773
	    push @defines2, qw(__WINESRC__) if $project !~ /^(?:wine(?:build|test)|.*?_test)$/;
774 775 776
	    if ($msvc_headers) {
	    	push @defines2, qw(__WINE_USE_NATIVE_HEADERS);
	    }
777
	    my $output_dir2 = $output_dir;
778 779
	    $output_dir2 =~ s/\\/\\\\/g;
	    push @defines2, "__WINETEST_OUTPUT_DIR=\\\"$output_dir2\\\"";
780 781
	    push @defines2, qw(__i386__ _X86_);

782 783 784 785
	    if ($project eq "wine") {
		push @defines2, "WINE_UNICODE_API=";
	    }

786
	    if ($project =~ /_test$/) {
787
		push @includes, "$msvc_wine_dir\\$output_dir";
788
	    }
789

790
	    if (!$msvc_headers || $project eq "winetest") {
791 792
		push @includes, $wine_include_dir;
	    }
793 794 795
	}

	if($wine) {
796
	    foreach my $include (@includes) {
797
                print OUT " /I \"$include\"";
798 799 800 801
	    }
	}

	foreach my $define (@defines2) {
802
	    if ($define !~ /=/) {
803 804 805 806
		print OUT " /D \"$define\"";
	    } else {
		print OUT " /D $define";
	    }
807 808 809 810
	}
	print OUT " /D inline=__inline" if $wine;
	print OUT " /D \"__STDC__\"" if 0 && $wine;

811 812 813 814
	if(exists($modules{$module}{extradefs})) {
	    print OUT " @{$modules{$module}{extradefs}} ";
	}

815 816 817 818 819
	print OUT " /YX" if $lib;
	print OUT " /FR" if !$lib;
	print OUT " /FD";
	print OUT " /GZ" if $debug;
	print OUT " /c";
820
	print OUT " /TP" if !$no_cpp;
821 822 823
	print OUT "\r\n";

	if($debug) {
824 825 826
	    print OUT "# SUBTRACT CPP /X /YX\r\n" if $dll;
	    print OUT "# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n" if $dll;
	    print OUT "# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n" if $dll;
827
	    print OUT "# ADD BASE RSC /l 0x41d /d \"_DEBUG\"\r\n";
828 829 830
	    print OUT "# ADD RSC /l 0x41d";
	    if($wine) {
		foreach my $include (@includes) {
831
		    print OUT " /i \"$include\"";
832 833 834
		}
	    }
	    print OUT " /d \"_DEBUG\"\r\n";
835
	} else {
836 837 838
	    print OUT "# SUBTRACT CPP /YX\r\n" if $dll;
	    print OUT "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n" if $dll;
	    print OUT "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n" if $dll;
839
	    print OUT "# ADD BASE RSC /l 0x41d /d \"NDEBUG\"\r\n";
840 841 842
	    print OUT "# ADD RSC /l 0x41d";
	    if($wine) {
		foreach my $include (@includes) {
843
		    print OUT " /i \"$include\"";
844 845 846
		}
	    }
	    print OUT "/d \"NDEBUG\"\r\n";
847 848 849 850 851 852 853
	}
	print OUT "BSC32=bscmake.exe\r\n";
	print OUT "# ADD BASE BSC32 /nologo\r\n";
	print OUT "# ADD BSC32 /nologo\r\n";

	if($exe || $dll) {
	    print OUT "LINK32=link.exe\r\n";
854
	    print OUT "# ADD BASE LINK32";
855 856 857 858
	    my @libraries = qw(kernel32.lib user32.lib gdi32.lib winspool.lib
			       comdlg32.lib advapi32.lib shell32.lib ole32.lib
			       oleaut32.lib uuid.lib odbc32.lib odbccp32.lib);
	    foreach my $library (@libraries) {
859
		print OUT " $library";
860
	    }
861 862 863 864 865 866 867
	    print OUT " /nologo";
	    print OUT " /dll" if $dll;
            print OUT " /subsystem:console" if $console;
	    print OUT " /debug" if $debug;
	    print OUT " /machine:I386";
	    print OUT " /pdbtype:sept" if $debug;
	    print OUT "\r\n";
868

869
	    print OUT "# ADD LINK32";
870
	    print OUT " libcmt.lib" if $project =~ /^ntdll$/; # FIXME: Kludge
871
	    foreach my $import (@imports) {
872
		print OUT " $import.lib" if ($import ne "msvcrt");
873
	    }
874
	    print OUT " /nologo";
875
	    print OUT " /dll" if $dll;
876
            print OUT " /subsystem:console" if $console;
877 878
	    print OUT " /debug" if $debug;
	    print OUT " /machine:I386";
879
	    print OUT " /nodefaultlib" if $project =~ /^ntdll$/; # FIXME: Kludge
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
	    print OUT " /def:\"$project.def\"" if $dll;
	    print OUT " /pdbtype:sept" if $debug;
	    print OUT "\r\n";
	} else {
	    print OUT "LIB32=link.exe -lib\r\n";
	    print OUT "# ADD BASE LIB32 /nologo\r\n";
	    print OUT "# ADD LIB32 /nologo\r\n";
	}

	$n++;
    }

    if($#cfgs != 0) {
	print OUT "\r\n";
	print OUT "!ENDIF \r\n";
	print OUT "\r\n";
    }

    print OUT "# Begin Target\r\n";
    print OUT "\r\n";
    foreach my $cfg (@cfgs) {
	print OUT "# Name \"$cfg\"\r\n";
    }

    print OUT "# Begin Group \"Source Files\"\r\n";
    print OUT "\r\n";
    print OUT "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";

908 909 910 911 912 913 914 915 916 917
    if ($project eq "winebuild") {
        for my $ source_file ("getopt.c", "getopt1.c", "mkstemps.c")
        {
            print OUT "# Begin Source File\r\n";
            print OUT "\r\n";
            print OUT "SOURCE=..\\..\\libs\\port\\$source_file\r\n";
            print OUT "# End Source File\r\n";
        }
    }

918 919 920 921 922 923
    foreach my $source_file (@source_files) {
	$source_file =~ s%/%\\%g;
	if($source_file !~ /^\./) {
	    $source_file = ".\\$source_file";
	}

924 925 926
	print OUT "# Begin Source File\r\n";
	print OUT "\r\n";

927 928
	print OUT "SOURCE=$source_file\r\n";

929 930 931 932
	if ($project eq "wine" && $source_file eq ".\\config.c") {
	    print OUT "# ADD CPP /D BINDIR=\\\"\\\" /D DLLDIR=\\\"\\\" /D LIB_TO_BINDIR=\\\"\\\" /D LIB_TO_DLLDIR=\\\"\\\" /D BIN_TO_DLLDIR=\\\"\\\" /D LIB_TO_DATADIR=\\\"\\\" /D BIN_TO_DATADIR=\\\"\\\"\r\n";
	}

933
	if($source_file =~ /^(.*?)\.spec$/) {
934 935
	    my $basename = $1;

936
	    my $spec_file = $source_file;
937 938 939
	    my $def_file = "$basename.def";

	    my $srcdir = "."; # FIXME: Is this really always correct?
940 941 942 943

	    print OUT "# Begin Custom Build\r\n";
	    print OUT "InputPath=$spec_file\r\n";
	    print OUT "\r\n";
944
	    print OUT "BuildCmds= \\\r\n";
945
	    print OUT "\t..\\..\\tools\\winebuild\\$output_dir\\winebuild.exe -w --def -k -o $def_file --export $spec_file\r\n";
946
	    print OUT "\r\n";
947
	    print OUT "\"$def_file\" : \$(SOURCE) \"\$(INTDIR)\" \"\$(OUTDIR)\"\r\n";
948
	    print OUT "   \$(BuildCmds)\r\n";
949
	    print OUT "# End Custom Build\r\n";
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977
	} elsif($source_file =~ /([^\\]*?\.h)$/) {
	    my $h_file = $1;

	    foreach my $cfg (@cfgs) {
		if($#cfgs == 0) {
		    # Nothing
		} elsif($n == 0) {
		    print OUT "!IF  \"\$(CFG)\" == \"$cfg\"\r\n";
		    print OUT "\r\n";
		} else {
		    print OUT "\r\n";
		    print OUT "!ELSEIF  \"\$(CFG)\" == \"$cfg\"\r\n";
		    print OUT "\r\n";
		}

		$output_dir = $cfg;
		$output_dir =~ s/^$project - //;
		$output_dir =~ s/ /_/g;
		$output_dir =~ s/C\+\+/Cxx/g;
		if($output_prefix_dir) {
		    $output_dir = "$output_prefix_dir\\$output_dir";
		}

		print OUT "# Begin Custom Build\r\n";
		print OUT "OutDir=$output_dir\r\n";
		print OUT "InputPath=$source_file\r\n";
		print OUT "\r\n";
		print OUT "\"\$(OutDir)\\wine\\$h_file\" : \$(SOURCE) \"\$(INTDIR)\" \"\$(OUTDIR)\"\r\n";
978
		print OUT "\tcopy \"\$(InputPath)\" \"\$(OutDir)\\wine\"\r\n";
979 980 981 982 983 984 985 986 987
		print OUT "\r\n";
		print OUT "# End Custom Build\r\n";
	    }

	    if($#cfgs != 0) {
		print OUT "\r\n";
		print OUT "!ENDIF \r\n";
		print OUT "\r\n";
	    }
988 989 990 991
	}

	print OUT "# End Source File\r\n";
    }
992

993 994 995 996 997 998 999
    output_dsp_idl_rules $wine_include_dir, ".h", \@idl_h_files;
    output_dsp_idl_rules $wine_include_dir, "_c.c", \@idl_c_files;
    output_dsp_idl_rules $wine_include_dir, "_s.c", \@idl_s_files;
    output_dsp_idl_rules $wine_include_dir, "_p.c", \@idl_p_files;
    # Hack - stdole2.idl cannot be compiled with midl
    if($project ne "include") {
	output_dsp_idl_rules $wine_include_dir, ".tlb", \@idl_tlb_files;
1000 1001
    }

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
    print OUT "# End Group\r\n";

    print OUT "# Begin Group \"Header Files\"\r\n";
    print OUT "\r\n";
    print OUT "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
    foreach my $header_file (@header_files) {
	print OUT "# Begin Source File\r\n";
	print OUT "\r\n";
	print OUT "SOURCE=.\\$header_file\r\n";
	print OUT "# End Source File\r\n";
    }
    print OUT "# End Group\r\n";



    print OUT "# Begin Group \"Resource Files\"\r\n";
    print OUT "\r\n";
    print OUT "# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
    foreach my $resource_file (@resource_files) {
	print OUT "# Begin Source File\r\n";
	print OUT "\r\n";
	print OUT "SOURCE=.\\$resource_file\r\n";
	print OUT "# End Source File\r\n";
    }
    print OUT "# End Group\r\n";

    print OUT "# End Target\r\n";
    print OUT "# End Project\r\n";

    close(OUT);
}

1034
sub _generate_dsw_header($) {
1035 1036 1037 1038 1039 1040 1041
    local *OUT = shift;

    print OUT "Microsoft Developer Studio Workspace File, Format Version 6.00\r\n";
    print OUT "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n";
    print OUT "\r\n";
}

1042
sub _generate_dsw_project($$$$) {
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
    local *OUT = shift;

    my $project = shift;
    my $dsp_file = shift;
    my @dependencies = @{(shift)};

    $dsp_file = "./$dsp_file";
    $dsp_file =~ y%/%\\%;
    
    @dependencies = sort(@dependencies);

    print OUT "###############################################################################\r\n";
    print OUT "\r\n";
    print OUT "Project: \"$project\"=$dsp_file - Package Owner=<4>\r\n";
    print OUT "\r\n";
    print OUT "Package=<5>\r\n";
    print OUT "{{{\r\n";
    print OUT "}}}\r\n";
    print OUT "\r\n";
    print OUT "Package=<4>\r\n";
    print OUT "{{{\r\n";
    foreach my $dependency (@dependencies) {
	print OUT "    Begin Project Dependency\r\n";
	print OUT "    Project_Dep_Name $dependency\r\n";
	print OUT "    End Project Dependency\r\n";
    }
    print OUT "}}}\r\n";
    print OUT "\r\n";
}

1073
sub _generate_dsw_footer($) {
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
    local *OUT = shift;

    print OUT "###############################################################################\r\n";
    print OUT "\r\n";
    print OUT "Global:\r\n";
    print OUT "\r\n";
    print OUT "Package=<5>\r\n";
    print OUT "{{{\r\n";
    print OUT "}}}\r\n";
    print OUT "\r\n";
    print OUT "Package=<3>\r\n";
    print OUT "{{{\r\n";
    print OUT "}}}\r\n";
    print OUT "\r\n";
    print OUT "###############################################################################\r\n";
    print OUT "\r\n";
}
1091

1092
if ($options->wine) {
1093 1094
    my $dsw_file = "wine.dsw";
    $output->progress("$dsw_file");
1095
    replace_file("$wine_dir/$dsw_file", \&_generate_wine_dsw);
1096
}
1097

1098
sub _generate_wine_dsw($) {
1099 1100
    local *OUT = shift;

1101
    _generate_dsw_header(\*OUT);
1102
    foreach my $module (sort(keys(%modules))) {
1103
	next if $module =~ /(?:winetest\.lib|wineruntests\.exe|_test\.exe)$/;
1104

1105 1106 1107 1108
	my $project = $modules{$module}{project};
	my $dsp_file = $modules{$module}{dsp_file};

	my @dependencies;
1109
	if($project eq "wine") {
1110
	    @dependencies = ();
1111 1112
	} elsif($project eq "winebuild") {
	    @dependencies = ("wine");
1113
	} elsif($project =~ /^(?:gdi32)_.+?$/) {
1114 1115
	    @dependencies = ();
	} else {
1116
	    @dependencies = ("wine", "include", "winebuild");
1117 1118
	}

1119 1120 1121 1122 1123 1124 1125 1126 1127
        if($project =~ /^gdi32$/) {
	    foreach my $dir (@gdi32_dirs) {
		my $dir2 = $dir;
		$dir2 =~ s%^.*?/([^/]+)$%$1%;

		my $module = "gdi32_$dir2";
		$module =~ s%/%_%g;
		push @dependencies, $module;
	    }
1128 1129
        }

1130 1131 1132
	_generate_dsw_project(\*OUT, $project, $dsp_file, \@dependencies);
    }
    _generate_dsw_footer(\*OUT);
1133

1134 1135 1136
    return 1;
}

1137
if ($options->winetest) {
1138 1139 1140
    my $dsw_file = "winetest.dsw";
    $output->progress("$dsw_file");
    replace_file("$wine_dir/$dsw_file", \&_generate_winetest_dsw);
1141
}
1142

1143
sub _generate_winetest_dsw($) {
1144 1145 1146 1147
    local *OUT = shift;

    _generate_dsw_header(\*OUT);

1148
    my @runtests_dependencies = ();
1149
    foreach my $module (sort(keys(%modules))) {
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
	next if $module !~ /(?:winetest\.lib|wineruntests\.exe|_test\.exe)$/;
	next if $module eq "wineruntests";

	my $project = $modules{$module}{project};

	push @runtests_dependencies, $project;
    }

    foreach my $module (sort(keys(%modules))) {
	next if $module !~ /(?:winetest\.lib|wineruntests\.exe|_test\.exe)$/;
1160 1161 1162 1163 1164 1165 1166

	my $project = $modules{$module}{project};
	my $dsp_file = $modules{$module}{dsp_file};

	my @dependencies;
	if($project =~ /^winetest$/) {
	    @dependencies = ();
1167 1168
	} elsif($project =~ /^wineruntests$/) {
	    @dependencies = @runtests_dependencies;
1169 1170
	} else {
	    @dependencies = ("winetest");
1171
	}
1172 1173

	_generate_dsw_project(\*OUT, $project, $dsp_file, \@dependencies);
1174 1175
    }

1176 1177
    _generate_dsw_footer(\*OUT);
}
1178

1179
if ($options->winetest) {
1180 1181 1182 1183 1184
    foreach my $module (sort(keys(%modules))) {
	next if $module !~ /_test\.exe$/;

	my $project = $modules{$module}{project};
	my $dsp_file = $modules{$module}{dsp_file};
1185
	my @tests = @{$modules{$module}{tests}};
1186 1187 1188 1189

	my $testlist_c = $dsp_file;
	$testlist_c =~ s%[^/]*\.dsp$%testlist.c%;

1190
	replace_file("$wine_dir/$testlist_c", \&_generate_testlist_c, \@tests);
1191
    }
1192
}
1193

1194
# ***** Keep in sync with tools/make_ctests *****
1195
sub _generate_testlist_c($$) {
1196 1197
    local *OUT = shift;

1198
    my @tests = @{(shift)};
1199 1200 1201

    print OUT "/* Automatically generated file; DO NOT EDIT!! */\n";
    print OUT "\n";
1202 1203
    print OUT "/* stdarg.h is needed for Winelib */\n";
    print OUT "#include <stdarg.h>\n";
1204 1205 1206 1207 1208
    print OUT "#include <stdio.h>\n";
    print OUT "#include <stdlib.h>\n";
    print OUT "#include \"windef.h\"\n";
    print OUT "#include \"winbase.h\"\n";
    print OUT "\n";
1209 1210 1211
    print OUT "#define STANDALONE\n";
    print OUT "#include \"wine/test.h\"\n";
    print OUT "\n";
1212 1213 1214 1215
    foreach my $test (@tests) {
	print OUT "extern void func_$test(void);\n";
    }
    print OUT "\n";
1216
    print OUT "const struct test winetest_testlist[] =\n";
1217 1218 1219 1220 1221 1222
    print OUT "{\n";
    foreach my $test (@tests) {
	print OUT "    { \"$test\", func_$test },\n";
    }
    print OUT "    { 0, 0 }\n";
    print OUT "};\n";
1223 1224
}

1225 1226 1227 1228
if ($options->winetest) {
    replace_file("$wine_dir/runtests.c", \&_generate_runtests_c);
}

1229
sub _generate_runtests_c($) {
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    local *OUT = shift;

    print OUT "/* Automatically generated file; DO NOT EDIT!! */\n";

    print OUT "\n";
    print OUT "#include <stdio.h>\n";
    print OUT "#include <stdlib.h>\n";
    print OUT "\n";

    print OUT "int main(int argc, char *argv[])\n";
    print OUT "{\n";
    print OUT "    char output_dir[] = __WINETEST_OUTPUT_DIR;\n";
    print OUT "    char command[4096];\n";
    print OUT "\n";
    foreach my $dsp_file (keys(%runtests)) {
	my @tests =  @{$runtests{$dsp_file}};

	my $project = $dsp_file;
	$project =~ s%^(.*?)/?([^/]+)\.dsp$%$2%;
	my $dir = $1;
	$dir =~ s%/%\\\\%g; 

	foreach my $test (@tests) {
	    print OUT "    sprintf(command, \"$dir\\\\%s\\\\$project.exe $test\", output_dir);\n";
	    print OUT "    system(command);\n";
	    print OUT "\n";
	}
    }
    print OUT "    return 0;\n";
    print OUT "}\n";
}

1262 1263 1264 1265
if ($options->winetest) {
    replace_file("$wine_dir/winetest.c", \&_generate_winetest_c);
}

1266
sub _generate_winetest_c($) {
1267 1268 1269 1270 1271
    local *OUT = shift;

    print OUT "/* Automatically generated file; DO NOT EDIT!! */\n\n";

    print OUT "/* Force the linker to generate a .lib file */\n";
1272
    print OUT "void __wine_dummy_lib_function(void)\n{\n}\n\n";
1273
}
1274

1275
if ($options->wine) {
1276 1277 1278 1279 1280
    my $config_h = "include/config.h";

    $output->progress("$config_h");

    replace_file("$wine_dir/$config_h", \&_generate_config_h);
1281
}
1282

1283
sub _generate_config_h($) {
1284
    local *OUT = shift;
1285
    my @defines;
1286 1287 1288 1289

    print OUT "#define __WINE_CONFIG_H\n";
    print OUT "\n";

1290
    my @headers = qw(direct.h float.h memory.h io.h stdlib.h string.h process.h sys/stat.h sys/types.h);
1291 1292
    foreach my $header (@headers) {
	$header =~ y/\.\//__/;
1293
	push @defines, "HAVE_\U$header\E 1";
1294 1295 1296
    }

    my @functions = qw(
1297 1298 1299
        _pclose _popen _snprintf _spawnvp _stricmp _strnicmp _strdup
        _strtoi64 _strtoui64 _vsnprintf
        chsize memmove strdup spawnvp strerror vsnprintf
1300 1301
    );
    foreach my $function (@functions) {
1302
	push @defines, "HAVE_\U$function\E 1";
1303 1304
    }

1305 1306 1307 1308 1309 1310 1311
    my @types = qw(
        long_long off_t size_t
    );
    foreach my $type (@types) {
	push @defines, "HAVE_\U$type\E 1";
    }

1312 1313
    foreach my $define (sort(@defines)) {
	print OUT "#define $define\n";
1314 1315 1316
	print OUT "\n";
    }

1317 1318
    print OUT "/* Define to the address where bug reports for this package should be sent. */\n";
    print OUT "#define PACKAGE_BUGREPORT \"\"\n";
1319
    print OUT "\n";
1320 1321 1322

    print OUT "/* Define to the full name of this package. */\n";
    print OUT "#define PACKAGE_NAME \"Wine\"\n";
1323
    print OUT "\n";
1324 1325 1326

    print OUT "/* Define to the full name and version of this package. */\n";
    print OUT "#define PACKAGE_STRING \"Wine YYYYMMDD\"\n";
1327
    print OUT "\n";
1328 1329 1330

    print OUT "/* Define to the one symbol short name of this package. */\n";
    print OUT "#define PACKAGE_TARNAME \"wine\"\n";
1331
    print OUT "\n";
1332 1333 1334

    print OUT "/* Define to the version of this package. */\n";
    print OUT "#define PACKAGE_VERSION \"YYYYMMDD\"\n";
1335
    print OUT "\n";
1336

1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
    print OUT "#define X_DISPLAY_MISSING 1\n";
    print OUT "\n";

    print OUT "/* Define to a macro to generate an assembly function directive */\n";
    print OUT "#define __ASM_FUNC(name) \"\"\n";
    print OUT "\n";

    print OUT "/* Define to a macro to generate an assembly name from a C symbol */\n";
    print OUT "#define __ASM_NAME(name) name\n";
    print OUT "\n";

1348 1349
    close(OUT);
}