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 12 13self=$0 14self_basename=${self##*/} 15EOL=$'\n' 16EOLDOS=$'\r' 17 18show_help() { 19 cat <<EOF 20Usage: ${self_basename} [options] file1 [file2 ...] 21 22This script generates a Visual Studio solution file from a list of project 23files. 24 25Options: 26 --help Print this message 27 --out=outfile Redirect output to a file 28 --ver=version Version (7,8,9,10,11,12,14,15) of visual studio to generate for 29 --target=isa-os-cc Target specifier 30EOF 31 exit 1 32} 33 34die() { 35 echo "${self_basename}: $@" >&2 36 [ -f "${outfile}" ] && rm -f ${outfile}{,.mk} 37 exit 1 38} 39 40die_unknown(){ 41 echo "Unknown option \"$1\"." >&2 42 echo "See ${self_basename} --help for available options." >&2 43 [ -f "${outfile}" ] && rm -f ${outfile}{,.mk} 44 exit 1 45} 46 47indent1=$'\t' 48indent="" 49indent_push() { 50 indent="${indent}${indent1}" 51} 52indent_pop() { 53 indent="${indent%${indent1}}" 54} 55 56parse_project() { 57 local file=$1 58 local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` 59 local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` 60 61 # save the project GUID to a varaible, normalizing to the basename of the 62 # vcxproj file without the extension 63 local var 64 var=${file##*/} 65 var=${var%%.${sfx}} 66 eval "${var}_file=\"$1\"" 67 eval "${var}_name=$name" 68 eval "${var}_guid=$guid" 69 70 cur_config_list=`grep -B1 'Label="Configuration"' $file | 71 grep Condition | cut -d\' -f4` 72 new_config_list=$(for i in $config_list $cur_config_list; do 73 echo $i 74 done | sort | uniq) 75 if [ "$config_list" != "" ] && [ "$config_list" != "$new_config_list" ]; then 76 mixed_platforms=1 77 fi 78 config_list="$new_config_list" 79 eval "${var}_config_list=\"$cur_config_list\"" 80 proj_list="${proj_list} ${var}" 81} 82 83process_project() { 84 eval "local file=\${$1_file}" 85 eval "local name=\${$1_name}" 86 eval "local guid=\${$1_guid}" 87 88 # save the project GUID to a varaible, normalizing to the basename of the 89 # vcproj file without the extension 90 local var 91 var=${file##*/} 92 var=${var%%.${sfx}} 93 eval "${var}_guid=$guid" 94 95 echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\"" 96 echo "EndProject" 97} 98 99process_global() { 100 echo "Global" 101 indent_push 102 103 # 104 # Solution Configuration Platforms 105 # 106 echo "${indent}GlobalSection(SolutionConfigurationPlatforms) = preSolution" 107 indent_push 108 IFS_bak=${IFS} 109 IFS=$'\r'$'\n' 110 if [ "$mixed_platforms" != "" ]; then 111 config_list=" 112Release|Mixed Platforms 113Debug|Mixed Platforms" 114 fi 115 for config in ${config_list}; do 116 echo "${indent}$config = $config" 117 done 118 IFS=${IFS_bak} 119 indent_pop 120 echo "${indent}EndGlobalSection" 121 122 # 123 # Project Configuration Platforms 124 # 125 echo "${indent}GlobalSection(ProjectConfigurationPlatforms) = postSolution" 126 indent_push 127 for proj in ${proj_list}; do 128 eval "local proj_guid=\${${proj}_guid}" 129 eval "local proj_config_list=\${${proj}_config_list}" 130 IFS=$'\r'$'\n' 131 for config in ${proj_config_list}; do 132 if [ "$mixed_platforms" != "" ]; then 133 local c=${config%%|*} 134 echo "${indent}${proj_guid}.${c}|Mixed Platforms.ActiveCfg = ${config}" 135 echo "${indent}${proj_guid}.${c}|Mixed Platforms.Build.0 = ${config}" 136 else 137 echo "${indent}${proj_guid}.${config}.ActiveCfg = ${config}" 138 echo "${indent}${proj_guid}.${config}.Build.0 = ${config}" 139 fi 140 141 done 142 IFS=${IFS_bak} 143 done 144 indent_pop 145 echo "${indent}EndGlobalSection" 146 147 # 148 # Solution Properties 149 # 150 echo "${indent}GlobalSection(SolutionProperties) = preSolution" 151 indent_push 152 echo "${indent}HideSolutionNode = FALSE" 153 indent_pop 154 echo "${indent}EndGlobalSection" 155 156 indent_pop 157 echo "EndGlobal" 158} 159 160process_makefile() { 161 IFS_bak=${IFS} 162 IFS=$'\r'$'\n' 163 local TAB=$'\t' 164 cat <<EOF 165MSBUILD_TOOL := msbuild.exe 166found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes) 167.nodevenv.once: 168${TAB}@echo " * \$(MSBUILD_TOOL) not found in path." 169${TAB}@echo " * " 170${TAB}@echo " * You will have to build all configurations manually using the" 171${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically," 172${TAB}@echo " * add the Common7/IDE directory of your Visual Studio" 173${TAB}@echo " * installation to your path, eg:" 174${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE" 175${TAB}@echo " * " 176${TAB}@touch \$@ 177CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once) 178 179EOF 180 181 for sln_config in ${config_list}; do 182 local config=${sln_config%%|*} 183 local platform=${sln_config##*|} 184 local nows_sln_config=`echo $sln_config | sed -e 's/[^a-zA-Z0-9]/_/g'` 185 cat <<EOF 186BUILD_TARGETS += \$(if \$(NO_LAUNCH_DEVENV),,$nows_sln_config) 187clean:: 188${TAB}rm -rf "$platform"/"$config" 189.PHONY: $nows_sln_config 190ifneq (\$(found_devenv),) 191$nows_sln_config: $outfile 192${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\ 193${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform" 194else 195$nows_sln_config: $outfile .nodevenv.once 196${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)." 197${TAB}@echo " * " 198endif 199 200EOF 201 done 202 IFS=${IFS_bak} 203} 204 205# Process command line 206outfile=/dev/stdout 207for opt in "$@"; do 208 optval="${opt#*=}" 209 case "$opt" in 210 --help|-h) show_help 211 ;; 212 --out=*) outfile="${optval}"; mkoutfile="${optval}".mk 213 ;; 214 --dep=*) eval "${optval%%:*}_deps=\"\${${optval%%:*}_deps} ${optval##*:}\"" 215 ;; 216 --ver=*) vs_ver="$optval" 217 case $optval in 218 10|11|12|14|15) 219 ;; 220 *) die Unrecognized Visual Studio Version in $opt 221 ;; 222 esac 223 ;; 224 --target=*) target="${optval}" 225 ;; 226 -*) die_unknown $opt 227 ;; 228 *) file_list[${#file_list[@]}]="$opt" 229 esac 230done 231outfile=${outfile:-/dev/stdout} 232mkoutfile=${mkoutfile:-/dev/stdout} 233case "${vs_ver:-10}" in 234 10) sln_vers="11.00" 235 sln_vers_str="Visual Studio 2010" 236 ;; 237 11) sln_vers="12.00" 238 sln_vers_str="Visual Studio 2012" 239 ;; 240 12) sln_vers="12.00" 241 sln_vers_str="Visual Studio 2013" 242 ;; 243 14) sln_vers="12.00" 244 sln_vers_str="Visual Studio 2015" 245 ;; 246 15) sln_vers="12.00" 247 sln_vers_str="Visual Studio 2017" 248 ;; 249esac 250sfx=vcxproj 251 252for f in "${file_list[@]}"; do 253 parse_project $f 254done 255cat >${outfile} <<EOF 256Microsoft Visual Studio Solution File, Format Version $sln_vers${EOLDOS} 257# $sln_vers_str${EOLDOS} 258EOF 259for proj in ${proj_list}; do 260 process_project $proj >>${outfile} 261done 262process_global >>${outfile} 263process_makefile >${mkoutfile} 264