#!/bin/bash ## ## Copyright (c) 2010 The WebM project authors. All Rights Reserved. ## ## Use of this source code is governed by a BSD-style license ## that can be found in the LICENSE file in the root of the source ## tree. An additional intellectual property rights grant can be found ## in the file PATENTS. All contributing project authors may ## be found in the AUTHORS file in the root of the source tree. ## self=$0 self_basename=${self##*/} self_dirname=$(dirname "$0") EOL=$'\n' 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 --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) --ver=version Version (7,8) of visual studio to generate for -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 } die() { echo "${self_basename}: $@" >&2 exit 1 } die_unknown(){ echo "Unknown option \"$1\"." >&2 echo "See ${self_basename} --help for available options." >&2 exit 1 } generate_uuid() { local hex="0123456789ABCDEF" local i local uuid="" local j #93995380-89BD-4b04-88EB-625FBE52EBFB for ((i=0; i<32; i++)); do (( j = $RANDOM % 16 )) uuid="${uuid}${hex:$j:1}" done echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}" } indent1=" " indent="" indent_push() { indent="${indent}${indent1}" } indent_pop() { indent="${indent%${indent1}}" } tag_attributes() { for opt in "$@"; do optval="${opt#*=}" [ -n "${optval}" ] || die "Missing attribute value in '$opt' while generating $tag tag" echo "${indent}${opt%%=*}=\"${optval}\"" done } open_tag() { local tag=$1 shift if [ $# -ne 0 ]; then echo "${indent}<${tag}" indent_push tag_attributes "$@" echo "${indent}>" else echo "${indent}<${tag}>" indent_push fi } close_tag() { local tag=$1 indent_pop echo "${indent}</${tag}>" } tag() { local tag=$1 shift if [ $# -ne 0 ]; then echo "${indent}<${tag}" indent_push tag_attributes "$@" indent_pop echo "${indent}/>" else echo "${indent}<${tag}/>" fi } 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 \ UniqueIdentifier=`generate_uuid` 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] open_tag File RelativePath="./$f" if [ "$pat" == "asm" ] && $asm_use_custom_step; then for plat in "${platforms[@]}"; do for cfg in Debug Release; do open_tag FileConfiguration \ Name="${cfg}|${plat}" tag Tool \ Name="VCCustomBuildTool" \ Description="Assembling \$(InputFileName)" \ CommandLine="$(eval echo \$asm_${cfg}_cmdline)"\ Outputs="\$(InputName).obj" close_tag FileConfiguration done done fi if [ "${f##*.}" == "cpp" ]; then for plat in "${platforms[@]}"; do for cfg in Debug Release; do open_tag FileConfiguration \ Name="${cfg}|${plat}" tag Tool \ Name="VCCLCompilerTool" \ CompileAs="2" close_tag FileConfiguration done done fi close_tag File break fi done done close_tag Filter IFS="$saveIFS" } # Process command line unset target for opt in "$@"; do optval="${opt#*=}" case "$opt" in --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" ;; --lib) proj_kind="lib" ;; --static-crt) use_static_runtime=true ;; --ver=*) vs_ver="$optval" case $optval in [789]) ;; *) die Unrecognized Visual Studio Version in $opt ;; esac ;; -I*) opt="${opt%/}" incs="${incs}${incs:+;}"${opt##-I}"" yasmincs="${yasmincs} ${opt}" ;; -D*) defines="${defines}${defines:+;}${opt##-D}" ;; -L*) # fudge . to $(OutDir) if [ "${opt##-L}" == "." ]; then libdirs="${libdirs}${libdirs:+;}"\$(OutDir)"" else # Also try directories for this platform/configuration libdirs="${libdirs}${libdirs:+;}"${opt##-L}"" libdirs="${libdirs}${libdirs:+;}"${opt##-L}/\$(PlatformName)/\$(ConfigurationName)"" libdirs="${libdirs}${libdirs:+;}"${opt##-L}/\$(PlatformName)"" fi ;; -l*) libs="${libs}${libs:+ }${opt##-l}.lib" ;; -*) die_unknown $opt ;; *) file_list[${#file_list[@]}]="$opt" case "$opt" in *.asm) uses_asm=true;; esac esac done 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 ;; 8) vs_ver_id="8.00" ;; 9) vs_ver_id="9.00" ;; 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 x86*) keyword="ManagedCProj" ;; arm*|iwmmx*) keyword="Win32Proj" ;; *) die "Unsupported target $target!" esac # List of all platforms supported for this target case "$target" in x86_64*) platforms[0]="x64" ;; x86*) platforms[0]="Win32" # these are only used by vs7 asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" ;; arm*|iwmmx*) case "${name}" in obj_int_extract) platforms[0]="Win32" ;; *) platforms[0]="Pocket PC 2003 (ARMV4)" ;; esac ;; *) die "Unsupported target $target!" esac # List Command-line Arguments for this target case "$target" in arm*|iwmmx*) if [ "$name" == "example" ];then ARGU="--codec vp6 --flipuv --progress _bnd.vp6" fi if [ "$name" == "xma" ];then ARGU="--codec vp6 -h 240 -w 320 -v" fi ;; esac generate_vcproj() { case "$proj_kind" in exe) vs_ConfigurationType=1 ;; *) vs_ConfigurationType=4 ;; esac echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>" open_tag VisualStudioProject \ ProjectType="Visual C++" \ Version="${vs_ver_id}" \ Name="${name}" \ ProjectGUID="{${guid}}" \ RootNamespace="${name}" \ Keyword="${keyword}" open_tag Platforms for plat in "${platforms[@]}"; do tag Platform Name="$plat" done close_tag Platforms open_tag ToolFiles case "$target" in x86*) $uses_asm && tag ToolFile RelativePath="$self_dirname/../x86-msvs/yasm.rules" ;; arm*|iwmmx*) if [ "$name" == "vpx" ];then case "$target" in armv5*) tag ToolFile RelativePath="$self_dirname/../arm-wince-vs8/armasmv5.rules" ;; armv6*) tag ToolFile RelativePath="$self_dirname/../arm-wince-vs8/armasmv6.rules" ;; iwmmxt*) tag ToolFile RelativePath="$self_dirname/../arm-wince-vs8/armasmxscale.rules" ;; esac fi ;; esac close_tag ToolFiles open_tag Configurations for plat in "${platforms[@]}"; do plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'` open_tag Configuration \ Name="Debug|$plat" \ OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \ IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \ ConfigurationType="$vs_ConfigurationType" \ CharacterSet="1" if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then case "$name" in vpx) tag Tool \ Name="VCPreBuildEventTool" \ CommandLine="call obj_int_extract.bat \$(ConfigurationName)" tag Tool \ Name="VCMIDLTool" \ TargetEnvironment="1" tag Tool \ Name="VCCLCompilerTool" \ ExecutionBucket="7" \ Optimization="0" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;" \ MinimalRebuild="true" \ RuntimeLibrary="1" \ BufferSecurityCheck="false" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="1" \ CompileAs="1" tag Tool \ Name="VCResourceCompilerTool" \ PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \ Culture="1033" \ AdditionalIncludeDirectories="\$(IntDir)" \ ;; example|xma) tag Tool \ Name="VCCLCompilerTool" \ ExecutionBucket="7" \ Optimization="0" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;DEBUG;_CONSOLE;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;" \ MinimalRebuild="true" \ RuntimeLibrary="1" \ BufferSecurityCheck="false" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="1" \ CompileAs="1" tag Tool \ Name="VCResourceCompilerTool" \ PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \ Culture="1033" \ AdditionalIncludeDirectories="\$(IntDir)" \ ;; obj_int_extract) tag Tool \ Name="VCCLCompilerTool" \ Optimization="0" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE" \ RuntimeLibrary="1" \ WarningLevel="3" \ DebugInformationFormat="1" \ ;; esac fi case "$target" in x86*) 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" \ DebugInformationFormat="1" \ Detect64BitPortabilityProblems="true" \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="1" ;; esac case "$proj_kind" in exe) case "$target" in x86*) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$debug_libs \$(NoInherit)" \ AdditionalLibraryDirectories="$libdirs" \ GenerateDebugInformation="true" \ ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \ ;; arm*|iwmmx*) case "$name" in obj_int_extract) tag Tool \ Name="VCLinkerTool" \ OutputFile="${name}.exe" \ GenerateDebugInformation="true" ;; *) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$debug_libs" \ OutputFile="\$(OutDir)/${name}.exe" \ LinkIncremental="2" \ AdditionalLibraryDirectories="${libdirs};"..\lib/$plat_no_ws"" \ DelayLoadDLLs="\$(NOINHERIT)" \ GenerateDebugInformation="true" \ ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \ SubSystem="9" \ StackReserveSize="65536" \ StackCommitSize="4096" \ EntryPointSymbol="mainWCRTStartup" \ TargetMachine="3" ;; esac ;; esac ;; lib) case "$target" in arm*|iwmmx*) tag Tool \ Name="VCLibrarianTool" \ AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM" \ OutputFile="\$(OutDir)/${name}.lib" \ ;; *) tag Tool \ Name="VCLibrarianTool" \ OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \ ;; esac ;; dll) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="\$(NoInherit)" \ LinkIncremental="2" \ GenerateDebugInformation="true" \ AssemblyDebug="1" \ TargetMachine="1" \ $link_opts esac if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then case "$name" in vpx) tag DeploymentTool \ ForceDirty="-1" \ RegisterOutput="0" ;; example|xma) tag DeploymentTool \ ForceDirty="-1" \ RegisterOutput="0" tag DebuggerTool \ Arguments="${ARGU}" ;; esac fi close_tag Configuration 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" if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then case "$name" in vpx) tag Tool \ Name="VCPreBuildEventTool" \ CommandLine="call obj_int_extract.bat \$(ConfigurationName)" tag Tool \ Name="VCMIDLTool" \ TargetEnvironment="1" tag Tool \ Name="VCCLCompilerTool" \ ExecutionBucket="7" \ Optimization="2" \ FavorSizeOrSpeed="1" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;_LIB;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;" \ RuntimeLibrary="0" \ BufferSecurityCheck="false" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ CompileAs="1" tag Tool \ Name="VCResourceCompilerTool" \ PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \ Culture="1033" \ AdditionalIncludeDirectories="\$(IntDir)" \ ;; example|xma) tag Tool \ Name="VCCLCompilerTool" \ ExecutionBucket="7" \ Optimization="2" \ FavorSizeOrSpeed="1" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;_CONSOLE;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;" \ RuntimeLibrary="0" \ BufferSecurityCheck="false" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ CompileAs="1" tag Tool \ Name="VCResourceCompilerTool" \ PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \ Culture="1033" \ AdditionalIncludeDirectories="\$(IntDir)" \ ;; obj_int_extract) tag Tool \ Name="VCCLCompilerTool" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" \ RuntimeLibrary="0" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ Detect64BitPortabilityProblems="true" \ DebugInformationFormat="0" \ ;; esac fi case "$target" in x86*) tag Tool \ Name="VCCLCompilerTool" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \ RuntimeLibrary="$release_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ Detect64BitPortabilityProblems="true" $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" ;; esac case "$proj_kind" in exe) case "$target" in x86*) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$libs \$(NoInherit)" \ AdditionalLibraryDirectories="$libdirs" \ ;; arm*|iwmmx*) case "$name" in obj_int_extract) tag Tool \ Name="VCLinkerTool" \ OutputFile="${name}.exe" \ LinkIncremental="1" \ GenerateDebugInformation="false" \ SubSystem="0" \ OptimizeReferences="0" \ EnableCOMDATFolding="0" \ TargetMachine="0" ;; *) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$libs" \ OutputFile="\$(OutDir)/${name}.exe" \ LinkIncremental="1" \ AdditionalLibraryDirectories="${libdirs};"..\lib/$plat_no_ws"" \ DelayLoadDLLs="\$(NOINHERIT)" \ GenerateDebugInformation="true" \ ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \ SubSystem="9" \ StackReserveSize="65536" \ StackCommitSize="4096" \ OptimizeReferences="2" \ EnableCOMDATFolding="2" \ EntryPointSymbol="mainWCRTStartup" \ TargetMachine="3" ;; esac ;; esac ;; lib) case "$target" in arm*|iwmmx*) tag Tool \ Name="VCLibrarianTool" \ AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM" \ OutputFile="\$(OutDir)/${name}.lib" \ ;; *) tag Tool \ Name="VCLibrarianTool" \ OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \ ;; esac ;; dll) # note differences to debug version: LinkIncremental, AssemblyDebug tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="\$(NoInherit)" \ LinkIncremental="1" \ GenerateDebugInformation="true" \ TargetMachine="1" \ $link_opts esac if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then case "$name" in vpx) tag DeploymentTool \ ForceDirty="-1" \ RegisterOutput="0" ;; example|xma) tag DeploymentTool \ ForceDirty="-1" \ RegisterOutput="0" tag DebuggerTool \ Arguments="${ARGU}" ;; esac fi close_tag Configuration done close_tag Configurations open_tag Files generate_filter srcs "Source Files" "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" generate_filter hdrs "Header Files" "h;hpp;hxx;hm;inl;inc;xsd" 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> -->