gen_msvs_proj.sh revision ba164dffc5a6795bce97fae02b51ccf3330e15e4
1#!/bin/bash
2##
3##  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4##
5##  Use of this source code is governed by a BSD-style license
6##  that can be found in the LICENSE file in the root of the source
7##  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.
10##
11
12
13self=$0
14self_basename=${self##*/}
15self_dirname=$(dirname "$0")
16EOL=$'\n'
17
18show_help() {
19    cat <<EOF
20Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
21
22This script generates a Visual Studio project file from a list of source
23code files.
24
25Options:
26    --help                      Print this message
27    --exe                       Generate a project for building an Application
28    --lib                       Generate a project for creating a static library
29    --dll                       Generate a project for creating a dll
30    --static-crt                Use the static C runtime (/MT)
31    --target=isa-os-cc          Target specifier (required)
32    --out=filename              Write output to a file [stdout]
33    --name=project_name         Name of the project (required)
34    --proj-guid=GUID            GUID to use for the project
35    --module-def=filename       File containing export definitions (for DLLs)
36    --ver=version               Version (7,8,9) of visual studio to generate for
37    --src-path-bare=dir         Path to root of source tree
38    -Ipath/to/include           Additional include directories
39    -DFLAG[=value]              Preprocessor macros to define
40    -Lpath/to/lib               Additional library search paths
41    -llibname                   Library to link against
42EOF
43    exit 1
44}
45
46die() {
47    echo "${self_basename}: $@" >&2
48    exit 1
49}
50
51die_unknown(){
52    echo "Unknown option \"$1\"." >&2
53    echo "See ${self_basename} --help for available options." >&2
54    exit 1
55}
56
57generate_uuid() {
58    local hex="0123456789ABCDEF"
59    local i
60    local uuid=""
61    local j
62    #93995380-89BD-4b04-88EB-625FBE52EBFB
63    for ((i=0; i<32; i++)); do
64        (( j = $RANDOM % 16 ))
65        uuid="${uuid}${hex:$j:1}"
66    done
67    echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}"
68}
69
70indent1="    "
71indent=""
72indent_push() {
73    indent="${indent}${indent1}"
74}
75indent_pop() {
76    indent="${indent%${indent1}}"
77}
78
79tag_attributes() {
80    for opt in "$@"; do
81        optval="${opt#*=}"
82        [ -n "${optval}" ] ||
83            die "Missing attribute value in '$opt' while generating $tag tag"
84        echo "${indent}${opt%%=*}=\"${optval}\""
85    done
86}
87
88open_tag() {
89    local tag=$1
90    shift
91    if [ $# -ne 0 ]; then
92        echo "${indent}<${tag}"
93        indent_push
94        tag_attributes "$@"
95        echo "${indent}>"
96    else
97        echo "${indent}<${tag}>"
98        indent_push
99    fi
100}
101
102close_tag() {
103    local tag=$1
104    indent_pop
105    echo "${indent}</${tag}>"
106}
107
108tag() {
109    local tag=$1
110    shift
111    if [ $# -ne 0 ]; then
112        echo "${indent}<${tag}"
113        indent_push
114        tag_attributes "$@"
115        indent_pop
116        echo "${indent}/>"
117    else
118        echo "${indent}<${tag}/>"
119    fi
120}
121
122generate_filter() {
123    local var=$1
124    local name=$2
125    local pats=$3
126    local file_list_sz
127    local i
128    local f
129    local saveIFS="$IFS"
130    local pack
131    echo "generating filter '$name' from ${#file_list[@]} files" >&2
132    IFS=*
133
134    open_tag Filter \
135        Name=$name \
136        Filter=$pats \
137        UniqueIdentifier=`generate_uuid` \
138
139    file_list_sz=${#file_list[@]}
140    for i in ${!file_list[@]}; do
141        f=${file_list[i]}
142        for pat in ${pats//;/$IFS}; do
143            if [ "${f##*.}" == "$pat" ]; then
144                unset file_list[i]
145
146                objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g')
147                open_tag File RelativePath="./$f"
148
149                if [ "$pat" == "asm" ] && $asm_use_custom_step; then
150                    for plat in "${platforms[@]}"; do
151                        for cfg in Debug Release; do
152                            open_tag FileConfiguration \
153                                Name="${cfg}|${plat}" \
154
155                            tag Tool \
156                                Name="VCCustomBuildTool" \
157                                Description="Assembling \$(InputFileName)" \
158                                CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \
159                                Outputs="\$(IntDir)$objf" \
160
161                            close_tag FileConfiguration
162                        done
163                    done
164                fi
165                if [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then
166                    for plat in "${platforms[@]}"; do
167                        for cfg in Debug Release; do
168                            open_tag FileConfiguration \
169                                Name="${cfg}|${plat}" \
170
171                            tag Tool \
172                                Name="VCCLCompilerTool" \
173                                ObjectFile="\$(IntDir)$objf" \
174
175                            close_tag FileConfiguration
176                        done
177                    done
178                fi
179                close_tag File
180
181                break
182            fi
183        done
184    done
185
186    close_tag Filter
187    IFS="$saveIFS"
188}
189
190# Process command line
191unset target
192for opt in "$@"; do
193    optval="${opt#*=}"
194    case "$opt" in
195        --help|-h) show_help
196        ;;
197        --target=*) target="${optval}"
198        ;;
199        --out=*) outfile="$optval"
200        ;;
201        --name=*) name="${optval}"
202        ;;
203        --proj-guid=*) guid="${optval}"
204        ;;
205        --module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
206        ;;
207        --exe) proj_kind="exe"
208        ;;
209        --dll) proj_kind="dll"
210        ;;
211        --lib) proj_kind="lib"
212        ;;
213        --src-path-bare=*) src_path_bare="$optval"
214        ;;
215        --static-crt) use_static_runtime=true
216        ;;
217        --ver=*)
218            vs_ver="$optval"
219            case "$optval" in
220                [789])
221                ;;
222                *) die Unrecognized Visual Studio Version in $opt
223                ;;
224            esac
225        ;;
226        -I*)
227            opt="${opt%/}"
228            incs="${incs}${incs:+;}&quot;${opt##-I}&quot;"
229            yasmincs="${yasmincs} ${opt}"
230        ;;
231        -D*) defines="${defines}${defines:+;}${opt##-D}"
232        ;;
233        -L*) # fudge . to $(OutDir)
234            if [ "${opt##-L}" == "." ]; then
235                libdirs="${libdirs}${libdirs:+;}&quot;\$(OutDir)&quot;"
236            else
237                 # Also try directories for this platform/configuration
238                 libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}&quot;"
239                 libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}/\$(PlatformName)/\$(ConfigurationName)&quot;"
240                 libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}/\$(PlatformName)&quot;"
241            fi
242        ;;
243        -l*) libs="${libs}${libs:+ }${opt##-l}.lib"
244        ;;
245        -*) die_unknown $opt
246        ;;
247        *)
248            file_list[${#file_list[@]}]="$opt"
249            case "$opt" in
250                 *.asm) uses_asm=true
251                 ;;
252            esac
253        ;;
254    esac
255done
256outfile=${outfile:-/dev/stdout}
257guid=${guid:-`generate_uuid`}
258asm_use_custom_step=false
259uses_asm=${uses_asm:-false}
260case "${vs_ver:-8}" in
261    7) vs_ver_id="7.10"
262       asm_use_custom_step=$uses_asm
263       warn_64bit='Detect64BitPortabilityProblems=true'
264    ;;
265    8) vs_ver_id="8.00"
266       asm_use_custom_step=$uses_asm
267       warn_64bit='Detect64BitPortabilityProblems=true'
268    ;;
269    9) vs_ver_id="9.00"
270       asm_use_custom_step=$uses_asm
271       warn_64bit='Detect64BitPortabilityProblems=false'
272    ;;
273esac
274
275[ -n "$name" ] || die "Project name (--name) must be specified!"
276[ -n "$target" ] || die "Target (--target) must be specified!"
277
278if ${use_static_runtime:-false}; then
279    release_runtime=0
280    debug_runtime=1
281    lib_sfx=mt
282else
283    release_runtime=2
284    debug_runtime=3
285    lib_sfx=md
286fi
287
288# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
289# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
290# debug exe, so this may need to be refactored later.
291for lib in ${libs}; do
292    if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
293        lib=${lib%.lib}d.lib
294    fi
295    debug_libs="${debug_libs}${debug_libs:+ }${lib}"
296done
297
298
299# List Keyword for this target
300case "$target" in
301    x86*) keyword="ManagedCProj"
302    ;;
303    *) die "Unsupported target $target!"
304esac
305
306# List of all platforms supported for this target
307case "$target" in
308    x86_64*)
309        platforms[0]="x64"
310        asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} &quot;\$(InputPath)&quot;"
311        asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} &quot;\$(InputPath)&quot;"
312    ;;
313    x86*)
314        platforms[0]="Win32"
315        asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} &quot;\$(InputPath)&quot;"
316        asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} &quot;\$(InputPath)&quot;"
317    ;;
318    *) die "Unsupported target $target!"
319    ;;
320esac
321
322generate_vcproj() {
323    case "$proj_kind" in
324        exe) vs_ConfigurationType=1
325        ;;
326        dll) vs_ConfigurationType=2
327        ;;
328        *)   vs_ConfigurationType=4
329        ;;
330    esac
331
332    echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
333    open_tag VisualStudioProject \
334        ProjectType="Visual C++" \
335        Version="${vs_ver_id}" \
336        Name="${name}" \
337        ProjectGUID="{${guid}}" \
338        RootNamespace="${name}" \
339        Keyword="${keyword}" \
340
341    open_tag Platforms
342    for plat in "${platforms[@]}"; do
343        tag Platform Name="$plat"
344    done
345    close_tag Platforms
346
347    open_tag Configurations
348    for plat in "${platforms[@]}"; do
349        plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
350        open_tag Configuration \
351            Name="Debug|$plat" \
352            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
353            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
354            ConfigurationType="$vs_ConfigurationType" \
355            CharacterSet="1" \
356
357        case "$target" in
358            x86*)
359                case "$name" in
360                    obj_int_extract)
361                        tag Tool \
362                            Name="VCCLCompilerTool" \
363                            Optimization="0" \
364                            AdditionalIncludeDirectories="$incs" \
365                            PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
366                            RuntimeLibrary="$debug_runtime" \
367                            WarningLevel="3" \
368                            DebugInformationFormat="1" \
369                            $warn_64bit \
370                    ;;
371                    vpx)
372                        tag Tool \
373                            Name="VCPreBuildEventTool" \
374                            CommandLine="call obj_int_extract.bat $src_path_bare" \
375
376                        tag Tool \
377                            Name="VCCLCompilerTool" \
378                            Optimization="0" \
379                            AdditionalIncludeDirectories="$incs" \
380                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
381                            RuntimeLibrary="$debug_runtime" \
382                            UsePrecompiledHeader="0" \
383                            WarningLevel="3" \
384                            DebugInformationFormat="1" \
385                            $warn_64bit \
386
387                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
388                    ;;
389                    *)
390                        tag Tool \
391                            Name="VCCLCompilerTool" \
392                            Optimization="0" \
393                            AdditionalIncludeDirectories="$incs" \
394                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
395                            RuntimeLibrary="$debug_runtime" \
396                            UsePrecompiledHeader="0" \
397                            WarningLevel="3" \
398                            DebugInformationFormat="1" \
399                            $warn_64bit \
400
401                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
402                    ;;
403                esac
404            ;;
405        esac
406
407        case "$proj_kind" in
408            exe)
409                case "$target" in
410                    x86*)
411                        case "$name" in
412                            obj_int_extract)
413                                tag Tool \
414                                    Name="VCLinkerTool" \
415                                    OutputFile="${name}.exe" \
416                                    GenerateDebugInformation="true" \
417                            ;;
418                            *)
419                                tag Tool \
420                                    Name="VCLinkerTool" \
421                                    AdditionalDependencies="$debug_libs \$(NoInherit)" \
422                                    AdditionalLibraryDirectories="$libdirs" \
423                                    GenerateDebugInformation="true" \
424                                    ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
425                            ;;
426                        esac
427                    ;;
428                 esac
429            ;;
430            lib)
431                case "$target" in
432                    x86*)
433                        tag Tool \
434                            Name="VCLibrarianTool" \
435                            OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
436
437                    ;;
438                esac
439            ;;
440            dll)
441                tag Tool \
442                    Name="VCLinkerTool" \
443                    AdditionalDependencies="\$(NoInherit)" \
444                    LinkIncremental="2" \
445                    GenerateDebugInformation="true" \
446                    AssemblyDebug="1" \
447                    TargetMachine="1" \
448                    $link_opts \
449
450            ;;
451        esac
452
453        close_tag Configuration
454
455        open_tag Configuration \
456            Name="Release|$plat" \
457            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
458            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
459            ConfigurationType="$vs_ConfigurationType" \
460            CharacterSet="1" \
461            WholeProgramOptimization="0" \
462
463        case "$target" in
464            x86*)
465                case "$name" in
466                    obj_int_extract)
467                        tag Tool \
468                            Name="VCCLCompilerTool" \
469                            Optimization="2" \
470                            FavorSizeorSpeed="1" \
471                            AdditionalIncludeDirectories="$incs" \
472                            PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
473                            RuntimeLibrary="$release_runtime" \
474                            UsePrecompiledHeader="0" \
475                            WarningLevel="3" \
476                            DebugInformationFormat="0" \
477                            $warn_64bit \
478                    ;;
479                    vpx)
480                        tag Tool \
481                            Name="VCPreBuildEventTool" \
482                            CommandLine="call obj_int_extract.bat $src_path_bare" \
483
484                        tag Tool \
485                            Name="VCCLCompilerTool" \
486                            Optimization="2" \
487                            FavorSizeorSpeed="1" \
488                            AdditionalIncludeDirectories="$incs" \
489                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
490                            RuntimeLibrary="$release_runtime" \
491                            UsePrecompiledHeader="0" \
492                            WarningLevel="3" \
493                            DebugInformationFormat="0" \
494                            $warn_64bit \
495
496                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
497                    ;;
498                    *)
499                        tag Tool \
500                            Name="VCCLCompilerTool" \
501                            AdditionalIncludeDirectories="$incs" \
502                            Optimization="2" \
503                            FavorSizeorSpeed="1" \
504                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
505                            RuntimeLibrary="$release_runtime" \
506                            UsePrecompiledHeader="0" \
507                            WarningLevel="3" \
508                            DebugInformationFormat="0" \
509                            $warn_64bit \
510
511                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
512                    ;;
513                esac
514            ;;
515        esac
516
517        case "$proj_kind" in
518            exe)
519                case "$target" in
520                    x86*)
521                        case "$name" in
522                            obj_int_extract)
523                                tag Tool \
524                                    Name="VCLinkerTool" \
525                                    OutputFile="${name}.exe" \
526                                    GenerateDebugInformation="true" \
527                            ;;
528                            *)
529                                tag Tool \
530                                    Name="VCLinkerTool" \
531                                    AdditionalDependencies="$libs \$(NoInherit)" \
532                                    AdditionalLibraryDirectories="$libdirs" \
533
534                            ;;
535                        esac
536                    ;;
537                 esac
538            ;;
539            lib)
540                case "$target" in
541                    x86*)
542                        tag Tool \
543                            Name="VCLibrarianTool" \
544                            OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
545
546                    ;;
547                esac
548            ;;
549            dll) # note differences to debug version: LinkIncremental, AssemblyDebug
550                tag Tool \
551                    Name="VCLinkerTool" \
552                    AdditionalDependencies="\$(NoInherit)" \
553                    LinkIncremental="1" \
554                    GenerateDebugInformation="true" \
555                    TargetMachine="1" \
556                    $link_opts \
557
558            ;;
559        esac
560
561        close_tag Configuration
562    done
563    close_tag Configurations
564
565    open_tag Files
566    generate_filter srcs   "Source Files"   "c;cc;def;odl;idl;hpj;bat;asm;asmx"
567    generate_filter hdrs   "Header Files"   "h;hm;inl;inc;xsd"
568    generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
569    generate_filter resrcs "Build Files"    "mk"
570    close_tag Files
571
572    tag       Globals
573    close_tag VisualStudioProject
574
575    # This must be done from within the {} subshell
576    echo "Ignored files list (${#file_list[@]} items) is:" >&2
577    for f in "${file_list[@]}"; do
578        echo "    $f" >&2
579    done
580}
581
582generate_vcproj |
583    sed  -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
584
585exit
586<!--
587TODO: Add any files not captured by filters.
588                <File
589                        RelativePath=".\ReadMe.txt"
590                        >
591                </File>
592-->
593