gen_msvs_proj.sh 16.4 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1 2
#!/bin/bash
##
3
##  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
4
##
5
##  Use of this source code is governed by a BSD-style license
6 7
##  that can be found in the LICENSE file in the root of the source
##  tree. An additional intellectual property rights grant can be found
8
##  in the file PATENTS.  All contributing project authors may
9
##  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
10 11 12 13
##

self=$0
self_basename=${self##*/}
14
self_dirname=$(dirname "$0")
15 16

. "$self_dirname/msvs_common.sh"|| exit 127
John Koleszar's avatar
John Koleszar committed
17 18 19 20 21 22 23 24 25 26 27 28

show_help() {
    cat <<EOF
Usage: ${self_basename} --name=projname [options] file1 [file2 ...]

This script generates a Visual Studio project file from a list of source
code files.

Options:
    --help                      Print this message
    --exe                       Generate a project for building an Application
    --lib                       Generate a project for creating a static library
Jim Bankoski's avatar
Jim Bankoski committed
29
    --dll                       Generate a project for creating a dll
John Koleszar's avatar
John Koleszar committed
30 31 32 33 34 35
    --static-crt                Use the static C runtime (/MT)
    --target=isa-os-cc          Target specifier (required)
    --out=filename              Write output to a file [stdout]
    --name=project_name         Name of the project (required)
    --proj-guid=GUID            GUID to use for the project
    --module-def=filename       File containing export definitions (for DLLs)
Johann's avatar
Johann committed
36
    --ver=version               Version (7,8,9) of visual studio to generate for
Johann's avatar
Johann committed
37
    --src-path-bare=dir         Path to root of source tree
John Koleszar's avatar
John Koleszar committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    -Ipath/to/include           Additional include directories
    -DFLAG[=value]              Preprocessor macros to define
    -Lpath/to/lib               Additional library search paths
    -llibname                   Library to link against
EOF
    exit 1
}

generate_filter() {
    local var=$1
    local name=$2
    local pats=$3
    local file_list_sz
    local i
    local f
    local saveIFS="$IFS"
    local pack
    echo "generating filter '$name' from ${#file_list[@]} files" >&2
    IFS=*

    open_tag Filter \
        Name=$name \
        Filter=$pats \
Johann's avatar
Johann committed
61
        UniqueIdentifier=`generate_uuid` \
John Koleszar's avatar
John Koleszar committed
62 63 64 65 66 67 68 69

    file_list_sz=${#file_list[@]}
    for i in ${!file_list[@]}; do
        f=${file_list[i]}
        for pat in ${pats//;/$IFS}; do
            if [ "${f##*.}" == "$pat" ]; then
                unset file_list[i]

70 71 72
                objf=$(echo ${f%.*}.obj \
                       | sed -e "s,$src_path_bare,," \
                             -e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
73
                open_tag File RelativePath="$f"
74

John Koleszar's avatar
John Koleszar committed
75
                if [ "$pat" == "asm" ] && $asm_use_custom_step; then
76 77 78 79
                    # Avoid object file name collisions, i.e. vpx_config.c and
                    # vpx_config.asm produce the same object file without
                    # this additional suffix.
                    objf=${objf%.obj}_asm.obj
John Koleszar's avatar
John Koleszar committed
80 81
                    for plat in "${platforms[@]}"; do
                        for cfg in Debug Release; do
Johann's avatar
Johann committed
82 83 84
                            open_tag FileConfiguration \
                                Name="${cfg}|${plat}" \

John Koleszar's avatar
John Koleszar committed
85 86 87
                            tag Tool \
                                Name="VCCustomBuildTool" \
                                Description="Assembling \$(InputFileName)" \
88 89
                                CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)\\$objf" \
                                Outputs="\$(IntDir)\\$objf" \
Johann's avatar
Johann committed
90

John Koleszar's avatar
John Koleszar committed
91 92 93 94
                            close_tag FileConfiguration
                        done
                    done
                fi
95 96
                if [ "$pat" == "c" ] || \
                   [ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
97 98 99 100
                    for plat in "${platforms[@]}"; do
                        for cfg in Debug Release; do
                            open_tag FileConfiguration \
                                Name="${cfg}|${plat}" \
John Koleszar's avatar
John Koleszar committed
101

102 103
                            tag Tool \
                                Name="VCCLCompilerTool" \
104
                                ObjectFile="\$(IntDir)\\$objf" \
105 106 107 108 109

                            close_tag FileConfiguration
                        done
                    done
                fi
Johann's avatar
Johann committed
110
                close_tag File
John Koleszar's avatar
John Koleszar committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

                break
            fi
        done
    done

    close_tag Filter
    IFS="$saveIFS"
}

# Process command line
unset target
for opt in "$@"; do
    optval="${opt#*=}"
    case "$opt" in
Johann's avatar
Johann committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139
        --help|-h) show_help
        ;;
        --target=*) target="${optval}"
        ;;
        --out=*) outfile="$optval"
        ;;
        --name=*) name="${optval}"
        ;;
        --proj-guid=*) guid="${optval}"
        ;;
        --module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
        ;;
        --exe) proj_kind="exe"
        ;;
Jim Bankoski's avatar
Jim Bankoski committed
140 141
        --dll) proj_kind="dll"
        ;;
Johann's avatar
Johann committed
142 143
        --lib) proj_kind="lib"
        ;;
144 145 146
        --src-path-bare=*)
            src_path_bare=$(fix_path "$optval")
            src_path_bare=${src_path_bare%/}
Johann's avatar
Johann committed
147
        ;;
Johann's avatar
Johann committed
148 149 150 151 152 153 154 155 156 157 158 159
        --static-crt) use_static_runtime=true
        ;;
        --ver=*)
            vs_ver="$optval"
            case "$optval" in
                [789])
                ;;
                *) die Unrecognized Visual Studio Version in $opt
                ;;
            esac
        ;;
        -I*)
160 161
            opt=${opt##-I}
            opt=$(fix_path "$opt")
162
            opt="${opt%/}"
163
            incs="${incs}${incs:+;}&quot;${opt}&quot;"
164
            yasmincs="${yasmincs} -I&quot;${opt}&quot;"
Johann's avatar
Johann committed
165 166 167 168 169 170 171 172
        ;;
        -D*) defines="${defines}${defines:+;}${opt##-D}"
        ;;
        -L*) # fudge . to $(OutDir)
            if [ "${opt##-L}" == "." ]; then
                libdirs="${libdirs}${libdirs:+;}&quot;\$(OutDir)&quot;"
            else
                 # Also try directories for this platform/configuration
173 174 175 176 177
                 opt=${opt##-L}
                 opt=$(fix_path "$opt")
                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}&quot;"
                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)/\$(ConfigurationName)&quot;"
                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)&quot;"
Johann's avatar
Johann committed
178 179 180 181 182 183 184
            fi
        ;;
        -l*) libs="${libs}${libs:+ }${opt##-l}.lib"
        ;;
        -*) die_unknown $opt
        ;;
        *)
185 186
            # The paths in file_list are fixed outside of the loop.
            file_list[${#file_list[@]}]="$opt"
Johann's avatar
Johann committed
187 188 189 190 191
            case "$opt" in
                 *.asm) uses_asm=true
                 ;;
            esac
        ;;
John Koleszar's avatar
John Koleszar committed
192 193
    esac
done
194 195 196 197

# Make one call to fix_path for file_list to improve performance.
fix_file_list

John Koleszar's avatar
John Koleszar committed
198 199 200 201 202 203 204
outfile=${outfile:-/dev/stdout}
guid=${guid:-`generate_uuid`}
asm_use_custom_step=false
uses_asm=${uses_asm:-false}
case "${vs_ver:-8}" in
    7) vs_ver_id="7.10"
       asm_use_custom_step=$uses_asm
205
       warn_64bit='Detect64BitPortabilityProblems=true'
John Koleszar's avatar
John Koleszar committed
206 207
    ;;
    8) vs_ver_id="8.00"
208
       asm_use_custom_step=$uses_asm
209
       warn_64bit='Detect64BitPortabilityProblems=true'
John Koleszar's avatar
John Koleszar committed
210
    ;;
Tom Finegan's avatar
Tom Finegan committed
211
    9) vs_ver_id="9.00"
212
       asm_use_custom_step=$uses_asm
213
       warn_64bit='Detect64BitPortabilityProblems=false'
Tom Finegan's avatar
Tom Finegan committed
214
    ;;
John Koleszar's avatar
John Koleszar committed
215 216 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
esac

[ -n "$name" ] || die "Project name (--name) must be specified!"
[ -n "$target" ] || die "Target (--target) must be specified!"

if ${use_static_runtime:-false}; then
    release_runtime=0
    debug_runtime=1
    lib_sfx=mt
else
    release_runtime=2
    debug_runtime=3
    lib_sfx=md
fi

# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
# debug exe, so this may need to be refactored later.
for lib in ${libs}; do
    if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
        lib=${lib%.lib}d.lib
    fi
    debug_libs="${debug_libs}${debug_libs:+ }${lib}"
done


# List Keyword for this target
case "$target" in
Johann's avatar
Johann committed
243
    x86*) keyword="ManagedCProj"
John Koleszar's avatar
John Koleszar committed
244 245 246 247 248 249 250 251
    ;;
    *) die "Unsupported target $target!"
esac

# List of all platforms supported for this target
case "$target" in
    x86_64*)
        platforms[0]="x64"
252 253
        asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
        asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
John Koleszar's avatar
John Koleszar committed
254 255 256
    ;;
    x86*)
        platforms[0]="Win32"
257 258
        asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
        asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
John Koleszar's avatar
John Koleszar committed
259 260
    ;;
    *) die "Unsupported target $target!"
Johann's avatar
Johann committed
261
    ;;
John Koleszar's avatar
John Koleszar committed
262 263 264 265
esac

generate_vcproj() {
    case "$proj_kind" in
Johann's avatar
Johann committed
266 267
        exe) vs_ConfigurationType=1
        ;;
Jim Bankoski's avatar
Jim Bankoski committed
268 269
        dll) vs_ConfigurationType=2
        ;;
Johann's avatar
Johann committed
270 271
        *)   vs_ConfigurationType=4
        ;;
John Koleszar's avatar
John Koleszar committed
272 273 274
    esac

    echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
Johann's avatar
Johann committed
275 276 277 278 279 280 281 282 283
    open_tag VisualStudioProject \
        ProjectType="Visual C++" \
        Version="${vs_ver_id}" \
        Name="${name}" \
        ProjectGUID="{${guid}}" \
        RootNamespace="${name}" \
        Keyword="${keyword}" \

    open_tag Platforms
John Koleszar's avatar
John Koleszar committed
284
    for plat in "${platforms[@]}"; do
Johann's avatar
Johann committed
285
        tag Platform Name="$plat"
John Koleszar's avatar
John Koleszar committed
286 287 288
    done
    close_tag Platforms

Johann's avatar
Johann committed
289
    open_tag Configurations
John Koleszar's avatar
John Koleszar committed
290 291
    for plat in "${platforms[@]}"; do
        plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
Johann's avatar
Johann committed
292 293 294 295 296 297
        open_tag Configuration \
            Name="Debug|$plat" \
            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
            ConfigurationType="$vs_ConfigurationType" \
            CharacterSet="1" \
John Koleszar's avatar
John Koleszar committed
298 299

        case "$target" in
Johann's avatar
Johann committed
300 301
            x86*)
                case "$name" in
Johann's avatar
Johann committed
302 303 304 305 306 307 308 309 310
                    vpx)
                        tag Tool \
                            Name="VCCLCompilerTool" \
                            Optimization="0" \
                            AdditionalIncludeDirectories="$incs" \
                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
                            RuntimeLibrary="$debug_runtime" \
                            UsePrecompiledHeader="0" \
                            WarningLevel="3" \
311
                            DebugInformationFormat="2" \
312
                            $warn_64bit \
Johann's avatar
Johann committed
313

314
                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
Johann's avatar
Johann committed
315
                    ;;
Johann's avatar
Johann committed
316 317 318 319 320 321 322 323 324
                    *)
                        tag Tool \
                            Name="VCCLCompilerTool" \
                            Optimization="0" \
                            AdditionalIncludeDirectories="$incs" \
                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
                            RuntimeLibrary="$debug_runtime" \
                            UsePrecompiledHeader="0" \
                            WarningLevel="3" \
325
                            DebugInformationFormat="2" \
326
                            $warn_64bit \
Johann's avatar
Johann committed
327

328
                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
Johann's avatar
Johann committed
329 330
                    ;;
                esac
John Koleszar's avatar
John Koleszar committed
331 332 333 334 335 336
            ;;
        esac

        case "$proj_kind" in
            exe)
                case "$target" in
Johann's avatar
Johann committed
337 338 339 340 341 342 343 344 345 346 347
                    x86*)
                        case "$name" in
                            *)
                                tag Tool \
                                    Name="VCLinkerTool" \
                                    AdditionalDependencies="$debug_libs \$(NoInherit)" \
                                    AdditionalLibraryDirectories="$libdirs" \
                                    GenerateDebugInformation="true" \
                                    ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
                            ;;
                        esac
John Koleszar's avatar
John Koleszar committed
348 349 350 351 352
                    ;;
                 esac
            ;;
            lib)
                case "$target" in
Johann's avatar
Johann committed
353 354 355 356 357 358
                    x86*)
                        tag Tool \
                            Name="VCLibrarianTool" \
                            OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \

                    ;;
John Koleszar's avatar
John Koleszar committed
359 360
                esac
            ;;
Johann's avatar
Johann committed
361 362 363 364 365 366 367 368 369 370 371
            dll)
                tag Tool \
                    Name="VCLinkerTool" \
                    AdditionalDependencies="\$(NoInherit)" \
                    LinkIncremental="2" \
                    GenerateDebugInformation="true" \
                    AssemblyDebug="1" \
                    TargetMachine="1" \
                    $link_opts \

            ;;
John Koleszar's avatar
John Koleszar committed
372 373 374 375
        esac

        close_tag Configuration

Johann's avatar
Johann committed
376 377 378 379 380 381 382
        open_tag Configuration \
            Name="Release|$plat" \
            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
            ConfigurationType="$vs_ConfigurationType" \
            CharacterSet="1" \
            WholeProgramOptimization="0" \
John Koleszar's avatar
John Koleszar committed
383

Johann's avatar
Johann committed
384 385 386
        case "$target" in
            x86*)
                case "$name" in
Johann's avatar
Johann committed
387 388 389
                    vpx)
                        tag Tool \
                            Name="VCCLCompilerTool" \
390 391
                            Optimization="2" \
                            FavorSizeorSpeed="1" \
Johann's avatar
Johann committed
392 393 394 395 396 397
                            AdditionalIncludeDirectories="$incs" \
                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
                            RuntimeLibrary="$release_runtime" \
                            UsePrecompiledHeader="0" \
                            WarningLevel="3" \
                            DebugInformationFormat="0" \
398
                            $warn_64bit \
Johann's avatar
Johann committed
399 400 401

                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
                    ;;
Johann's avatar
Johann committed
402 403 404 405
                    *)
                        tag Tool \
                            Name="VCCLCompilerTool" \
                            AdditionalIncludeDirectories="$incs" \
406 407
                            Optimization="2" \
                            FavorSizeorSpeed="1" \
Johann's avatar
Johann committed
408 409 410 411 412
                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
                            RuntimeLibrary="$release_runtime" \
                            UsePrecompiledHeader="0" \
                            WarningLevel="3" \
                            DebugInformationFormat="0" \
413
                            $warn_64bit \
Johann's avatar
Johann committed
414 415 416

                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
                    ;;
John Koleszar's avatar
John Koleszar committed
417
                esac
Johann's avatar
Johann committed
418 419
            ;;
        esac
John Koleszar's avatar
John Koleszar committed
420 421 422 423

        case "$proj_kind" in
            exe)
                case "$target" in
Johann's avatar
Johann committed
424 425 426 427 428 429 430 431 432 433
                    x86*)
                        case "$name" in
                            *)
                                tag Tool \
                                    Name="VCLinkerTool" \
                                    AdditionalDependencies="$libs \$(NoInherit)" \
                                    AdditionalLibraryDirectories="$libdirs" \

                            ;;
                        esac
John Koleszar's avatar
John Koleszar committed
434 435 436
                    ;;
                 esac
            ;;
Johann's avatar
Johann committed
437
            lib)
John Koleszar's avatar
John Koleszar committed
438
                case "$target" in
Johann's avatar
Johann committed
439 440 441 442 443 444
                    x86*)
                        tag Tool \
                            Name="VCLibrarianTool" \
                            OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \

                    ;;
John Koleszar's avatar
John Koleszar committed
445
                esac
Johann's avatar
Johann committed
446 447 448 449 450 451 452 453 454 455 456
            ;;
            dll) # note differences to debug version: LinkIncremental, AssemblyDebug
                tag Tool \
                    Name="VCLinkerTool" \
                    AdditionalDependencies="\$(NoInherit)" \
                    LinkIncremental="1" \
                    GenerateDebugInformation="true" \
                    TargetMachine="1" \
                    $link_opts \

            ;;
John Koleszar's avatar
John Koleszar committed
457 458 459 460 461 462
        esac

        close_tag Configuration
    done
    close_tag Configurations

Johann's avatar
Johann committed
463
    open_tag Files
464
    generate_filter srcs   "Source Files"   "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
Johann's avatar
Johann committed
465
    generate_filter hdrs   "Header Files"   "h;hm;inl;inc;xsd"
John Koleszar's avatar
John Koleszar committed
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
    generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
    generate_filter resrcs "Build Files"    "mk"
    close_tag Files

    tag       Globals
    close_tag VisualStudioProject

    # This must be done from within the {} subshell
    echo "Ignored files list (${#file_list[@]} items) is:" >&2
    for f in "${file_list[@]}"; do
        echo "    $f" >&2
    done
}

generate_vcproj |
    sed  -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}

exit
<!--
TODO: Add any files not captured by filters.
                <File
                        RelativePath=".\ReadMe.txt"
                        >
                </File>
-->