Add a new script for producing vcxproj files
Change-Id: If02a7b85f417b9693dcdab73573fc13f67e17016
This commit is contained in:
506
build/make/gen_msvs_vcxproj.sh
Executable file
506
build/make/gen_msvs_vcxproj.sh
Executable file
@@ -0,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
|
||||
Reference in New Issue
Block a user