#!/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,9) 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 } 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 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" ;; --src-path-bare=*) src_path_bare="$optval" ;; --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" ;; *) 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)"" ;; *) die "Unsupported target $target!" ;; 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" ;; 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" \ case "$target" in x86*) case "$name" in obj_int_extract) tag Tool \ Name="VCCLCompilerTool" \ Optimization="0" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \ RuntimeLibrary="$debug_runtime" \ WarningLevel="3" \ Detect64BitPortabilityProblems="true" \ DebugInformationFormat="1" \ ;; vpx) tag Tool \ Name="VCPreBuildEventTool" \ CommandLine="call obj_int_extract.bat $src_path_bare" \ 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" ;; *) 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 ;; esac case "$proj_kind" in exe) case "$target" in x86*) case "$name" in obj_int_extract) tag Tool \ Name="VCLinkerTool" \ OutputFile="${name}.exe" \ GenerateDebugInformation="true" \ ;; *) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$debug_libs \$(NoInherit)" \ AdditionalLibraryDirectories="$libdirs" \ GenerateDebugInformation="true" \ ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \ ;; esac ;; esac ;; lib) case "$target" in x86*) 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 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" \ case "$target" in x86*) case "$name" in obj_int_extract) tag Tool \ Name="VCCLCompilerTool" \ AdditionalIncludeDirectories="$incs" \ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \ RuntimeLibrary="$release_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ Detect64BitPortabilityProblems="true" \ DebugInformationFormat="0" \ ;; vpx) tag Tool \ Name="VCPreBuildEventTool" \ CommandLine="call obj_int_extract.bat $src_path_bare" \ 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" ;; *) 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 ;; esac case "$proj_kind" in exe) case "$target" in x86*) case "$name" in obj_int_extract) tag Tool \ Name="VCLinkerTool" \ OutputFile="${name}.exe" \ GenerateDebugInformation="true" \ ;; *) tag Tool \ Name="VCLinkerTool" \ AdditionalDependencies="$libs \$(NoInherit)" \ AdditionalLibraryDirectories="$libdirs" \ ;; esac ;; esac ;; lib) case "$target" in x86*) 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 close_tag Configuration done close_tag Configurations open_tag Files generate_filter srcs "Source Files" "c;def;odl;idl;hpj;bat;asm;asmx" generate_filter hdrs "Header Files" "h;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> -->