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
12self=$0
13self_basename=${self##*/}
14self_dirname=$(dirname "$0")
15
16. "$self_dirname/msvs_common.sh"|| exit 127
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
46generate_filter() {
47    local var=$1
48    local name=$2
49    local pats=$3
50    local file_list_sz
51    local i
52    local f
53    local saveIFS="$IFS"
54    local pack
55    echo "generating filter '$name' from ${#file_list[@]} files" >&2
56    IFS=*
57
58    open_tag Filter \
59        Name=$name \
60        Filter=$pats \
61        UniqueIdentifier=`generate_uuid` \
62
63    file_list_sz=${#file_list[@]}
64    for i in ${!file_list[@]}; do
65        f=${file_list[i]}
66        for pat in ${pats//;/$IFS}; do
67            if [ "${f##*.}" == "$pat" ]; then
68                unset file_list[i]
69
70                objf=$(echo ${f%.*}.obj \
71                       | sed -e "s,$src_path_bare,," \
72                             -e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
73                open_tag File RelativePath="$f"
74
75                if [ "$pat" == "asm" ] && $asm_use_custom_step; then
76                    for plat in "${platforms[@]}"; do
77                        for cfg in Debug Release; do
78                            open_tag FileConfiguration \
79                                Name="${cfg}|${plat}" \
80
81                            tag Tool \
82                                Name="VCCustomBuildTool" \
83                                Description="Assembling \$(InputFileName)" \
84                                CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)\\$objf" \
85                                Outputs="\$(IntDir)\\$objf" \
86
87                            close_tag FileConfiguration
88                        done
89                    done
90                fi
91                if [ "$pat" == "c" ] || \
92                   [ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
93                    for plat in "${platforms[@]}"; do
94                        for cfg in Debug Release; do
95                            open_tag FileConfiguration \
96                                Name="${cfg}|${plat}" \
97
98                            tag Tool \
99                                Name="VCCLCompilerTool" \
100                                ObjectFile="\$(IntDir)\\$objf" \
101
102                            close_tag FileConfiguration
103                        done
104                    done
105                fi
106                close_tag File
107
108                break
109            fi
110        done
111    done
112
113    close_tag Filter
114    IFS="$saveIFS"
115}
116
117# Process command line
118unset target
119for opt in "$@"; do
120    optval="${opt#*=}"
121    case "$opt" in
122        --help|-h) show_help
123        ;;
124        --target=*) target="${optval}"
125        ;;
126        --out=*) outfile="$optval"
127        ;;
128        --name=*) name="${optval}"
129        ;;
130        --proj-guid=*) guid="${optval}"
131        ;;
132        --module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
133        ;;
134        --exe) proj_kind="exe"
135        ;;
136        --dll) proj_kind="dll"
137        ;;
138        --lib) proj_kind="lib"
139        ;;
140        --src-path-bare=*)
141            src_path_bare=$(fix_path "$optval")
142            src_path_bare=${src_path_bare%/}
143        ;;
144        --static-crt) use_static_runtime=true
145        ;;
146        --ver=*)
147            vs_ver="$optval"
148            case "$optval" in
149                [789])
150                ;;
151                *) die Unrecognized Visual Studio Version in $opt
152                ;;
153            esac
154        ;;
155        -I*)
156            opt=${opt##-I}
157            opt=$(fix_path "$opt")
158            opt="${opt%/}"
159            incs="${incs}${incs:+;}&quot;${opt}&quot;"
160            yasmincs="${yasmincs} -I&quot;${opt}&quot;"
161        ;;
162        -D*) defines="${defines}${defines:+;}${opt##-D}"
163        ;;
164        -L*) # fudge . to $(OutDir)
165            if [ "${opt##-L}" == "." ]; then
166                libdirs="${libdirs}${libdirs:+;}&quot;\$(OutDir)&quot;"
167            else
168                 # Also try directories for this platform/configuration
169                 opt=${opt##-L}
170                 opt=$(fix_path "$opt")
171                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}&quot;"
172                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)/\$(ConfigurationName)&quot;"
173                 libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)&quot;"
174            fi
175        ;;
176        -l*) libs="${libs}${libs:+ }${opt##-l}.lib"
177        ;;
178        -*) die_unknown $opt
179        ;;
180        *)
181            # The paths in file_list are fixed outside of the loop.
182            file_list[${#file_list[@]}]="$opt"
183            case "$opt" in
184                 *.asm) uses_asm=true
185                 ;;
186            esac
187        ;;
188    esac
189done
190
191# Make one call to fix_path for file_list to improve performance.
192fix_file_list
193
194outfile=${outfile:-/dev/stdout}
195guid=${guid:-`generate_uuid`}
196asm_use_custom_step=false
197uses_asm=${uses_asm:-false}
198case "${vs_ver:-8}" in
199    7) vs_ver_id="7.10"
200       asm_use_custom_step=$uses_asm
201       warn_64bit='Detect64BitPortabilityProblems=true'
202    ;;
203    8) vs_ver_id="8.00"
204       asm_use_custom_step=$uses_asm
205       warn_64bit='Detect64BitPortabilityProblems=true'
206    ;;
207    9) vs_ver_id="9.00"
208       asm_use_custom_step=$uses_asm
209       warn_64bit='Detect64BitPortabilityProblems=false'
210    ;;
211esac
212
213[ -n "$name" ] || die "Project name (--name) must be specified!"
214[ -n "$target" ] || die "Target (--target) must be specified!"
215
216if ${use_static_runtime:-false}; then
217    release_runtime=0
218    debug_runtime=1
219    lib_sfx=mt
220else
221    release_runtime=2
222    debug_runtime=3
223    lib_sfx=md
224fi
225
226# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
227# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
228# debug exe, so this may need to be refactored later.
229for lib in ${libs}; do
230    if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
231        lib=${lib%.lib}d.lib
232    fi
233    debug_libs="${debug_libs}${debug_libs:+ }${lib}"
234done
235
236
237# List Keyword for this target
238case "$target" in
239    x86*) keyword="ManagedCProj"
240    ;;
241    *) die "Unsupported target $target!"
242esac
243
244# List of all platforms supported for this target
245case "$target" in
246    x86_64*)
247        platforms[0]="x64"
248        asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
249        asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
250    ;;
251    x86*)
252        platforms[0]="Win32"
253        asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
254        asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
255    ;;
256    *) die "Unsupported target $target!"
257    ;;
258esac
259
260generate_vcproj() {
261    case "$proj_kind" in
262        exe) vs_ConfigurationType=1
263        ;;
264        dll) vs_ConfigurationType=2
265        ;;
266        *)   vs_ConfigurationType=4
267        ;;
268    esac
269
270    echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
271    open_tag VisualStudioProject \
272        ProjectType="Visual C++" \
273        Version="${vs_ver_id}" \
274        Name="${name}" \
275        ProjectGUID="{${guid}}" \
276        RootNamespace="${name}" \
277        Keyword="${keyword}" \
278
279    open_tag Platforms
280    for plat in "${platforms[@]}"; do
281        tag Platform Name="$plat"
282    done
283    close_tag Platforms
284
285    open_tag Configurations
286    for plat in "${platforms[@]}"; do
287        plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
288        open_tag Configuration \
289            Name="Debug|$plat" \
290            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
291            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
292            ConfigurationType="$vs_ConfigurationType" \
293            CharacterSet="1" \
294
295        case "$target" in
296            x86*)
297                case "$name" in
298                    obj_int_extract)
299                        tag Tool \
300                            Name="VCCLCompilerTool" \
301                            Optimization="0" \
302                            AdditionalIncludeDirectories="$incs" \
303                            PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
304                            RuntimeLibrary="$debug_runtime" \
305                            WarningLevel="3" \
306                            DebugInformationFormat="1" \
307                            $warn_64bit \
308                    ;;
309                    vpx)
310                        tag Tool \
311                            Name="VCPreBuildEventTool" \
312                            CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
313
314                        tag Tool \
315                            Name="VCCLCompilerTool" \
316                            Optimization="0" \
317                            AdditionalIncludeDirectories="$incs" \
318                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
319                            RuntimeLibrary="$debug_runtime" \
320                            UsePrecompiledHeader="0" \
321                            WarningLevel="3" \
322                            DebugInformationFormat="2" \
323                            $warn_64bit \
324
325                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
326                    ;;
327                    *)
328                        tag Tool \
329                            Name="VCCLCompilerTool" \
330                            Optimization="0" \
331                            AdditionalIncludeDirectories="$incs" \
332                            PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
333                            RuntimeLibrary="$debug_runtime" \
334                            UsePrecompiledHeader="0" \
335                            WarningLevel="3" \
336                            DebugInformationFormat="2" \
337                            $warn_64bit \
338
339                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="true"
340                    ;;
341                esac
342            ;;
343        esac
344
345        case "$proj_kind" in
346            exe)
347                case "$target" in
348                    x86*)
349                        case "$name" in
350                            obj_int_extract)
351                                tag Tool \
352                                    Name="VCLinkerTool" \
353                                    GenerateDebugInformation="true" \
354                            ;;
355                            *)
356                                tag Tool \
357                                    Name="VCLinkerTool" \
358                                    AdditionalDependencies="$debug_libs \$(NoInherit)" \
359                                    AdditionalLibraryDirectories="$libdirs" \
360                                    GenerateDebugInformation="true" \
361                                    ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
362                            ;;
363                        esac
364                    ;;
365                 esac
366            ;;
367            lib)
368                case "$target" in
369                    x86*)
370                        tag Tool \
371                            Name="VCLibrarianTool" \
372                            OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
373
374                    ;;
375                esac
376            ;;
377            dll)
378                tag Tool \
379                    Name="VCLinkerTool" \
380                    AdditionalDependencies="\$(NoInherit)" \
381                    LinkIncremental="2" \
382                    GenerateDebugInformation="true" \
383                    AssemblyDebug="1" \
384                    TargetMachine="1" \
385                    $link_opts \
386
387            ;;
388        esac
389
390        close_tag Configuration
391
392        open_tag Configuration \
393            Name="Release|$plat" \
394            OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
395            IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
396            ConfigurationType="$vs_ConfigurationType" \
397            CharacterSet="1" \
398            WholeProgramOptimization="0" \
399
400        case "$target" in
401            x86*)
402                case "$name" in
403                    obj_int_extract)
404                        tag Tool \
405                            Name="VCCLCompilerTool" \
406                            Optimization="2" \
407                            FavorSizeorSpeed="1" \
408                            AdditionalIncludeDirectories="$incs" \
409                            PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
410                            RuntimeLibrary="$release_runtime" \
411                            UsePrecompiledHeader="0" \
412                            WarningLevel="3" \
413                            DebugInformationFormat="0" \
414                            $warn_64bit \
415                    ;;
416                    vpx)
417                        tag Tool \
418                            Name="VCPreBuildEventTool" \
419                            CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
420
421                        tag Tool \
422                            Name="VCCLCompilerTool" \
423                            Optimization="2" \
424                            FavorSizeorSpeed="1" \
425                            AdditionalIncludeDirectories="$incs" \
426                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
427                            RuntimeLibrary="$release_runtime" \
428                            UsePrecompiledHeader="0" \
429                            WarningLevel="3" \
430                            DebugInformationFormat="0" \
431                            $warn_64bit \
432
433                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
434                    ;;
435                    *)
436                        tag Tool \
437                            Name="VCCLCompilerTool" \
438                            AdditionalIncludeDirectories="$incs" \
439                            Optimization="2" \
440                            FavorSizeorSpeed="1" \
441                            PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
442                            RuntimeLibrary="$release_runtime" \
443                            UsePrecompiledHeader="0" \
444                            WarningLevel="3" \
445                            DebugInformationFormat="0" \
446                            $warn_64bit \
447
448                        $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
449                    ;;
450                esac
451            ;;
452        esac
453
454        case "$proj_kind" in
455            exe)
456                case "$target" in
457                    x86*)
458                        case "$name" in
459                            obj_int_extract)
460                                tag Tool \
461                                    Name="VCLinkerTool" \
462                                    GenerateDebugInformation="true" \
463                            ;;
464                            *)
465                                tag Tool \
466                                    Name="VCLinkerTool" \
467                                    AdditionalDependencies="$libs \$(NoInherit)" \
468                                    AdditionalLibraryDirectories="$libdirs" \
469
470                            ;;
471                        esac
472                    ;;
473                 esac
474            ;;
475            lib)
476                case "$target" in
477                    x86*)
478                        tag Tool \
479                            Name="VCLibrarianTool" \
480                            OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
481
482                    ;;
483                esac
484            ;;
485            dll) # note differences to debug version: LinkIncremental, AssemblyDebug
486                tag Tool \
487                    Name="VCLinkerTool" \
488                    AdditionalDependencies="\$(NoInherit)" \
489                    LinkIncremental="1" \
490                    GenerateDebugInformation="true" \
491                    TargetMachine="1" \
492                    $link_opts \
493
494            ;;
495        esac
496
497        close_tag Configuration
498    done
499    close_tag Configurations
500
501    open_tag Files
502    generate_filter srcs   "Source Files"   "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
503    generate_filter hdrs   "Header Files"   "h;hm;inl;inc;xsd"
504    generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
505    generate_filter resrcs "Build Files"    "mk"
506    close_tag Files
507
508    tag       Globals
509    close_tag VisualStudioProject
510
511    # This must be done from within the {} subshell
512    echo "Ignored files list (${#file_list[@]} items) is:" >&2
513    for f in "${file_list[@]}"; do
514        echo "    $f" >&2
515    done
516}
517
518generate_vcproj |
519    sed  -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
520
521exit
522<!--
523TODO: Add any files not captured by filters.
524                <File
525                        RelativePath=".\ReadMe.txt"
526                        >
527                </File>
528-->
529