ref: 56666f07263d9a5e278f78fd4008c7e1bc8896a8
parent: 70977814679d84b314b2cf41d8e6b76c0868c21b
author: Martin Storsjo <martin@martin.st>
date: Thu May 16 20:53:05 EDT 2013
Add a new script for producing vcxproj files Change-Id: If02a7b85f417b9693dcdab73573fc13f67e17016
--- /dev/null
+++ b/build/make/gen_msvs_vcxproj.sh
@@ -1,0 +1,506 @@
+#!/bin/bash
+##
+## Copyright (c) 2013 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
+ --dll Generate a project for creating a dll
+ --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 (10,11) of visual studio to generate for
+ --src-path-bare=dir Path to root of source tree
+ -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
+}
+
+tag_content() {+ local tag=$1
+ local content=$2
+ shift
+ shift
+ if [ $# -ne 0 ]; then
+ echo "${indent}<${tag}"+ indent_push
+ tag_attributes "$@"
+ echo "${indent}>${content}</${tag}>"+ indent_pop
+ else
+ echo "${indent}<${tag}>${content}</${tag}>"+ fi
+}
+
+generate_filter() {+ local name=$1
+ local pats=$2
+ local file_list_sz
+ local i
+ local f
+ local saveIFS="$IFS"
+ local pack
+ echo "generating filter '$name' from ${#file_list[@]} files" >&2+ IFS=*
+
+ 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]
+
+ objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g')+
+ if [ "$pat" == "asm" ] && $asm_use_custom_step; then
+ open_tag CustomBuild \
+ Include=".\\$f"
+ for plat in "${platforms[@]}"; do+ for cfg in Debug Release; do
+ tag_content Message "Assembling %(Filename)%(Extension)" \
+ Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+ tag_content Command "$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \+ Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+ tag_content Outputs "\$(IntDir)$objf" \
+ Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+ done
+ done
+ close_tag CustomBuild
+ elif [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then
+ open_tag ClCompile \
+ Include=".\\$f"
+ # Separate file names with Condition?
+ tag_content ObjectFileName "\$(IntDir)$objf"
+ close_tag ClCompile
+ elif [ "$pat" == "h" ] ; then
+ tag ClInclude \
+ Include=".\\$f"
+ elif [ "$pat" == "vcxproj" ] ; then
+ open_tag ProjectReference \
+ Include="$f"
+ depguid=`grep ProjectGuid "$f" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
+ tag_content Project "$depguid"
+ tag_content ReferenceOutputAssembly false
+ close_tag ProjectReference
+ else
+ tag None \
+ Include=".\\$f"
+ fi
+
+ break
+ fi
+ done
+ done
+
+ 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=*) module_def="${optval}"+ ;;
+ --exe) proj_kind="exe"
+ ;;
+ --dll) proj_kind="dll"
+ ;;
+ --lib) proj_kind="lib"
+ ;;
+ --src-path-bare=*) src_path_bare="$optval"
+ ;;
+ --static-crt) use_static_runtime=true
+ ;;
+ --ver=*)
+ vs_ver="$optval"
+ case "$optval" in
+ 10|11)
+ ;;
+ *) 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)/\$(Configuration)"+ 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:-11}" in+ 10|11)
+ asm_use_custom_step=$uses_asm
+ ;;
+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=MultiThreaded
+ debug_runtime=MultiThreadedDebug
+ lib_sfx=mt
+else
+ release_runtime=MultiThreadedDLL
+ debug_runtime=MultiThreadedDebugDLL
+ 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
+debug_libs=${debug_libs// /;}+libs=${libs// /;}+
+
+# List of all platforms supported for this target
+case "$target" in
+ x86_64*)
+ platforms[0]="x64"
+ asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)""+ asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)""+ ;;
+ x86*)
+ platforms[0]="Win32"
+ asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)""+ asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)""+ ;;
+ *) die "Unsupported target $target!"
+ ;;
+esac
+
+generate_vcxproj() {+ echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ open_tag Project \
+ DefaultTargets="Build" \
+ ToolsVersion="4.0" \
+ xmlns="http://schemas.microsoft.com/developer/msbuild/2003" \
+
+ open_tag ItemGroup \
+ Label="ProjectConfigurations"
+ for plat in "${platforms[@]}"; do+ for config in Debug Release; do
+ open_tag ProjectConfiguration \
+ Include="$config|$plat"
+ tag_content Configuration $config
+ tag_content Platform $plat
+ close_tag ProjectConfiguration
+ done
+ done
+ close_tag ItemGroup
+
+ open_tag PropertyGroup \
+ Label="Globals"
+ tag_content ProjectGuid "{${guid}}"+ tag_content RootNamespace ${name}+ tag_content Keyword ManagedCProj
+ close_tag PropertyGroup
+
+ tag Import \
+ Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props"
+
+ for plat in "${platforms[@]}"; do+ for config in Release Debug; do
+ open_tag PropertyGroup \
+ Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" \
+ Label="Configuration"
+ if [ "$proj_kind" = "exe" ]; then
+ tag_content ConfigurationType Application
+ elif [ "$proj_kind" = "dll" ]; then
+ tag_content ConfigurationType DynamicLibrary
+ else
+ tag_content ConfigurationType StaticLibrary
+ fi
+ tag_content PlatformToolset v110 # v110_wp80, omit for v10
+ tag_content CharacterSet Unicode
+ if [ "$config" = "Release" ]; then
+ tag_content WholeProgramOptimization true
+ fi
+ close_tag PropertyGroup
+ done
+ done
+
+ tag Import \
+ Project="\$(VCTargetsPath)\\Microsoft.Cpp.props"
+
+ open_tag ImportGroup \
+ Label="PropertySheets"
+ tag Import \
+ Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" \
+ Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" \+ Label="LocalAppDataPlatform"
+ close_tag ImportGroup
+
+ tag PropertyGroup \
+ Label="UserMacros"
+
+ for plat in "${platforms[@]}"; do+ plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
+ for config in Debug Release; do
+ open_tag PropertyGroup \
+ Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'"
+ tag_content OutDir "\$(SolutionDir)$plat_no_ws\\\$(Configuration)\\"
+ tag_content IntDir "$plat_no_ws\\\$(Configuration)\\${name}\\"+ close_tag PropertyGroup
+ done
+ done
+
+ for plat in "${platforms[@]}"; do+ for config in Debug Release; do
+ open_tag ItemDefinitionGroup \
+ Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'"
+ if [ "$name" = "vpx" ]; then
+ open_tag PreBuildEvent
+ tag_content Command "call obj_int_extract.bat $src_path_bare"
+ close_tag PreBuildEvent
+ fi
+ open_tag ClCompile
+ if [ "$config" = "Debug" ]; then
+ opt=Disabled
+ runtime=$debug_runtime
+ curlibs=$debug_libs
+ confsuffix=d
+ case "$name" in
+ obj_int_extract)
+ debug=DEBUG
+ ;;
+ *)
+ debug=_DEBUG
+ ;;
+ esac
+ else
+ opt=MaxSpeed
+ runtime=$release_runtime
+ curlibs=$libs
+ confsuffix=""
+ tag_content FavorSizeOrSpeed Speed
+ debug=NDEBUG
+ fi
+ case "$name" in
+ obj_int_extract)
+ extradefines=";_CONSOLE"
+ ;;
+ *)
+ extradefines=";$defines"
+ ;;
+ esac
+ tag_content Optimization $opt
+ tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)"
+ tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)"
+ tag_content RuntimeLibrary $runtime
+ tag_content WarningLevel Level3
+ # DebugInformationFormat
+ close_tag ClCompile
+ case "$proj_kind" in
+ exe)
+ open_tag Link
+ if [ "$name" = "obj_int_extract" ]; then
+ tag_content OutputFile "${name}.exe"+ else
+ tag_content AdditionalDependencies "$curlibs"
+ tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)"
+ fi
+ tag_content GenerateDebugInformation true
+ close_tag Link
+ ;;
+ dll)
+ open_tag Link
+ tag_content GenerateDebugInformation true
+ tag_content ModuleDefinitionFile $module_def
+ close_tag Link
+ ;;
+ lib)
+ open_tag Lib
+ tag_content OutputFile "\$(OutDir)${name}${lib_sfx}${confsuffix}.lib"+ close_tag Lib
+ ;;
+ esac
+ close_tag ItemDefinitionGroup
+ done
+
+ done
+
+ open_tag ItemGroup
+ generate_filter "Source Files" "c;cc;def;odl;idl;hpj;bat;asm;asmx"
+ close_tag ItemGroup
+ open_tag ItemGroup
+ generate_filter "Header Files" "h;hm;inl;inc;xsd"
+ close_tag ItemGroup
+ open_tag ItemGroup
+ generate_filter "Build Files" "mk"
+ close_tag ItemGroup
+ open_tag ItemGroup
+ generate_filter "References" "vcxproj"
+ close_tag ItemGroup
+
+ tag Import \
+ Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets"
+
+ open_tag ImportGroup \
+ Label="ExtensionTargets"
+ close_tag ImportGroup
+
+ close_tag Project
+
+ # 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
+}
+
+# This regexp doesn't catch most of the strings in the vcxproj format,
+# since they're like <tag>path</tag> instead of <tag attr="path" />
+# as previously. It still seems to work ok despite this.
+generate_vcxproj |
+ sed -e '/"/s;\([^ "]\)/;\1\\;g' |
+ sed -e '/xmlns/s;\\;/;g' > ${outfile}+
+exit
--
⑨