b17800184c63f27eafbfae4dbaf0cf19c6e06d90
   1package Generators::Vcproj;
   2require Exporter;
   3
   4use strict;
   5use vars qw($VERSION);
   6use Digest::SHA qw(sha256_hex);
   7
   8our $VERSION = '1.00';
   9our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
  10@ISA = qw(Exporter);
  11
  12BEGIN {
  13    push @EXPORT_OK, qw(generate);
  14}
  15
  16sub generate_guid ($) {
  17    my $hex = sha256_hex($_[0]);
  18    $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
  19    $hex =~ tr/a-z/A-Z/;
  20    return $hex;
  21}
  22
  23sub generate {
  24    my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
  25    my @libs = @{$build_structure{"LIBS"}};
  26    foreach (@libs) {
  27        createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
  28    }
  29
  30    my @apps = @{$build_structure{"APPS"}};
  31    foreach (@apps) {
  32        createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
  33    }
  34
  35    createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
  36    return 0;
  37}
  38
  39sub createLibProject {
  40    my ($libname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
  41    print "Generate $libname vcproj lib project\n";
  42    $rel_dir = "..\\$rel_dir";
  43    $rel_dir =~ s/\//\\/g;
  44
  45    my $target = $libname;
  46    $target =~ s/\//_/g;
  47    $target =~ s/\.a//;
  48
  49    my $uuid = generate_guid($libname);
  50    $$build_structure{"LIBS_${target}_GUID"} = $uuid;
  51
  52    my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
  53    my @sources;
  54    foreach (@srcs) {
  55        $_ =~ s/\//\\/g;
  56        push(@sources, $_);
  57    }
  58    my $defines = join(",", sort(@{$$build_structure{"LIBS_${libname}_DEFINES"}}));
  59    my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
  60    my $cflags  = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
  61    $cflags =~ s/\"/"/g;
  62
  63    my $cflags_debug = $cflags;
  64    $cflags_debug =~ s/-MT/-MTd/;
  65    $cflags_debug =~ s/-O.//;
  66
  67    my $cflags_release = $cflags;
  68    $cflags_release =~ s/-MTd/-MT/;
  69
  70    my @tmp  = @{$$build_structure{"LIBS_${libname}_LFLAGS"}};
  71    my @tmp2 = ();
  72    foreach (@tmp) {
  73        if (/^-LTCG/) {
  74        } elsif (/^-L/) {
  75            $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
  76        }
  77        push(@tmp2, $_);
  78    }
  79    my $lflags = join(" ", sort(@tmp));
  80
  81    $defines =~ s/-D//g;
  82    $defines =~ s/\"/\\"/g;
  83    $defines =~ s/\'//g;
  84    $includes =~ s/-I//g;
  85    mkdir "$target" || die "Could not create the directory $target for lib project!\n";
  86    open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
  87    binmode F, ":crlf";
  88    print F << "EOM";
  89<?xml version="1.0" encoding = "Windows-1252"?>
  90<VisualStudioProject
  91        ProjectType="Visual C++"
  92        Version="9,00"
  93        Name="$target"
  94        ProjectGUID="$uuid">
  95        <Platforms>
  96                <Platform
  97                        Name="Win32"/>
  98        </Platforms>
  99        <ToolFiles>
 100        </ToolFiles>
 101        <Configurations>
 102                <Configuration
 103                        Name="Debug|Win32"
 104                        OutputDirectory="$rel_dir"
 105                        ConfigurationType="4"
 106                        CharacterSet="0"
 107                        IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
 108                        >
 109                        <Tool
 110                                Name="VCPreBuildEventTool"
 111                        />
 112                        <Tool
 113                                Name="VCCustomBuildTool"
 114                        />
 115                        <Tool
 116                                Name="VCXMLDataGeneratorTool"
 117                        />
 118                        <Tool
 119                                Name="VCMIDLTool"
 120                        />
 121                        <Tool
 122                                Name="VCCLCompilerTool"
 123                                AdditionalOptions="$cflags_debug"
 124                                Optimization="0"
 125                                InlineFunctionExpansion="1"
 126                                AdditionalIncludeDirectories="$includes"
 127                                PreprocessorDefinitions="WIN32,_DEBUG,$defines"
 128                                MinimalRebuild="true"
 129                                RuntimeLibrary="1"
 130                                UsePrecompiledHeader="0"
 131                                ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
 132                                WarningLevel="3"
 133                                DebugInformationFormat="3"
 134                        />
 135                        <Tool
 136                                Name="VCManagedResourceCompilerTool"
 137                        />
 138                        <Tool
 139                                Name="VCResourceCompilerTool"
 140                        />
 141                        <Tool
 142                                Name="VCPreLinkEventTool"
 143                        />
 144                        <Tool
 145                                Name="VCLibrarianTool"
 146                                SuppressStartupBanner="true"
 147                        />
 148                        <Tool
 149                                Name="VCALinkTool"
 150                        />
 151                        <Tool
 152                                Name="VCXDCMakeTool"
 153                        />
 154                        <Tool
 155                                Name="VCBscMakeTool"
 156                        />
 157                        <Tool
 158                                Name="VCFxCopTool"
 159                        />
 160                        <Tool
 161                                Name="VCPostBuildEventTool"
 162                        />
 163                </Configuration>
 164                <Configuration
 165                        Name="Release|Win32"
 166                        OutputDirectory="$rel_dir"
 167                        ConfigurationType="4"
 168                        CharacterSet="0"
 169                        WholeProgramOptimization="1"
 170                        IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
 171                        >
 172                        <Tool
 173                                Name="VCPreBuildEventTool"
 174                        />
 175                        <Tool
 176                                Name="VCCustomBuildTool"
 177                        />
 178                        <Tool
 179                                Name="VCXMLDataGeneratorTool"
 180                        />
 181                        <Tool
 182                                Name="VCMIDLTool"
 183                        />
 184                        <Tool
 185                                Name="VCCLCompilerTool"
 186                                AdditionalOptions="$cflags_release"
 187                                Optimization="2"
 188                                InlineFunctionExpansion="1"
 189                                EnableIntrinsicFunctions="true"
 190                                AdditionalIncludeDirectories="$includes"
 191                                PreprocessorDefinitions="WIN32,NDEBUG,$defines"
 192                                RuntimeLibrary="0"
 193                                EnableFunctionLevelLinking="true"
 194                                UsePrecompiledHeader="0"
 195                                ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
 196                                WarningLevel="3"
 197                                DebugInformationFormat="3"
 198                        />
 199                        <Tool
 200                                Name="VCManagedResourceCompilerTool"
 201                        />
 202                        <Tool
 203                                Name="VCResourceCompilerTool"
 204                        />
 205                        <Tool
 206                                Name="VCPreLinkEventTool"
 207                        />
 208                        <Tool
 209                                Name="VCLibrarianTool"
 210                                SuppressStartupBanner="true"
 211                        />
 212                        <Tool
 213                                Name="VCALinkTool"
 214                        />
 215                        <Tool
 216                                Name="VCXDCMakeTool"
 217                        />
 218                        <Tool
 219                                Name="VCBscMakeTool"
 220                        />
 221                        <Tool
 222                                Name="VCFxCopTool"
 223                        />
 224                        <Tool
 225                                Name="VCPostBuildEventTool"
 226                        />
 227                </Configuration>
 228        </Configurations>
 229        <Files>
 230                <Filter
 231                        Name="Source Files"
 232                        Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
 233                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
 234EOM
 235    foreach(@sources) {
 236        print F << "EOM";
 237                        <File
 238                                RelativePath="$_"/>
 239EOM
 240    }
 241    print F << "EOM";
 242                </Filter>
 243        </Files>
 244        <Globals>
 245        </Globals>
 246</VisualStudioProject>
 247EOM
 248    close F;
 249}
 250
 251sub createAppProject {
 252    my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
 253    print "Generate $appname vcproj app project\n";
 254    $rel_dir = "..\\$rel_dir";
 255    $rel_dir =~ s/\//\\/g;
 256
 257    my $target = $appname;
 258    $target =~ s/\//_/g;
 259    $target =~ s/\.exe//;
 260
 261    my $uuid = generate_guid($appname);
 262    $$build_structure{"APPS_${target}_GUID"} = $uuid;
 263
 264    my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
 265    my @sources;
 266    foreach (@srcs) {
 267        $_ =~ s/\//\\/g;
 268        push(@sources, $_);
 269    }
 270    my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
 271    my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
 272    my $cflags  = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
 273    $cflags =~ s/\"/&quot;/g;
 274
 275    my $cflags_debug = $cflags;
 276    $cflags_debug =~ s/-MT/-MTd/;
 277    $cflags_debug =~ s/-O.//;
 278
 279    my $cflags_release = $cflags;
 280    $cflags_release =~ s/-MTd/-MT/;
 281
 282    my $libs;
 283    foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
 284        $_ =~ s/\//_/g;
 285        $libs .= " $_";
 286    }
 287    my @tmp  = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
 288    my @tmp2 = ();
 289    foreach (@tmp) {
 290        if (/^-LTCG/) {
 291        } elsif (/^-L/) {
 292            $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
 293        }
 294        push(@tmp2, $_);
 295    }
 296    my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
 297
 298    $defines =~ s/-D//g;
 299    $defines =~ s/\"/\\&quot;/g;
 300    $defines =~ s/\'//g;
 301    $defines =~ s/\\\\/\\/g;
 302    $includes =~ s/-I//g;
 303    mkdir "$target" || die "Could not create the directory $target for lib project!\n";
 304    open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
 305    binmode F, ":crlf";
 306    print F << "EOM";
 307<?xml version="1.0" encoding = "Windows-1252"?>
 308<VisualStudioProject
 309        ProjectType="Visual C++"
 310        Version="9,00"
 311        Name="$target"
 312        ProjectGUID="$uuid">
 313        <Platforms>
 314                <Platform
 315                        Name="Win32"/>
 316        </Platforms>
 317        <ToolFiles>
 318        </ToolFiles>
 319        <Configurations>
 320                <Configuration
 321                        Name="Debug|Win32"
 322                        OutputDirectory="$rel_dir"
 323                        ConfigurationType="1"
 324                        CharacterSet="0"
 325                        IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
 326                        >
 327                        <Tool
 328                                Name="VCPreBuildEventTool"
 329                        />
 330                        <Tool
 331                                Name="VCCustomBuildTool"
 332                        />
 333                        <Tool
 334                                Name="VCXMLDataGeneratorTool"
 335                        />
 336                        <Tool
 337                                Name="VCMIDLTool"
 338                        />
 339                        <Tool
 340                                Name="VCCLCompilerTool"
 341                                AdditionalOptions="$cflags_debug"
 342                                Optimization="0"
 343                                InlineFunctionExpansion="1"
 344                                AdditionalIncludeDirectories="$includes"
 345                                PreprocessorDefinitions="WIN32,_DEBUG,$defines"
 346                                MinimalRebuild="true"
 347                                RuntimeLibrary="1"
 348                                UsePrecompiledHeader="0"
 349                                ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
 350                                WarningLevel="3"
 351                                DebugInformationFormat="3"
 352                        />
 353                        <Tool
 354                                Name="VCManagedResourceCompilerTool"
 355                        />
 356                        <Tool
 357                                Name="VCResourceCompilerTool"
 358                        />
 359                        <Tool
 360                                Name="VCPreLinkEventTool"
 361                        />
 362                        <Tool
 363                                Name="VCLinkerTool"
 364                                AdditionalDependencies="$libs"
 365                                AdditionalOptions="$lflags"
 366                                LinkIncremental="2"
 367                                GenerateDebugInformation="true"
 368                                SubSystem="1"
 369                                TargetMachine="1"
 370                        />
 371                        <Tool
 372                                Name="VCALinkTool"
 373                        />
 374                        <Tool
 375                                Name="VCXDCMakeTool"
 376                        />
 377                        <Tool
 378                                Name="VCBscMakeTool"
 379                        />
 380                        <Tool
 381                                Name="VCFxCopTool"
 382                        />
 383                        <Tool
 384                                Name="VCPostBuildEventTool"
 385                        />
 386                </Configuration>
 387                <Configuration
 388                        Name="Release|Win32"
 389                        OutputDirectory="$rel_dir"
 390                        ConfigurationType="1"
 391                        CharacterSet="0"
 392                        WholeProgramOptimization="1"
 393                        IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
 394                        >
 395                        <Tool
 396                                Name="VCPreBuildEventTool"
 397                        />
 398                        <Tool
 399                                Name="VCCustomBuildTool"
 400                        />
 401                        <Tool
 402                                Name="VCXMLDataGeneratorTool"
 403                        />
 404                        <Tool
 405                                Name="VCMIDLTool"
 406                        />
 407                        <Tool
 408                                Name="VCCLCompilerTool"
 409                                AdditionalOptions="$cflags_release"
 410                                Optimization="2"
 411                                InlineFunctionExpansion="1"
 412                                EnableIntrinsicFunctions="true"
 413                                AdditionalIncludeDirectories="$includes"
 414                                PreprocessorDefinitions="WIN32,NDEBUG,$defines"
 415                                RuntimeLibrary="0"
 416                                EnableFunctionLevelLinking="true"
 417                                UsePrecompiledHeader="0"
 418                                ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
 419                                WarningLevel="3"
 420                                DebugInformationFormat="3"
 421                        />
 422                        <Tool
 423                                Name="VCManagedResourceCompilerTool"
 424                        />
 425                        <Tool
 426                                Name="VCResourceCompilerTool"
 427                        />
 428                        <Tool
 429                                Name="VCPreLinkEventTool"
 430                        />
 431                        <Tool
 432                                Name="VCLinkerTool"
 433                                AdditionalDependencies="$libs"
 434                                AdditionalOptions="$lflags"
 435                                LinkIncremental="1"
 436                                GenerateDebugInformation="true"
 437                                SubSystem="1"
 438                                TargetMachine="1"
 439                                OptimizeReferences="2"
 440                                EnableCOMDATFolding="2"
 441                        />
 442                        <Tool
 443                                Name="VCALinkTool"
 444                        />
 445                        <Tool
 446                                Name="VCXDCMakeTool"
 447                        />
 448                        <Tool
 449                                Name="VCBscMakeTool"
 450                        />
 451                        <Tool
 452                                Name="VCFxCopTool"
 453                        />
 454                        <Tool
 455                                Name="VCPostBuildEventTool"
 456                        />
 457                </Configuration>
 458        </Configurations>
 459        <Files>
 460                <Filter
 461                        Name="Source Files"
 462                        Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
 463                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
 464EOM
 465    foreach(@sources) {
 466        print F << "EOM";
 467                        <File
 468                                RelativePath="$_"/>
 469EOM
 470    }
 471    print F << "EOM";
 472                </Filter>
 473        </Files>
 474        <Globals>
 475        </Globals>
 476</VisualStudioProject>
 477EOM
 478    close F;
 479}
 480
 481sub createGlueProject {
 482    my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
 483    print "Generate solutions file\n";
 484    $rel_dir = "..\\$rel_dir";
 485    $rel_dir =~ s/\//\\/g;
 486    my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\n";
 487    my $SLN_PRE  = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
 488    my $SLN_POST = "\nEndProject\n";
 489
 490    my @libs = @{$build_structure{"LIBS"}};
 491    my @tmp;
 492    foreach (@libs) {
 493        $_ =~ s/\//_/g;
 494        $_ =~ s/\.a//;
 495        push(@tmp, $_);
 496    }
 497    @libs = @tmp;
 498
 499    my @apps = @{$build_structure{"APPS"}};
 500    @tmp = ();
 501    foreach (@apps) {
 502        $_ =~ s/\//_/g;
 503        $_ =~ s/\.exe//;
 504        if ($_ eq "git" ) {
 505            unshift(@tmp, $_);
 506        } else {
 507            push(@tmp, $_);
 508        }
 509    }
 510    @apps = @tmp;
 511
 512    open F, ">git.sln" || die "Could not open git.sln for writing!\n";
 513    binmode F, ":crlf";
 514    print F "$SLN_HEAD";
 515
 516    my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
 517    my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
 518    foreach (@apps) {
 519        my $appname = $_;
 520        my $uuid = $build_structure{"APPS_${appname}_GUID"};
 521        print F "$SLN_PRE";
 522        print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\"\n";
 523        print F "       ProjectSection(ProjectDependencies) = postProject\n";
 524        print F "               ${uuid_libgit} = ${uuid_libgit}\n";
 525        print F "               ${uuid_xdiff_lib} = ${uuid_xdiff_lib}\n";
 526        print F "       EndProjectSection";
 527        print F "$SLN_POST";
 528    }
 529    foreach (@libs) {
 530        my $libname = $_;
 531        my $uuid = $build_structure{"LIBS_${libname}_GUID"};
 532        print F "$SLN_PRE";
 533        print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
 534        print F "$SLN_POST";
 535    }
 536
 537    print F << "EOM";
 538Global
 539        GlobalSection(SolutionConfigurationPlatforms) = preSolution
 540                Debug|Win32 = Debug|Win32
 541                Release|Win32 = Release|Win32
 542        EndGlobalSection
 543EOM
 544    print F << "EOM";
 545        GlobalSection(ProjectConfigurationPlatforms) = postSolution
 546EOM
 547    foreach (@apps) {
 548        my $appname = $_;
 549        my $uuid = $build_structure{"APPS_${appname}_GUID"};
 550        print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
 551        print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
 552        print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
 553        print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
 554    }
 555    foreach (@libs) {
 556        my $libname = $_;
 557        my $uuid = $build_structure{"LIBS_${libname}_GUID"};
 558        print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
 559        print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
 560        print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
 561        print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
 562    }
 563
 564    print F << "EOM";
 565        EndGlobalSection
 566EndGlobal
 567EOM
 568    close F;
 569}
 570
 5711;