/ Check-in [8b90e0c4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tool to generate a VSIX package usable by Visual Studio 2012 RC.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8b90e0c4dbcedaf3e61c5d49452997705be1ef98
User & Date: mistachkin 2012-07-27 02:36:06
Context
2012-07-27
07:13
Add tool to build the core DLL for multiple platforms using MSVC. check-in: e42f5812 user: mistachkin tags: trunk
02:36
Add tool to generate a VSIX package usable by Visual Studio 2012 RC. check-in: 8b90e0c4 user: mistachkin tags: trunk
2012-07-24
19:46
Mark parameters to sorter interfaces as const where appropriate. check-in: d8da26f1 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added tool/mkvsix.tcl.

            1  +#!/usr/bin/tclsh
            2  +#
            3  +# This script is used to generate a VSIX (Visual Studio Extension) file for
            4  +# SQLite usable by Visual Studio.
            5  +
            6  +proc fail { {error ""} {usage false} } {
            7  +  if {[string length $error] > 0} then {
            8  +    puts stdout $error
            9  +    if {!$usage} then {exit 1}
           10  +  }
           11  +
           12  +  puts stdout "usage:\
           13  +[file tail [info nameofexecutable]]\
           14  +[file tail [info script]] <binaryDirectory> \[sourceDirectory\]"
           15  +
           16  +  exit 1
           17  +}
           18  +
           19  +proc getEnvironmentVariable { name } {
           20  +  #
           21  +  # NOTE: Returns the value of the specified environment variable or an empty
           22  +  #       string for environment variables that do not exist in the current
           23  +  #       process environment.
           24  +  #
           25  +  return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
           26  +}
           27  +
           28  +proc getTemporaryPath {} {
           29  +  #
           30  +  # NOTE: Returns the normalized path to the first temporary directory found
           31  +  #       in the typical set of environment variables used for that purpose
           32  +  #       or an empty string to signal a failure to locate such a directory.
           33  +  #
           34  +  set names [list]
           35  +
           36  +  foreach name [list TEMP TMP] {
           37  +    lappend names [string toupper $name] [string tolower $name] \
           38  +        [string totitle $name]
           39  +  }
           40  +
           41  +  foreach name $names {
           42  +    set value [getEnvironmentVariable $name]
           43  +
           44  +    if {[string length $value] > 0} then {
           45  +      return [file normalize $value]
           46  +    }
           47  +  }
           48  +
           49  +  return ""
           50  +}
           51  +
           52  +proc appendArgs { args } {
           53  +  #
           54  +  # NOTE: Returns all passed arguments joined together as a single string with
           55  +  #       no intervening spaces between arguments.
           56  +  #
           57  +  eval append result $args
           58  +}
           59  +
           60  +proc readFile { fileName } {
           61  +  #
           62  +  # NOTE: Reads and returns the entire contents of the specified file, which
           63  +  #       may contain binary data.
           64  +  #
           65  +  set file_id [open $fileName RDONLY]
           66  +  fconfigure $file_id -encoding binary -translation binary
           67  +  set result [read $file_id]
           68  +  close $file_id
           69  +  return $result
           70  +}
           71  +
           72  +proc writeFile { fileName data } {
           73  +  #
           74  +  # NOTE: Writes the entire contents of the specified file, which may contain
           75  +  #       binary data.
           76  +  #
           77  +  set file_id [open $fileName {WRONLY CREAT TRUNC}]
           78  +  fconfigure $file_id -encoding binary -translation binary
           79  +  puts -nonewline $file_id $data
           80  +  close $file_id
           81  +  return ""
           82  +}
           83  +
           84  +proc substFile { fileName } {
           85  +  #
           86  +  # NOTE: Performs all Tcl command, variable, and backslash substitutions in
           87  +  #       the specified file and then re-writes the contents of that same file
           88  +  #       with the substituted data.
           89  +  #
           90  +  return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
           91  +}
           92  +
           93  +proc replacePlatform { fileName platformName } {
           94  +  #
           95  +  # NOTE: Returns the specified file name containing the platform name instead
           96  +  #       of platform placeholder tokens.
           97  +  #
           98  +  return [string map [list <platform> $platformName] $fileName]
           99  +}
          100  +
          101  +set script [file normalize [info script]]
          102  +
          103  +if {[string length $script] == 0} then {
          104  +  fail "script file currently being evaluated is unknown" true
          105  +}
          106  +
          107  +set path [file dirname $script]
          108  +set rootName [file rootname [file tail $script]]
          109  +
          110  +###############################################################################
          111  +
          112  +#
          113  +# NOTE: Process and verify all the command line arguments.
          114  +#
          115  +set argc [llength $argv]
          116  +if {$argc != 1 && $argc != 2} then {fail}
          117  +
          118  +set binaryDirectory [lindex $argv 0]
          119  +
          120  +if {[string length $binaryDirectory] == 0} then {
          121  +  fail "invalid binary directory"
          122  +}
          123  +
          124  +if {![file exists $binaryDirectory] || \
          125  +    ![file isdirectory $binaryDirectory]} then {
          126  +  fail "binary directory does not exist"
          127  +}
          128  +
          129  +if {$argc == 2} then {
          130  +  set sourceDirectory [lindex $argv 1]
          131  +} else {
          132  +  #
          133  +  # NOTE: Assume that the source directory is the parent directory of the one
          134  +  #       that contains this script file.
          135  +  #
          136  +  set sourceDirectory [file dirname $path]
          137  +}
          138  +
          139  +if {[string length $sourceDirectory] == 0} then {
          140  +  fail "invalid source directory"
          141  +}
          142  +
          143  +if {![file exists $sourceDirectory] || \
          144  +    ![file isdirectory $sourceDirectory]} then {
          145  +  fail "source directory does not exist"
          146  +}
          147  +
          148  +###############################################################################
          149  +
          150  +set templateFile [file join $path win sqlite.vsix]
          151  +
          152  +if {![file exists $templateFile] || \
          153  +    ![file isfile $templateFile]} then {
          154  +  fail [appendArgs "template file \"" $templateFile "\" does not exist"]
          155  +}
          156  +
          157  +set currentDirectory [pwd]
          158  +set outputFile [file join $currentDirectory sqlite-output.vsix]
          159  +
          160  +if {[file exists $outputFile]} then {
          161  +  fail [appendArgs "output file \"" $outputFile "\" already exists"]
          162  +}
          163  +
          164  +###############################################################################
          165  +
          166  +#
          167  +# NOTE: Make sure that a valid temporary directory exists.
          168  +#
          169  +set temporaryDirectory [getTemporaryPath]
          170  +
          171  +if {[string length $temporaryDirectory] == 0 || \
          172  +    ![file exists $temporaryDirectory] || \
          173  +    ![file isdirectory $temporaryDirectory]} then {
          174  +  fail "cannot locate a usable temporary directory"
          175  +}
          176  +
          177  +#
          178  +# NOTE: Setup the staging directory to have a unique name inside of the
          179  +#       configured temporary directory.
          180  +#
          181  +set stagingDirectory [file normalize [file join $temporaryDirectory \
          182  +    [appendArgs $rootName . [pid]]]]
          183  +
          184  +###############################################################################
          185  +
          186  +#
          187  +# NOTE: Configure the external zipping tool.  First, see if it has already
          188  +#       been pre-configured.  If not, try to query it from the environment.
          189  +#       Finally, fallback on the default of simply "zip", which will then
          190  +#       be assumed to exist somewhere along the PATH.
          191  +#
          192  +if {![info exists zip]} then {
          193  +  if {[info exists env(ZipTool)]} then {
          194  +    set zip $env(ZipTool)
          195  +  }
          196  +  if {![info exists zip] || ![file exists $zip]} then {
          197  +    set zip zip
          198  +  }
          199  +}
          200  +
          201  +#
          202  +# NOTE: Configure the external unzipping tool.  First, see if it has already
          203  +#       been pre-configured.  If not, try to query it from the environment.
          204  +#       Finally, fallback on the default of simply "unzip", which will then
          205  +#       be assumed to exist somewhere along the PATH.
          206  +#
          207  +if {![info exists unzip]} then {
          208  +  if {[info exists env(UnZipTool)]} then {
          209  +    set unzip $env(UnZipTool)
          210  +  }
          211  +  if {![info exists unzip] || ![file exists $unzip]} then {
          212  +    set unzip unzip
          213  +  }
          214  +}
          215  +
          216  +###############################################################################
          217  +
          218  +#
          219  +# NOTE: Attempt to extract the SQLite version from the "sqlite3.h" header file
          220  +#       in the source directory.  This script assumes that the header file has
          221  +#       already been generated by the build process.
          222  +#
          223  +set pattern {^#define\s+?SQLITE_VERSION\s+?"(.*?)"$}
          224  +set data [readFile [file join $sourceDirectory sqlite3.h]]
          225  +
          226  +if {![regexp -line -- $pattern $data dummy version]} then {
          227  +  fail [appendArgs "cannot locate SQLITE_VERSION value in \"" \
          228  +      [file join $sourceDirectory sqlite3.h] \"]
          229  +}
          230  +
          231  +###############################################################################
          232  +
          233  +#
          234  +# NOTE: Setup the master file list data, including the necessary flags.
          235  +#
          236  +set fileNames(source) [list "" "" "" \
          237  +    [file join $sourceDirectory sqlite3.h] \
          238  +    [file join $binaryDirectory <platform> sqlite3.lib] \
          239  +    [file join $binaryDirectory <platform> sqlite3.dll]]
          240  +
          241  +set fileNames(destination) [list \
          242  +    [file join $stagingDirectory extension.vsixmanifest] \
          243  +    [file join $stagingDirectory SDKManifest.xml] \
          244  +    [file join $stagingDirectory DesignTime CommonConfiguration \
          245  +        <platform> SQLite.WinRT.props] \
          246  +    [file join $stagingDirectory DesignTime CommonConfiguration \
          247  +        <platform> sqlite3.h] \
          248  +    [file join $stagingDirectory DesignTime CommonConfiguration \
          249  +        <platform> sqlite3.lib] \
          250  +    [file join $stagingDirectory Redist CommonConfiguration \
          251  +        <platform> sqlite3.dll]]
          252  +
          253  +set fileNames(neutral) [list 1 1 1 1 0 0]
          254  +set fileNames(subst) [list 1 1 1 0 0 0]
          255  +
          256  +###############################################################################
          257  +
          258  +#
          259  +# NOTE: Setup the list of platforms supported by this script.
          260  +#
          261  +set platformNames [list ARM x64 x86]
          262  +
          263  +###############################################################################
          264  +
          265  +#
          266  +# NOTE: Make sure the staging directory exists, creating it if necessary.
          267  +#
          268  +file mkdir $stagingDirectory
          269  +
          270  +#
          271  +# NOTE: Build the Tcl command used to extract the template package to the
          272  +#       staging directory.
          273  +#
          274  +set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
          275  +
          276  +#
          277  +# NOTE: Extract the template package to the staging directory.
          278  +#
          279  +eval $extractCommand
          280  +
          281  +###############################################################################
          282  +
          283  +#
          284  +# NOTE: Process each file in the master file list.  There are actually four
          285  +#       parallel lists that contain the source file names, destination file
          286  +#       names, the platform-neutral flags, and the use-subst flags.  When the
          287  +#       platform-neutral flag is non-zero, the file is not platform-specific.
          288  +#       When the use-subst flag is non-zero, the file is considered to be a
          289  +#       text file that may contain Tcl variable and/or command replacements,
          290  +#       to be dynamically replaced during processing.  If the source file name
          291  +#       is an empty string, then the destination file name will be assumed to
          292  +#       already exist in the staging directory and will not be copied; however,
          293  +#       dynamic replacements may still be performed on the destination file
          294  +#       prior to the package being re-zipped.
          295  +#
          296  +foreach sourceFileName $fileNames(source) \
          297  +    destinationFileName $fileNames(destination) \
          298  +    isNeutral $fileNames(neutral) useSubst $fileNames(subst) {
          299  +  #
          300  +  # NOTE: If the current file is platform-neutral, then only one platform will
          301  +  #       be processed for it, namely "neutral"; otherwise, each supported
          302  +  #       platform will be processed for it individually.
          303  +  #
          304  +  foreach platformName [expr {$isNeutral ? [list neutral] : $platformNames}] {
          305  +    #
          306  +    # NOTE: Does the source file need to be copied to the destination file?
          307  +    #
          308  +    if {[string length $sourceFileName] > 0} then {
          309  +      #
          310  +      # NOTE: Copy the source file to the destination file verbatim.
          311  +      #
          312  +      file copy [replacePlatform $sourceFileName $platformName] \
          313  +          [replacePlatform $destinationFileName $platformName]
          314  +    }
          315  +
          316  +    #
          317  +    # NOTE: Does the destination file contain dynamic replacements that must
          318  +    #       be processed now?
          319  +    #
          320  +    if {$useSubst} then {
          321  +      #
          322  +      # NOTE: Perform any dynamic replacements contained in the destination
          323  +      #       file and then re-write it in-place.
          324  +      #
          325  +      substFile [replacePlatform $destinationFileName $platformName]
          326  +    }
          327  +  }
          328  +}
          329  +
          330  +###############################################################################
          331  +
          332  +#
          333  +# NOTE: Change the current directory to the staging directory so that the
          334  +#       external archive building tool can pickup the necessary files using
          335  +#       relative paths.
          336  +#
          337  +cd $stagingDirectory
          338  +
          339  +#
          340  +# NOTE: Build the Tcl command used to archive the final package in the
          341  +#       output directory.
          342  +#
          343  +set archiveCommand [list exec -- $zip -r $outputFile *]
          344  +
          345  +#
          346  +# NOTE: Build the final package archive in the output directory.
          347  +#
          348  +eval $archiveCommand
          349  +
          350  +#
          351  +# NOTE: Change back to the previously saved current directory.
          352  +#
          353  +cd $currentDirectory
          354  +
          355  +#
          356  +# NOTE: Cleanup the temporary staging directory.
          357  +#
          358  +file delete -force $stagingDirectory
          359  +
          360  +###############################################################################
          361  +
          362  +#
          363  +# NOTE: Success, emit the fully qualified path of the generated VSIX file.
          364  +#
          365  +puts stdout $outputFile

Added tool/win/sqlite.vsix.

cannot compute difference between binary files