123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- #!/usr/bin/tclsh
- #
- # This script is used to generate a VSIX (Visual Studio Extension) file for
- # SQLite usable by Visual Studio.
- #
- # PREREQUISITES
- #
- # 1. Tcl 8.4 and later are supported, earlier versions have not been tested.
- #
- # 2. The "sqlite3.h" file is assumed to exist in the parent directory of the
- # directory containing this script. The [optional] second command line
- # argument to this script may be used to specify an alternate location.
- # This script also assumes that the "sqlite3.h" file corresponds with the
- # version of the binaries to be packaged. This assumption is not verified
- # by this script.
- #
- # 3. The temporary directory specified in the TEMP or TMP environment variables
- # must refer to an existing directory writable by the current user.
- #
- # 4. The "zip" and "unzip" command line tools must be located either in a
- # directory contained in the PATH environment variable or specified as the
- # exact file names to execute in the "ZipTool" and "UnZipTool" environment
- # variables, respectively.
- #
- # 5. The template VSIX file (which is basically a zip file) must be located in
- # a "win" directory inside the directory containing this script. It should
- # not contain any executable binaries. It should only contain dynamic
- # textual content files to be processed using [subst] and/or static content
- # files to be copied verbatim.
- #
- # 6. The executable and other compiled binary files to be packaged into the
- # final VSIX file (e.g. DLLs, LIBs, and PDBs) must be located in a single
- # directory tree. The top-level directory of the tree must be specified as
- # the first command line argument to this script. The second level
- # sub-directory names must match those of the build configuration (e.g.
- # "Debug" or "Retail"). The third level sub-directory names must match
- # those of the platform (e.g. "x86", "x64", and "ARM"). For example, the
- # binary files to be packaged would need to be organized as follows when
- # packaging the "Debug" and "Retail" build configurations for the "x86" and
- # "x64" platforms (in this example, "C:\temp" is the top-level directory as
- # specified in the first command line argument):
- #
- # C:\Temp\Debug\x86\sqlite3.lib
- # C:\Temp\Debug\x86\sqlite3.dll
- # C:\Temp\Debug\x86\sqlite3.pdb
- # C:\Temp\Debug\x64\sqlite3.lib
- # C:\Temp\Debug\x64\sqlite3.dll
- # C:\Temp\Debug\x64\sqlite3.pdb
- # C:\Temp\Retail\x86\sqlite3.lib
- # C:\Temp\Retail\x86\sqlite3.dll
- # C:\Temp\Retail\x86\sqlite3.pdb
- # C:\Temp\Retail\x64\sqlite3.lib
- # C:\Temp\Retail\x64\sqlite3.dll
- # C:\Temp\Retail\x64\sqlite3.pdb
- #
- # The above directory tree organization is performed automatically if the
- # "tool\build-all-msvc.bat" batch script is used to build the binary files
- # to be packaged.
- #
- # USAGE
- #
- # The first argument to this script is required and must be the name of the
- # top-level directory containing the directories and files organized into a
- # tree as described in item 6 of the PREREQUISITES section, above. The second
- # argument is optional and if present must contain the name of the directory
- # containing the root of the source tree for SQLite. The third argument is
- # optional and if present must contain the flavor the VSIX package to build.
- # Currently, the only supported package flavors are "WinRT", "WinRT81", "WP80",
- # "WP81", and "Win32". The fourth argument is optional and if present must be
- # a string containing a list of platforms to include in the VSIX package. The
- # platform list is "platform1,platform2,platform3". The fifth argument is
- # optional and if present must contain the version of Visual Studio required by
- # the package. Currently, the only supported versions are "2012" and "2013".
- # The package flavors "WinRT81" and "WP81" are only supported when the Visual
- # Studio version is "2013". Typically, when on Windows, this script is
- # executed using commands similar to the following from a normal Windows
- # command prompt:
- #
- # CD /D C:\dev\sqlite\core
- # tclsh tool\mkvsix.tcl C:\Temp
- #
- # In the example above, "C:\dev\sqlite\core" represents the root of the source
- # tree for SQLite and "C:\Temp" represents the top-level directory containing
- # the executable and other compiled binary files, organized into a directory
- # tree as described in item 6 of the PREREQUISITES section, above.
- #
- # This script should work on non-Windows platforms as well, provided that all
- # the requirements listed in the PREREQUISITES section are met.
- #
- # NOTES
- #
- # The temporary directory is used as a staging area for the final VSIX file.
- # The template VSIX file is extracted, its contents processed, and then the
- # resulting files are packaged into the final VSIX file.
- #
- package require Tcl 8.4
- proc fail { {error ""} {usage false} } {
- if {[string length $error] > 0} then {
- puts stdout $error
- if {!$usage} then {exit 1}
- }
- puts stdout "usage:\
- [file tail [info nameofexecutable]]\
- [file tail [info script]] <binaryDirectory> \[sourceDirectory\]\
- \[packageFlavor\] \[platformNames\] \[vsVersion\]"
- exit 1
- }
- proc getEnvironmentVariable { name } {
- #
- # NOTE: Returns the value of the specified environment variable or an empty
- # string for environment variables that do not exist in the current
- # process environment.
- #
- return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
- }
- proc getTemporaryPath {} {
- #
- # NOTE: Returns the normalized path to the first temporary directory found
- # in the typical set of environment variables used for that purpose
- # or an empty string to signal a failure to locate such a directory.
- #
- set names [list]
- foreach name [list TEMP TMP] {
- lappend names [string toupper $name] [string tolower $name] \
- [string totitle $name]
- }
- foreach name $names {
- set value [getEnvironmentVariable $name]
- if {[string length $value] > 0} then {
- return [file normalize $value]
- }
- }
- return ""
- }
- proc appendArgs { args } {
- #
- # NOTE: Returns all passed arguments joined together as a single string with
- # no intervening spaces between arguments.
- #
- eval append result $args
- }
- proc readFile { fileName } {
- #
- # NOTE: Reads and returns the entire contents of the specified file, which
- # may contain binary data.
- #
- set file_id [open $fileName RDONLY]
- fconfigure $file_id -translation binary
- set result [read $file_id]
- close $file_id
- return $result
- }
- proc writeFile { fileName data } {
- #
- # NOTE: Writes the entire contents of the specified file, which may contain
- # binary data.
- #
- set file_id [open $fileName {WRONLY CREAT TRUNC}]
- fconfigure $file_id -translation binary
- puts -nonewline $file_id $data
- close $file_id
- return ""
- }
- #
- # TODO: Modify this procedure when a new version of Visual Studio is released.
- #
- proc getMinVsVersionXmlChunk { vsVersion } {
- switch -exact $vsVersion {
- 2012 {
- return [appendArgs \
- "\r\n " {MinVSVersion="11.0"}]
- }
- 2013 {
- return [appendArgs \
- "\r\n " {MinVSVersion="12.0"}]
- }
- 2015 {
- return [appendArgs \
- "\r\n " {MinVSVersion="14.0"}]
- }
- default {
- return ""
- }
- }
- }
- #
- # TODO: Modify this procedure when a new version of Visual Studio is released.
- #
- proc getMaxPlatformVersionXmlChunk { packageFlavor vsVersion } {
- #
- # NOTE: Only Visual Studio 2013 and later support this attribute within the
- # SDK manifest.
- #
- if {![string equal $vsVersion 2013] && \
- ![string equal $vsVersion 2015]} then {
- return ""
- }
- switch -exact $packageFlavor {
- WinRT {
- return [appendArgs \
- "\r\n " {MaxPlatformVersion="8.0"}]
- }
- WinRT81 {
- return [appendArgs \
- "\r\n " {MaxPlatformVersion="8.1"}]
- }
- WP80 {
- return [appendArgs \
- "\r\n " {MaxPlatformVersion="8.0"}]
- }
- WP81 {
- return [appendArgs \
- "\r\n " {MaxPlatformVersion="8.1"}]
- }
- default {
- return ""
- }
- }
- }
- #
- # TODO: Modify this procedure when a new version of Visual Studio is released.
- #
- proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
- #
- # NOTE: Windows Phone 8.0 does not require any extra attributes in its VSIX
- # package SDK manifests; however, it appears that Windows Phone 8.1
- # does.
- #
- if {[string equal $packageFlavor WP80]} then {
- return ""
- }
- set appliesTo [expr {[string equal $packageFlavor Win32] ? \
- "VisualC" : "WindowsAppContainer"}]
- switch -exact $vsVersion {
- 2012 {
- return [appendArgs \
- "\r\n " AppliesTo=\" $appliesTo \" \
- "\r\n " {DependsOn="Microsoft.VCLibs, version=11.0"}]
- }
- 2013 {
- return [appendArgs \
- "\r\n " AppliesTo=\" $appliesTo \" \
- "\r\n " {DependsOn="Microsoft.VCLibs, version=12.0"}]
- }
- 2015 {
- return [appendArgs \
- "\r\n " AppliesTo=\" $appliesTo \" \
- "\r\n " {DependsOn="Microsoft.VCLibs, version=14.0"}]
- }
- default {
- return ""
- }
- }
- }
- proc replaceFileNameTokens { fileName name buildName platformName } {
- #
- # NOTE: Returns the specified file name containing the platform name instead
- # of platform placeholder tokens.
- #
- return [string map [list <build> $buildName <platform> $platformName \
- <name> $name] $fileName]
- }
- proc substFile { fileName } {
- #
- # NOTE: Performs all Tcl command, variable, and backslash substitutions in
- # the specified file and then rewrites the contents of that same file
- # with the substituted data.
- #
- return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
- }
- #
- # NOTE: This is the entry point for this script.
- #
- set script [file normalize [info script]]
- if {[string length $script] == 0} then {
- fail "script file currently being evaluated is unknown" true
- }
- set path [file dirname $script]
- set rootName [file rootname [file tail $script]]
- ###############################################################################
- #
- # NOTE: Process and verify all the command line arguments.
- #
- set argc [llength $argv]
- if {$argc < 1 || $argc > 5} then {fail}
- set binaryDirectory [lindex $argv 0]
- if {[string length $binaryDirectory] == 0} then {
- fail "invalid binary directory"
- }
- if {![file exists $binaryDirectory] || \
- ![file isdirectory $binaryDirectory]} then {
- fail "binary directory does not exist"
- }
- if {$argc >= 2} then {
- set sourceDirectory [lindex $argv 1]
- } else {
- #
- # NOTE: Assume that the source directory is the parent directory of the one
- # that contains this script file.
- #
- set sourceDirectory [file dirname $path]
- }
- if {[string length $sourceDirectory] == 0} then {
- fail "invalid source directory"
- }
- if {![file exists $sourceDirectory] || \
- ![file isdirectory $sourceDirectory]} then {
- fail "source directory does not exist"
- }
- if {$argc >= 3} then {
- set packageFlavor [lindex $argv 2]
- } else {
- #
- # NOTE: Assume the package flavor is WinRT.
- #
- set packageFlavor WinRT
- }
- if {[string length $packageFlavor] == 0} then {
- fail "invalid package flavor"
- }
- if {$argc >= 4} then {
- set platformNames [list]
- foreach platformName [split [lindex $argv 3] ", "] {
- set platformName [string trim $platformName]
- if {[string length $platformName] > 0} then {
- lappend platformNames $platformName
- }
- }
- }
- if {$argc >= 5} then {
- set vsVersion [lindex $argv 4]
- } else {
- set vsVersion 2012
- }
- if {[string length $vsVersion] == 0} then {
- fail "invalid Visual Studio version"
- }
- if {![string equal $vsVersion 2012] && ![string equal $vsVersion 2013] && \
- ![string equal $vsVersion 2015]} then {
- fail [appendArgs \
- "unsupported Visual Studio version, must be one of: " \
- [list 2012 2013 2015]]
- }
- set shortNames(WinRT,2012) SQLite.WinRT
- set shortNames(WinRT,2013) SQLite.WinRT.2013
- set shortNames(WinRT81,2013) SQLite.WinRT81
- set shortNames(WP80,2012) SQLite.WP80
- set shortNames(WP80,2013) SQLite.WP80.2013
- set shortNames(WP81,2013) SQLite.WP81
- set shortNames(Win32,2012) SQLite.Win32
- set shortNames(Win32,2013) SQLite.Win32.2013
- set shortNames(UWP,2015) SQLite.UWP.2015
- set displayNames(WinRT,2012) "SQLite for Windows Runtime"
- set displayNames(WinRT,2013) "SQLite for Windows Runtime"
- set displayNames(WinRT81,2013) "SQLite for Windows Runtime (Windows 8.1)"
- set displayNames(WP80,2012) "SQLite for Windows Phone"
- set displayNames(WP80,2013) "SQLite for Windows Phone"
- set displayNames(WP81,2013) "SQLite for Windows Phone 8.1"
- set displayNames(Win32,2012) "SQLite for Windows"
- set displayNames(Win32,2013) "SQLite for Windows"
- set displayNames(UWP,2015) "SQLite for Universal Windows Platform"
- if {[string equal $packageFlavor WinRT]} then {
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier Windows
- set targetPlatformVersion v8.0
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath ""
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } elseif {[string equal $packageFlavor WinRT81]} then {
- if {$vsVersion ne "2013"} then {
- fail [appendArgs \
- "unsupported combination, package flavor " $packageFlavor \
- " is only supported with Visual Studio 2013"]
- }
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier Windows
- set targetPlatformVersion v8.1
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath ""
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } elseif {[string equal $packageFlavor WP80]} then {
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier "Windows Phone"
- set targetPlatformVersion v8.0
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath "\\..\\$targetPlatformIdentifier"
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } elseif {[string equal $packageFlavor WP81]} then {
- if {$vsVersion ne "2013"} then {
- fail [appendArgs \
- "unsupported combination, package flavor " $packageFlavor \
- " is only supported with Visual Studio 2013"]
- }
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier WindowsPhoneApp
- set targetPlatformVersion v8.1
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath "\\..\\$targetPlatformIdentifier"
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } elseif {[string equal $packageFlavor UWP]} then {
- if {$vsVersion ne "2015"} then {
- fail [appendArgs \
- "unsupported combination, package flavor " $packageFlavor \
- " is only supported with Visual Studio 2015"]
- }
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier UAP; # NOTE: Not "UWP".
- set targetPlatformVersion v0.8.0.0
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath "\\..\\$targetPlatformIdentifier"
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } elseif {[string equal $packageFlavor Win32]} then {
- set shortName $shortNames($packageFlavor,$vsVersion)
- set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier Windows
- set targetPlatformVersion v8.0
- set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
- set maxPlatformVersion \
- [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
- set extraSdkPath ""
- set extraFileListAttributes \
- [getExtraFileListXmlChunk $packageFlavor $vsVersion]
- } else {
- fail [appendArgs \
- "unsupported package flavor, must be one of: " \
- [list WinRT WinRT81 WP80 WP81 UWP Win32]]
- }
- ###############################################################################
- #
- # NOTE: Evaluate the user-specific customizations file, if it exists.
- #
- set userFile [file join $path [appendArgs \
- $rootName . $tcl_platform(user) .tcl]]
- if {[file exists $userFile] && \
- [file isfile $userFile]} then {
- source $userFile
- }
- ###############################################################################
- set templateFile [file join $path win sqlite.vsix]
- if {![file exists $templateFile] || \
- ![file isfile $templateFile]} then {
- fail [appendArgs "template file \"" $templateFile "\" does not exist"]
- }
- set currentDirectory [pwd]
- set outputFile [file join $currentDirectory [appendArgs sqlite- \
- $packageFlavor -output.vsix]]
- if {[file exists $outputFile]} then {
- fail [appendArgs "output file \"" $outputFile "\" already exists"]
- }
- ###############################################################################
- #
- # NOTE: Make sure that a valid temporary directory exists.
- #
- set temporaryDirectory [getTemporaryPath]
- if {[string length $temporaryDirectory] == 0 || \
- ![file exists $temporaryDirectory] || \
- ![file isdirectory $temporaryDirectory]} then {
- fail "cannot locate a usable temporary directory"
- }
- #
- # NOTE: Setup the staging directory to have a unique name inside of the
- # configured temporary directory.
- #
- set stagingDirectory [file normalize [file join $temporaryDirectory \
- [appendArgs $rootName . [pid]]]]
- ###############################################################################
- #
- # NOTE: Configure the external zipping tool. First, see if it has already
- # been pre-configured. If not, try to query it from the environment.
- # Finally, fallback on the default of simply "zip", which will then
- # be assumed to exist somewhere along the PATH.
- #
- if {![info exists zip]} then {
- if {[info exists env(ZipTool)]} then {
- set zip $env(ZipTool)
- }
- if {![info exists zip] || ![file exists $zip]} then {
- set zip zip
- }
- }
- #
- # NOTE: Configure the external unzipping tool. First, see if it has already
- # been pre-configured. If not, try to query it from the environment.
- # Finally, fallback on the default of simply "unzip", which will then
- # be assumed to exist somewhere along the PATH.
- #
- if {![info exists unzip]} then {
- if {[info exists env(UnZipTool)]} then {
- set unzip $env(UnZipTool)
- }
- if {![info exists unzip] || ![file exists $unzip]} then {
- set unzip unzip
- }
- }
- ###############################################################################
- #
- # NOTE: Attempt to extract the SQLite version from the "sqlite3.h" header file
- # in the source directory. This script assumes that the header file has
- # already been generated by the build process.
- #
- set pattern {^#define\s+SQLITE_VERSION\s+"(.*)"$}
- set data [readFile [file join $sourceDirectory sqlite3.h]]
- if {![regexp -line -- $pattern $data dummy version]} then {
- fail [appendArgs "cannot locate SQLITE_VERSION value in \"" \
- [file join $sourceDirectory sqlite3.h] \"]
- }
- ###############################################################################
- #
- # NOTE: Setup all the master file list data. This includes the source file
- # names, the destination file names, and the file processing flags. The
- # possible file processing flags are:
- #
- # "buildNeutral" -- This flag indicates the file location and content do
- # not depend on the build configuration.
- #
- # "platformNeutral" -- This flag indicates the file location and content
- # do not depend on the build platform.
- #
- # "subst" -- This flag indicates that the file contains dynamic textual
- # content that needs to be processed using [subst] prior to
- # packaging the file into the final VSIX package. The primary
- # use of this flag is to insert the name of the VSIX package,
- # some package flavor-specific value, or the SQLite version
- # into a file.
- #
- # "noDebug" -- This flag indicates that the file should be skipped when
- # processing the debug build.
- #
- # "noRetail" -- This flag indicates that the file should be skipped when
- # processing the retail build.
- #
- # "move" -- This flag indicates that the file should be moved from the
- # source to the destination instead of being copied.
- #
- # This file metadata may be overridden, either in whole or in part, via
- # the user-specific customizations file.
- #
- if {![info exists fileNames(source)]} then {
- set fileNames(source) [list "" "" \
- [file join $stagingDirectory DesignTime <build> <platform> sqlite3.props] \
- [file join $sourceDirectory sqlite3.h] \
- [file join $binaryDirectory <build> <platform> sqlite3.lib] \
- [file join $binaryDirectory <build> <platform> sqlite3.dll]]
- if {![info exists no(symbols)]} then {
- lappend fileNames(source) \
- [file join $binaryDirectory <build> <platform> sqlite3.pdb]
- }
- }
- if {![info exists fileNames(destination)]} then {
- set fileNames(destination) [list \
- [file join $stagingDirectory extension.vsixmanifest] \
- [file join $stagingDirectory SDKManifest.xml] \
- [file join $stagingDirectory DesignTime <build> <platform> <name>.props] \
- [file join $stagingDirectory DesignTime <build> <platform> sqlite3.h] \
- [file join $stagingDirectory DesignTime <build> <platform> sqlite3.lib] \
- [file join $stagingDirectory Redist <build> <platform> sqlite3.dll]]
- if {![info exists no(symbols)]} then {
- lappend fileNames(destination) \
- [file join $stagingDirectory Redist <build> <platform> sqlite3.pdb]
- }
- }
- if {![info exists fileNames(flags)]} then {
- set fileNames(flags) [list \
- [list buildNeutral platformNeutral subst] \
- [list buildNeutral platformNeutral subst] \
- [list buildNeutral platformNeutral subst move] \
- [list buildNeutral platformNeutral] \
- [list] [list] [list noRetail]]
- if {![info exists no(symbols)]} then {
- lappend fileNames(flags) [list noRetail]
- }
- }
- ###############################################################################
- #
- # NOTE: Setup the list of builds supported by this script. These may be
- # overridden via the user-specific customizations file.
- #
- if {![info exists buildNames]} then {
- set buildNames [list Debug Retail]
- }
- ###############################################################################
- #
- # NOTE: Setup the list of platforms supported by this script. These may be
- # overridden via the command line or the user-specific customizations
- # file.
- #
- if {![info exists platformNames] || [llength $platformNames] == 0} then {
- set platformNames [list x86 x64 ARM]
- }
- ###############################################################################
- #
- # NOTE: Make sure the staging directory exists, creating it if necessary.
- #
- file mkdir $stagingDirectory
- #
- # NOTE: Build the Tcl command used to extract the template VSIX package to
- # the staging directory.
- #
- set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
- #
- # NOTE: Extract the template VSIX package to the staging directory.
- #
- eval $extractCommand
- ###############################################################################
- #
- # NOTE: Process each file in the master file list. There are actually three
- # parallel lists that contain the source file names, the destination file
- # names, and the file processing flags. If the "buildNeutral" flag is
- # present, the file location and content do not depend on the build
- # configuration and "CommonConfiguration" will be used in place of the
- # build configuration name. If the "platformNeutral" flag is present,
- # the file location and content do not depend on the build platform and
- # "neutral" will be used in place of the build platform name. If the
- # "subst" flag is present, the file is assumed to be a text file that may
- # contain Tcl variable, command, and backslash replacements, to be
- # dynamically replaced during processing using the Tcl [subst] command.
- # If the "noDebug" flag is present, the file will be skipped when
- # processing for the debug build. If the "noRetail" flag is present, the
- # file will be skipped when processing for the retail build. If the
- # "move" flag is present, the source file will be deleted after it is
- # copied to the destination file. If the source file name is an empty
- # string, the destination file name will be assumed to already exist in
- # the staging directory and will not be copied; however, Tcl variable,
- # command, and backslash replacements may still be performed on the
- # destination file prior to the final VSIX package being built if the
- # "subst" flag is present.
- #
- foreach sourceFileName $fileNames(source) \
- destinationFileName $fileNames(destination) \
- fileFlags $fileNames(flags) {
- #
- # NOTE: Process the file flags into separate boolean variables that may be
- # used within the loop.
- #
- set isBuildNeutral [expr {[lsearch $fileFlags buildNeutral] != -1}]
- set isPlatformNeutral [expr {[lsearch $fileFlags platformNeutral] != -1}]
- set isMove [expr {[lsearch $fileFlags move] != -1}]
- set useSubst [expr {[lsearch $fileFlags subst] != -1}]
- #
- # NOTE: If the current file is build-neutral, then only one build will
- # be processed for it, namely "CommonConfiguration"; otherwise, each
- # supported build will be processed for it individually.
- #
- foreach buildName \
- [expr {$isBuildNeutral ? [list CommonConfiguration] : $buildNames}] {
- #
- # NOTE: Should the current file be skipped for this build?
- #
- if {[lsearch $fileFlags no${buildName}] != -1} then {
- continue
- }
- #
- # NOTE: If the current file is platform-neutral, then only one platform
- # will be processed for it, namely "neutral"; otherwise, each
- # supported platform will be processed for it individually.
- #
- foreach platformName \
- [expr {$isPlatformNeutral ? [list neutral] : $platformNames}] {
- #
- # NOTE: Use the actual platform name in the destination file name.
- #
- set newDestinationFileName [replaceFileNameTokens $destinationFileName \
- $shortName $buildName $platformName]
- #
- # NOTE: Does the source file need to be copied to the destination file?
- #
- if {[string length $sourceFileName] > 0} then {
- #
- # NOTE: First, make sure the destination directory exists.
- #
- file mkdir [file dirname $newDestinationFileName]
- #
- # NOTE: Then, copy the source file to the destination file verbatim.
- #
- set newSourceFileName [replaceFileNameTokens $sourceFileName \
- $shortName $buildName $platformName]
- file copy $newSourceFileName $newDestinationFileName
- #
- # NOTE: If this is a move instead of a copy, delete the source file
- # now.
- #
- if {$isMove} then {
- file delete $newSourceFileName
- }
- }
- #
- # NOTE: Does the destination file contain dynamic replacements that must
- # be processed now?
- #
- if {$useSubst} then {
- #
- # NOTE: Perform any dynamic replacements contained in the destination
- # file and then re-write it in-place.
- #
- substFile $newDestinationFileName
- }
- }
- }
- }
- ###############################################################################
- #
- # NOTE: Change the current directory to the staging directory so that the
- # external archive building tool can pickup the necessary files using
- # relative paths.
- #
- cd $stagingDirectory
- #
- # NOTE: Build the Tcl command used to archive the final VSIX package in the
- # output directory.
- #
- set archiveCommand [list exec -- $zip -r $outputFile *]
- #
- # NOTE: Build the final VSIX package archive in the output directory.
- #
- eval $archiveCommand
- #
- # NOTE: Change back to the previously saved current directory.
- #
- cd $currentDirectory
- #
- # NOTE: Cleanup the temporary staging directory.
- #
- file delete -force $stagingDirectory
- ###############################################################################
- #
- # NOTE: Success, emit the fully qualified path of the generated VSIX file.
- #
- puts stdout $outputFile
|