2012-07-27 02:36:06 +00:00
# !/usr/bin/tclsh
#
# This script is used to generate a VSIX (Visual Studio Extension) file for
# SQLite usable by Visual Studio.
2012-10-19 00:23:31 +00:00
#
# 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
#
2012-10-20 08:40:05 +00:00
# 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.
2014-05-06 21:26:34 +00:00
# Currently, the only supported package flavors are "WinRT", "WinRT81", "WP80",
2014-05-06 21:30:25 +00:00
# "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
2014-05-06 00:09:46 +00:00
# command prompt:
2012-10-19 00:23:31 +00:00
#
# CD /D C:\dev\sqlite\core
2016-11-03 21:35:10 +00:00
# tclsh tool\mkvsix.tcl C:\Temp
2012-10-19 00:23:31 +00:00
#
# 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
2012-07-27 02:36:06 +00:00
proc fail { { error " " } { usage false} } {
if { [ string length $error ] > 0 } then {
puts stdout $error
if { ! $usage } then { exit 1 }
}
puts stdout " u s a g e : \
[ file tail [ info nameofexecutable] ] \
2012-10-20 08:40:05 +00:00
[ file tail [ info script] ] < binaryDirectory > \ [ sourceDirectory \ ] \
2014-05-06 00:09:46 +00:00
\ [ packageFlavor \ ] \ [ platformNames \ ] \ [ vsVersion \ ] "
2012-07-27 02:36:06 +00:00
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 - encoding binary - 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 - encoding binary - translation binary
puts - nonewline $file_id $data
close $file_id
return " "
}
2015-04-19 23:39:05 +00:00
#
# TODO: Modify this procedure when a new version of Visual Studio is released.
#
2014-05-06 00:09:46 +00:00
proc getMinVsVersionXmlChunk { vsVersion } {
switch - exact $vsVersion {
2012 {
return [ appendArgs \
" \r \n " { MinVSVersion = " 1 1 . 0 " } ]
}
2013 {
return [ appendArgs \
" \r \n " { MinVSVersion = " 1 2 . 0 " } ]
}
2015-04-19 23:39:05 +00:00
2015 {
return [ appendArgs \
" \r \n " { MinVSVersion = " 1 4 . 0 " } ]
}
2014-05-06 00:09:46 +00:00
default {
return " "
}
}
}
2015-04-19 23:39:05 +00:00
#
# TODO: Modify this procedure when a new version of Visual Studio is released.
#
2014-05-10 17:28:45 +00:00
proc getMaxPlatformVersionXmlChunk { packageFlavor vsVersion } {
#
2015-04-19 23:39:05 +00:00
# NOTE: Only Visual Studio 2013 and later support this attribute within the
# SDK manifest.
2014-05-10 17:28:45 +00:00
#
2015-04-19 23:39:05 +00:00
if { ! [ string equal $vsVersion 2013 ] && \
! [ string equal $vsVersion 2015 ] } then {
2014-05-10 17:28:45 +00:00
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 " } ]
}
2014-05-10 17:33:11 +00:00
WP81 {
return [ appendArgs \
" \r \n " { MaxPlatformVersion = " 8 . 1 " } ]
}
2014-05-10 17:28:45 +00:00
default {
return " "
}
}
}
2015-04-19 23:39:05 +00:00
#
# TODO: Modify this procedure when a new version of Visual Studio is released.
#
2014-05-06 00:09:46 +00:00
proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
2012-07-27 02:36:06 +00:00
#
2014-05-06 21:26:34 +00:00
# NOTE: Windows Phone 8.0 does not require any extra attributes in its VSIX
2014-05-10 17:33:11 +00:00
# package SDK manifests; however, it appears that Windows Phone 8.1
# does.
2012-07-27 02:36:06 +00:00
#
2014-05-06 21:26:34 +00:00
if { [ string equal $packageFlavor WP80] } then {
2014-05-06 00:09:46 +00:00
return " "
}
set appliesTo [ expr { [ string equal $packageFlavor Win32] ? \
" V i s u a l C " : " W i n d o w s A p p C o n t a i n e r " } ]
switch - exact $vsVersion {
2012 {
return [ appendArgs \
" \r \n " AppliesTo = \ " $ a p p l i e s T o \" \
" \r \n " { DependsOn = " M i c r o s o f t . V C L i b s , v e r s i o n = 1 1 . 0 " } ]
}
2013 {
return [ appendArgs \
" \r \n " AppliesTo = \ " $ a p p l i e s T o \" \
" \r \n " { DependsOn = " M i c r o s o f t . V C L i b s , v e r s i o n = 1 2 . 0 " } ]
}
2015-04-19 23:39:05 +00:00
2015 {
return [ appendArgs \
" \r \n " AppliesTo = \ " $ a p p l i e s T o \" \
2015-07-31 15:14:14 +00:00
" \r \n " { DependsOn = " M i c r o s o f t . V C L i b s , v e r s i o n = 1 4 . 0 " } ]
2015-04-19 23:39:05 +00:00
}
2014-05-06 00:09:46 +00:00
default {
return " "
}
}
2012-07-27 02:36:06 +00:00
}
2012-10-20 08:40:05 +00:00
proc replaceFileNameTokens { fileName name buildName platformName } {
2012-07-27 02:36:06 +00:00
#
# NOTE: Returns the specified file name containing the platform name instead
# of platform placeholder tokens.
#
2012-10-20 08:40:05 +00:00
return [ string map [ list < build> $buildName < platform> $platformName \
< name > $name ] $fileName ]
2012-07-27 02:36:06 +00:00
}
2014-05-06 00:09:46 +00:00
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 ] ] ] ]
}
2012-10-20 08:40:05 +00:00
#
# NOTE: This is the entry point for this script.
#
2012-07-27 02:36:06 +00:00
set script [ file normalize [ info script] ]
if { [ string length $script ] == 0 } then {
fail " s c r i p t f i l e c u r r e n t l y b e i n g e v a l u a t e d i s u n k n o w n " 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 ]
2014-05-06 00:09:46 +00:00
if { $argc < 1 || $argc > 5 } then { fail }
2012-07-27 02:36:06 +00:00
set binaryDirectory [ lindex $argv 0 ]
if { [ string length $binaryDirectory ] == 0 } then {
fail " i n v a l i d b i n a r y d i r e c t o r y "
}
if { ! [ file exists $binaryDirectory ] || \
! [ file isdirectory $binaryDirectory ] } then {
fail " b i n a r y d i r e c t o r y d o e s n o t e x i s t "
}
2012-10-20 08:40:05 +00:00
if { $argc >= 2 } then {
2012-07-27 02:36:06 +00:00
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 " i n v a l i d s o u r c e d i r e c t o r y "
}
if { ! [ file exists $sourceDirectory ] || \
! [ file isdirectory $sourceDirectory ] } then {
fail " s o u r c e d i r e c t o r y d o e s n o t e x i s t "
}
2012-10-20 08:40:05 +00:00
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 " i n v a l i d p a c k a g e f l a v o r "
}
2014-05-06 00:09:46 +00:00
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 " i n v a l i d V i s u a l S t u d i o v e r s i o n "
}
2015-04-19 23:39:05 +00:00
if { ! [ string equal $vsVersion 2012 ] && ! [ string equal $vsVersion 2013 ] && \
! [ string equal $vsVersion 2015 ] } then {
2014-05-06 00:09:46 +00:00
fail [ appendArgs \
" u n s u p p o r t e d V i s u a l S t u d i o v e r s i o n , m u s t b e o n e o f : " \
2015-04-19 23:39:05 +00:00
[ list 2012 2013 2015 ] ]
2014-05-06 00:09:46 +00:00
}
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
2016-02-12 05:19:29 +00:00
set shortNames( UWP , 2015 ) SQLite.UWP.2015
2014-05-06 00:09:46 +00:00
set displayNames( WinRT , 2012 ) " S Q L i t e f o r W i n d o w s R u n t i m e "
set displayNames( WinRT , 2013 ) " S Q L i t e f o r W i n d o w s R u n t i m e "
set displayNames( WinRT81 , 2013 ) " S Q L i t e f o r W i n d o w s R u n t i m e ( W i n d o w s 8 . 1 ) "
set displayNames( WP80 , 2012 ) " S Q L i t e f o r W i n d o w s P h o n e "
set displayNames( WP80 , 2013 ) " S Q L i t e f o r W i n d o w s P h o n e "
set displayNames( WP81 , 2013 ) " S Q L i t e f o r W i n d o w s P h o n e 8 . 1 "
set displayNames( Win32 , 2012 ) " S Q L i t e f o r W i n d o w s "
set displayNames( Win32 , 2013 ) " S Q L i t e f o r W i n d o w s "
2016-02-12 05:19:29 +00:00
set displayNames( UWP , 2015 ) " S Q L i t e f o r U n i v e r s a l W i n d o w s P l a t f o r m "
2014-05-06 00:09:46 +00:00
if { [ string equal $packageFlavor WinRT] } then {
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
2014-04-21 18:00:11 +00:00
set targetPlatformIdentifier Windows
set targetPlatformVersion v8.0
2014-05-06 00:09:46 +00:00
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
2014-05-10 17:28:45 +00:00
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
2014-04-21 18:00:11 +00:00
set extraSdkPath " "
2014-05-06 00:09:46 +00:00
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
} elseif { [ string equal $packageFlavor WinRT81] } then {
if { $vsVersion ne " 2 0 1 3 " } then {
fail [ appendArgs \
" u n s u p p o r t e d c o m b i n a t i o n , p a c k a g e f l a v o r " $packageFlavor \
" i s o n l y s u p p o r t e d w i t h V i s u a l S t u d i o 2 0 1 3 " ]
}
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
2013-06-20 18:53:33 +00:00
set targetPlatformIdentifier Windows
set targetPlatformVersion v8.1
2014-05-06 00:09:46 +00:00
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
2014-05-10 17:28:45 +00:00
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
2013-06-20 18:53:33 +00:00
set extraSdkPath " "
2014-05-06 00:09:46 +00:00
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
} elseif { [ string equal $packageFlavor WP80] } then {
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
2014-04-21 18:00:11 +00:00
set targetPlatformIdentifier " W i n d o w s P h o n e "
set targetPlatformVersion v8.0
2014-05-06 00:09:46 +00:00
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
2014-05-10 17:28:45 +00:00
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
2014-04-21 18:00:11 +00:00
set extraSdkPath " \\ . . \\ $ t a r g e t P l a t f o r m I d e n t i f i e r "
2014-05-06 00:09:46 +00:00
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
} elseif { [ string equal $packageFlavor WP81] } then {
if { $vsVersion ne " 2 0 1 3 " } then {
fail [ appendArgs \
" u n s u p p o r t e d c o m b i n a t i o n , p a c k a g e f l a v o r " $packageFlavor \
" i s o n l y s u p p o r t e d w i t h V i s u a l S t u d i o 2 0 1 3 " ]
}
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
set targetPlatformIdentifier WindowsPhoneApp
2014-04-18 00:08:13 +00:00
set targetPlatformVersion v8.1
2014-05-06 00:09:46 +00:00
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
2014-05-10 17:33:11 +00:00
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
2012-10-20 08:40:05 +00:00
set extraSdkPath " \\ . . \\ $ t a r g e t P l a t f o r m I d e n t i f i e r "
2014-05-06 00:09:46 +00:00
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
2016-02-12 05:19:29 +00:00
} elseif { [ string equal $packageFlavor UWP] } then {
2015-04-19 23:39:05 +00:00
if { $vsVersion ne " 2 0 1 5 " } then {
fail [ appendArgs \
" u n s u p p o r t e d c o m b i n a t i o n , p a c k a g e f l a v o r " $packageFlavor \
" i s o n l y s u p p o r t e d w i t h V i s u a l S t u d i o 2 0 1 5 " ]
}
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
2016-02-18 21:00:29 +00:00
set targetPlatformIdentifier UAP; # NOTE: Not "UWP".
2015-04-19 23:39:05 +00:00
set targetPlatformVersion v0.8.0.0
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
set extraSdkPath " \\ . . \\ $ t a r g e t P l a t f o r m I d e n t i f i e r "
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
2014-05-06 00:09:46 +00:00
} elseif { [ string equal $packageFlavor Win32] } then {
set shortName $shortNames ( $packageFlavor , $vsVersion )
set displayName $displayNames ( $packageFlavor , $vsVersion )
2013-04-11 00:13:46 +00:00
set targetPlatformIdentifier Windows
set targetPlatformVersion v8.0
2014-05-06 00:09:46 +00:00
set minVsVersion [ getMinVsVersionXmlChunk $vsVersion ]
2014-05-10 17:28:45 +00:00
set maxPlatformVersion \
[ getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion ]
2013-04-11 00:13:46 +00:00
set extraSdkPath " "
2014-05-06 00:09:46 +00:00
set extraFileListAttributes \
[ getExtraFileListXmlChunk $packageFlavor $vsVersion ]
2012-10-20 08:40:05 +00:00
} else {
2014-04-18 00:08:13 +00:00
fail [ appendArgs \
" u n s u p p o r t e d p a c k a g e f l a v o r , m u s t b e o n e o f : " \
2016-02-12 05:19:29 +00:00
[ list WinRT WinRT81 WP80 WP81 UWP Win32] ]
2012-10-20 08:40:05 +00:00
}
2012-07-27 02:36:06 +00:00
# ##############################################################################
2012-07-31 00:43:31 +00:00
#
# 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
}
# ##############################################################################
2012-07-27 02:36:06 +00:00
set templateFile [ file join $path win sqlite.vsix]
if { ! [ file exists $templateFile ] || \
! [ file isfile $templateFile ] } then {
fail [ appendArgs " t e m p l a t e f i l e \" " $templateFile " \" d o e s n o t e x i s t " ]
}
set currentDirectory [ pwd ]
2012-10-28 19:35:55 +00:00
set outputFile [ file join $currentDirectory [ appendArgs sqlite- \
$packageFlavor -output.vsix ] ]
2012-07-27 02:36:06 +00:00
if { [ file exists $outputFile ] } then {
fail [ appendArgs " o u t p u t f i l e \" " $outputFile " \" a l r e a d y e x i s t s " ]
}
# ##############################################################################
#
# 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 " c a n n o t l o c a t e a u s a b l e t e m p o r a r y d i r e c t o r y "
}
#
# 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.
#
2012-07-31 00:43:31 +00:00
set pattern { ^ # define\s+SQLITE_VERSION\s+"(.*)"$}
2012-07-27 02:36:06 +00:00
set data [ readFile [ file join $sourceDirectory sqlite3.h] ]
if { ! [ regexp - line - - $pattern $data dummy version] } then {
fail [ appendArgs " c a n n o t l o c a t e S Q L I T E _ V E R S I O N v a l u e i n \" " \
[ file join $sourceDirectory sqlite3.h] \ " ]
}
# ##############################################################################
#
2012-10-20 08:40:05 +00:00
# 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.
2012-07-27 02:36:06 +00:00
#
2012-07-31 00:43:31 +00:00
if { ! [ info exists fileNames( source ) ] } then {
2012-10-20 08:40:05 +00:00
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] ]
2012-07-31 00:43:31 +00:00
if { ! [ info exists no( symbols ) ] } then {
lappend fileNames( source ) \
2012-10-12 18:06:07 +00:00
[ file join $binaryDirectory < build> < platform> sqlite3.pdb]
2012-07-31 00:43:31 +00:00
}
}
if { ! [ info exists fileNames( destination ) ] } then {
set fileNames( destination ) [ list \
2012-10-20 08:40:05 +00:00
[ 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] ]
2012-07-31 00:43:31 +00:00
if { ! [ info exists no( symbols ) ] } then {
lappend fileNames( destination ) \
2012-10-12 18:06:07 +00:00
[ file join $stagingDirectory Redist < build> < platform> sqlite3.pdb]
2012-07-31 00:43:31 +00:00
}
}
2012-10-20 08:40:05 +00:00
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] ]
2012-07-31 00:43:31 +00:00
if { ! [ info exists no( symbols ) ] } then {
2012-10-20 08:40:05 +00:00
lappend fileNames( flags ) [ list noRetail]
2012-10-12 18:06:07 +00:00
}
}
# ##############################################################################
#
2012-10-20 08:40:05 +00:00
# NOTE: Setup the list of builds supported by this script. These may be
# overridden via the user-specific customizations file.
2012-10-12 18:06:07 +00:00
#
if { ! [ info exists buildNames] } then {
set buildNames [ list Debug Retail]
}
2012-07-27 02:36:06 +00:00
# ##############################################################################
#
2012-10-20 08:40:05 +00:00
# NOTE: Setup the list of platforms supported by this script. These may be
# overridden via the command line or the user-specific customizations
# file.
2012-07-27 02:36:06 +00:00
#
2014-05-06 00:09:46 +00:00
if { ! [ info exists platformNames] || [ llength $platformNames ] == 0 } then {
2012-07-31 08:15:56 +00:00
set platformNames [ list x86 x64 ARM]
2012-07-31 00:43:31 +00:00
}
2012-07-27 02:36:06 +00:00
# ##############################################################################
#
# NOTE: Make sure the staging directory exists, creating it if necessary.
#
file mkdir $stagingDirectory
#
2012-10-20 08:40:05 +00:00
# NOTE: Build the Tcl command used to extract the template VSIX package to
# the staging directory.
2012-07-27 02:36:06 +00:00
#
set extractCommand [ list exec - - $unzip $templateFile - d $stagingDirectory ]
#
2012-10-20 08:40:05 +00:00
# NOTE: Extract the template VSIX package to the staging directory.
2012-07-27 02:36:06 +00:00
#
eval $extractCommand
# ##############################################################################
#
2012-10-20 08:40:05 +00:00
# NOTE: Process each file in the master file list. There are actually three
2012-10-15 20:28:22 +00:00
# parallel lists that contain the source file names, the destination file
2012-10-20 08:40:05 +00:00
# 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.
2012-07-27 02:36:06 +00:00
#
2012-10-15 20:28:22 +00:00
foreach sourceFileName $fileNames ( source ) \
destinationFileName $fileNames ( destination ) \
2012-10-20 08:40:05 +00:00
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 } ]
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
# 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.
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
foreach buildName \
2012-10-20 08:40:05 +00:00
[ expr { $isBuildNeutral ? [ list CommonConfiguration] : $buildNames } ] {
2012-07-31 00:43:31 +00:00
#
2012-10-12 18:06:07 +00:00
# NOTE: Should the current file be skipped for this build?
2012-07-31 00:43:31 +00:00
#
2012-10-20 08:40:05 +00:00
if { [ lsearch $fileFlags no$ { buildName } ] != -1 } then {
2012-10-12 18:06:07 +00:00
continue
}
2012-07-31 00:43:31 +00:00
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
# 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.
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
foreach platformName \
2012-10-20 08:40:05 +00:00
[ expr { $isPlatformNeutral ? [ list neutral] : $platformNames } ] {
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
# NOTE: Use the actual platform name in the destination file name.
2012-07-31 00:43:31 +00:00
#
2012-10-20 08:40:05 +00:00
set newDestinationFileName [ replaceFileNameTokens $destinationFileName \
$shortName $buildName $platformName ]
2012-07-31 00:43:31 +00:00
#
2012-10-12 18:06:07 +00:00
# NOTE: Does the source file need to be copied to the destination file?
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
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.
#
2012-10-20 08:40:05 +00:00
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
}
2012-10-12 18:06:07 +00:00
}
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
# NOTE: Does the destination file contain dynamic replacements that must
# be processed now?
2012-07-27 02:36:06 +00:00
#
2012-10-12 18:06:07 +00:00
if { $useSubst } then {
#
# NOTE: Perform any dynamic replacements contained in the destination
# file and then re-write it in-place.
#
substFile $newDestinationFileName
}
2012-07-27 02:36:06 +00:00
}
}
}
# ##############################################################################
#
# 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
#
2012-10-20 08:40:05 +00:00
# NOTE: Build the Tcl command used to archive the final VSIX package in the
2012-07-27 02:36:06 +00:00
# output directory.
#
set archiveCommand [ list exec - - $zip - r $outputFile * ]
#
2012-10-20 08:40:05 +00:00
# NOTE: Build the final VSIX package archive in the output directory.
2012-07-27 02:36:06 +00:00
#
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