From 08119c361d1181b3e8f1abb429236e488a664753 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 13 Aug 2013 15:42:54 -0400 Subject: Imported Upstream version 2.2.1 --- tool/mkvsix.tcl | 368 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 290 insertions(+), 78 deletions(-) (limited to 'tool/mkvsix.tcl') diff --git a/tool/mkvsix.tcl b/tool/mkvsix.tcl index a751778..e9f1f81 100644 --- a/tool/mkvsix.tcl +++ b/tool/mkvsix.tcl @@ -2,7 +2,95 @@ # # 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" and "WP80". The +# fourth argument is optional and if present must be a string containing a list +# of platforms to include in the VSIX package. The format of the platform list +# string is "platform1,platform2,platform3". 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 +# tclsh85 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 @@ -11,7 +99,8 @@ proc fail { {error ""} {usage false} } { puts stdout "usage:\ [file tail [info nameofexecutable]]\ -[file tail [info script]] \[sourceDirectory\]" +[file tail [info script]] \[sourceDirectory\]\ +\[packageFlavor\] \[platformNames\]" exit 1 } @@ -84,20 +173,24 @@ proc writeFile { fileName data } { proc substFile { fileName } { # # NOTE: Performs all Tcl command, variable, and backslash substitutions in - # the specified file and then re-writes the contents of that same file + # 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]]]] } -proc replacePlatform { fileName platformName } { +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 $platformName] $fileName] + return [string map [list $buildName $platformName \ + $name] $fileName] } +# +# NOTE: This is the entry point for this script. +# set script [file normalize [info script]] if {[string length $script] == 0} then { @@ -113,7 +206,7 @@ set rootName [file rootname [file tail $script]] # NOTE: Process and verify all the command line arguments. # set argc [llength $argv] -if {$argc != 1 && $argc != 2} then {fail} +if {$argc < 1 || $argc > 4} then {fail} set binaryDirectory [lindex $argv 0] @@ -126,7 +219,7 @@ if {![file exists $binaryDirectory] || \ fail "binary directory does not exist" } -if {$argc == 2} then { +if {$argc >= 2} then { set sourceDirectory [lindex $argv 1] } else { # @@ -145,6 +238,47 @@ if {![file exists $sourceDirectory] || \ 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 {[string equal -nocase $packageFlavor WinRT]} then { + set shortName SQLite.WinRT + set displayName "SQLite for Windows Runtime" + set targetPlatformIdentifier Windows + set extraSdkPath "" + set extraFileListAttributes [appendArgs \ + "\r\n " {AppliesTo="WindowsAppContainer"} \ + "\r\n " {DependsOn="Microsoft.VCLibs, version=11.0"}] +} elseif {[string equal -nocase $packageFlavor WP80]} then { + set shortName SQLite.WP80 + set displayName "SQLite for Windows Phone" + set targetPlatformIdentifier "Windows Phone" + set extraSdkPath "\\..\\$targetPlatformIdentifier" + set extraFileListAttributes "" +} else { + fail "unsupported package flavor, must be \"WinRT\" or \"WP80\"" +} + +if {$argc >= 4} then { + set platformNames [list] + + foreach platformName [split [lindex $argv 3] ", "] { + if {[string length $platformName] > 0} then { + lappend platformNames $platformName + } + } +} + ############################################################################### # @@ -168,7 +302,8 @@ if {![file exists $templateFile] || \ } set currentDirectory [pwd] -set outputFile [file join $currentDirectory sqlite-output.vsix] +set outputFile [file join $currentDirectory [appendArgs sqlite- \ + $packageFlavor -output.vsix]] if {[file exists $outputFile]} then { fail [appendArgs "output file \"" $outputFile "\" already exists"] @@ -244,60 +379,92 @@ if {![regexp -line -- $pattern $data dummy version]} then { ############################################################################### # -# NOTE: Setup the master file list data, including the necessary flags. +# 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 $sourceDirectory sqlite3.h] \ - [file join $binaryDirectory sqlite3.lib] \ - [file join $binaryDirectory sqlite3.dll]] + set fileNames(source) [list "" "" \ + [file join $stagingDirectory DesignTime sqlite3.props] \ + [file join $sourceDirectory sqlite3.h] \ + [file join $binaryDirectory sqlite3.lib] \ + [file join $binaryDirectory sqlite3.dll]] if {![info exists no(symbols)]} then { lappend fileNames(source) \ - [file join $binaryDirectory sqlite3.pdb] + [file join $binaryDirectory 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 CommonConfiguration \ - SQLite.WinRT.props] \ - [file join $stagingDirectory DesignTime CommonConfiguration \ - sqlite3.h] \ - [file join $stagingDirectory DesignTime CommonConfiguration \ - sqlite3.lib] \ - [file join $stagingDirectory Redist CommonConfiguration \ - sqlite3.dll]] + [file join $stagingDirectory extension.vsixmanifest] \ + [file join $stagingDirectory SDKManifest.xml] \ + [file join $stagingDirectory DesignTime .props] \ + [file join $stagingDirectory DesignTime sqlite3.h] \ + [file join $stagingDirectory DesignTime sqlite3.lib] \ + [file join $stagingDirectory Redist sqlite3.dll]] if {![info exists no(symbols)]} then { lappend fileNames(destination) \ - [file join $stagingDirectory Redist Debug \ - sqlite3.pdb] + [file join $stagingDirectory Redist sqlite3.pdb] } } -if {![info exists fileNames(neutral)]} then { - set fileNames(neutral) [list 1 1 1 1 0 0] +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(neutral) 0 + lappend fileNames(flags) [list noRetail] } } -if {![info exists fileNames(subst)]} then { - set fileNames(subst) [list 1 1 1 0 0 0] +############################################################################### - if {![info exists no(symbols)]} then { - lappend fileNames(subst) 0 - } +# +# 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. +# 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]} then { set platformNames [list x86 x64 ARM] @@ -311,72 +478,117 @@ if {![info exists platformNames]} then { file mkdir $stagingDirectory # -# NOTE: Build the Tcl command used to extract the template package to the -# staging directory. +# 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 package to the staging directory. +# NOTE: Extract the template VSIX package to the staging directory. # eval $extractCommand ############################################################################### # -# NOTE: Process each file in the master file list. There are actually four -# parallel lists that contain the source file names, destination file -# names, the platform-neutral flags, and the use-subst flags. When the -# platform-neutral flag is non-zero, the file is not platform-specific. -# When the use-subst flag is non-zero, the file is considered to be a -# text file that may contain Tcl variable and/or command replacements, -# to be dynamically replaced during processing. If the source file name -# is an empty string, then the destination file name will be assumed to -# already exist in the staging directory and will not be copied; however, -# dynamic replacements may still be performed on the destination file -# prior to the package being re-zipped. -# -foreach sourceFileName $fileNames(source) \ - destinationFileName $fileNames(destination) \ - isNeutral $fileNames(neutral) useSubst $fileNames(subst) { +# 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 platform-neutral, then only one platform will - # be processed for it, namely "neutral"; otherwise, each supported - # platform will be processed for it individually. + # 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 platformName [expr {$isNeutral ? [list neutral] : $platformNames}] { + foreach buildName \ + [expr {$isBuildNeutral ? [list CommonConfiguration] : $buildNames}] { # - # NOTE: Use the actual platform name in the destination file name. + # NOTE: Should the current file be skipped for this build? # - set newDestinationFileName [replacePlatform $destinationFileName \ - $platformName] + if {[lsearch $fileFlags no${buildName}] != -1} then { + continue + } # - # NOTE: Does the source file need to be copied to the destination file? + # 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. # - if {[string length $sourceFileName] > 0} then { + foreach platformName \ + [expr {$isPlatformNeutral ? [list neutral] : $platformNames}] { # - # NOTE: First, make sure the destination directory exists. + # NOTE: Use the actual platform name in the destination file name. # - file mkdir [file dirname $newDestinationFileName] + set newDestinationFileName [replaceFileNameTokens $destinationFileName \ + $shortName $buildName $platformName] # - # NOTE: Then, copy the source file to the destination file verbatim. + # NOTE: Does the source file need to be copied to the destination file? # - file copy [replacePlatform $sourceFileName $platformName] \ - $newDestinationFileName - } + 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. + # NOTE: Does the destination file contain dynamic replacements that must + # be processed now? # - substFile $newDestinationFileName + if {$useSubst} then { + # + # NOTE: Perform any dynamic replacements contained in the destination + # file and then re-write it in-place. + # + substFile $newDestinationFileName + } } } } @@ -391,13 +603,13 @@ foreach sourceFileName $fileNames(source) \ cd $stagingDirectory # -# NOTE: Build the Tcl command used to archive the final package in the +# 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 package archive in the output directory. +# NOTE: Build the final VSIX package archive in the output directory. # eval $archiveCommand -- cgit v1.2.3