| #!/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") |
| |
| . "$self_dirname/msvs_common.sh"|| exit 127 |
| |
| 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) |
| --enable-werror Treat warnings as errors (/WX) |
| --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,12,14) 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 |
| } |
| |
| 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,$src_path_bare,," \ |
| -e 's/^[\./]\+//g' -e 's,[:/ ],_,g') |
| |
| if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then |
| # Avoid object file name collisions, i.e. vpx_config.c and |
| # vpx_config.asm produce the same object file without |
| # this additional suffix. |
| objf=${objf%.obj}_asm.obj |
| 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" ] || [ "$pat" == "cpp" ]; then |
| open_tag ClCompile \ |
| Include="$f" |
| # Separate file names with Condition? |
| tag_content ObjectFileName "\$(IntDir)$objf" |
| # Check for AVX and turn it on to avoid warnings. |
| if [[ $f =~ avx.?\.c$ ]]; then |
| tag_content AdditionalOptions "/arch:AVX" |
| fi |
| 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=$(fix_path "$optval") |
| src_path_bare=${src_path_bare%/} |
| ;; |
| --static-crt) use_static_runtime=true |
| ;; |
| --enable-werror) werror=true |
| ;; |
| --ver=*) |
| vs_ver="$optval" |
| case "$optval" in |
| 10|11|12|14) |
| ;; |
| *) die Unrecognized Visual Studio Version in $opt |
| ;; |
| esac |
| ;; |
| -I*) |
| opt=${opt##-I} |
| opt=$(fix_path "$opt") |
| opt="${opt%/}" |
| incs="${incs}${incs:+;}"${opt}"" |
| yasmincs="${yasmincs} -I"${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 |
| opt=${opt##-L} |
| opt=$(fix_path "$opt") |
| libdirs="${libdirs}${libdirs:+;}"${opt}"" |
| libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)/\$(Configuration)"" |
| libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)"" |
| fi |
| ;; |
| -l*) libs="${libs}${libs:+ }${opt##-l}.lib" |
| ;; |
| -*) die_unknown $opt |
| ;; |
| *) |
| # The paths in file_list are fixed outside of the loop. |
| file_list[${#file_list[@]}]="$opt" |
| case "$opt" in |
| *.asm|*.s) uses_asm=true |
| ;; |
| esac |
| ;; |
| esac |
| done |
| |
| # Make one call to fix_path for file_list to improve performance. |
| fix_file_list file_list |
| |
| 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|12|14) |
| 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 win64 ${yasmincs} "%(FullPath)"" |
| asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} "%(FullPath)"" |
| ;; |
| x86*) |
| platforms[0]="Win32" |
| asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} "%(FullPath)"" |
| asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} "%(FullPath)"" |
| ;; |
| arm*) |
| platforms[0]="ARM" |
| asm_Debug_cmdline="armasm -nologo -oldit "%(FullPath)"" |
| asm_Release_cmdline="armasm -nologo -oldit "%(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 |
| if [ $vs_ver -ge 12 ] && [ "${platforms[0]}" = "ARM" ]; then |
| tag_content AppContainerApplication true |
| # The application type can be one of "Windows Store", |
| # "Windows Phone" or "Windows Phone Silverlight". The |
| # actual value doesn't matter from the libaom point of view, |
| # since a static library built for one works on the others. |
| # The PlatformToolset field needs to be set in sync with this; |
| # for Windows Store and Windows Phone Silverlight it should be |
| # v120 while it should be v120_wp81 if the type is Windows Phone. |
| tag_content ApplicationType "Windows Store" |
| tag_content ApplicationTypeRevision 8.1 |
| fi |
| 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 |
| if [ "$vs_ver" = "11" ]; then |
| if [ "$plat" = "ARM" ]; then |
| # Setting the wp80 toolchain automatically sets the |
| # WINAPI_FAMILY define, which is required for building |
| # code for arm with the windows headers. Alternatively, |
| # one could add AppContainerApplication=true in the Globals |
| # section and add PrecompiledHeader=NotUsing and |
| # CompileAsWinRT=false in ClCompile and SubSystem=Console |
| # in Link. |
| tag_content PlatformToolset v110_wp80 |
| else |
| tag_content PlatformToolset v110 |
| fi |
| fi |
| if [ "$vs_ver" = "12" ]; then |
| # Setting a PlatformToolset indicating windows phone isn't |
| # enough to build code for arm with MSVC 2013, one strictly |
| # has to enable AppContainerApplication as well. |
| tag_content PlatformToolset v120 |
| fi |
| if [ "$vs_ver" = "14" ]; then |
| tag_content PlatformToolset v140 |
| fi |
| 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}\\" |
| if [ "$proj_kind" == "lib" ]; then |
| if [ "$config" == "Debug" ]; then |
| config_suffix=d |
| else |
| config_suffix="" |
| fi |
| tag_content TargetName "${name}${lib_sfx}${config_suffix}" |
| fi |
| 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 |
| hostplat=$plat |
| if [ "$hostplat" == "ARM" ]; then |
| hostplat=Win32 |
| fi |
| fi |
| open_tag ClCompile |
| if [ "$config" = "Debug" ]; then |
| opt=Disabled |
| runtime=$debug_runtime |
| curlibs=$debug_libs |
| debug=_DEBUG |
| else |
| opt=MaxSpeed |
| runtime=$release_runtime |
| curlibs=$libs |
| tag_content FavorSizeOrSpeed Speed |
| debug=NDEBUG |
| fi |
| extradefines=";$defines" |
| 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 |
| if ${werror:-false}; then |
| tag_content TreatWarningAsError true |
| fi |
| if [ $vs_ver -ge 11 ]; then |
| # We need to override the defaults for these settings |
| # if AppContainerApplication is set. |
| tag_content CompileAsWinRT false |
| tag_content PrecompiledHeader NotUsing |
| tag_content SDLCheck false |
| fi |
| close_tag ClCompile |
| case "$proj_kind" in |
| exe) |
| open_tag Link |
| tag_content GenerateDebugInformation true |
| # Console is the default normally, but if |
| # AppContainerApplication is set, we need to override it. |
| tag_content SubSystem Console |
| close_tag Link |
| ;; |
| dll) |
| open_tag Link |
| tag_content GenerateDebugInformation true |
| tag_content ModuleDefinitionFile $module_def |
| close_tag Link |
| ;; |
| lib) |
| ;; |
| esac |
| close_tag ItemDefinitionGroup |
| done |
| |
| done |
| |
| open_tag ItemGroup |
| generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s" |
| 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 |