1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-01 06:27:03 +03:00

Update the threads branch to include all the latest trunk changes.

FossilOrigin-Name: f4125771e21f1ca29d5442b5441dacfc06b8032b
This commit is contained in:
drh
2012-08-16 11:24:22 +00:00
38 changed files with 1719 additions and 881 deletions

394
tool/build-all-msvc.bat Executable file
View File

@ -0,0 +1,394 @@
@ECHO OFF
::
:: build-all-msvc.bat --
::
:: Multi-Platform Build Tool for MSVC
::
SETLOCAL
REM SET __ECHO=ECHO
REM SET __ECHO2=ECHO
IF NOT DEFINED _AECHO (SET _AECHO=REM)
IF NOT DEFINED _CECHO (SET _CECHO=REM)
IF NOT DEFINED _VECHO (SET _VECHO=REM)
%_AECHO% Running %0 %*
REM SET DFLAGS=/L
%_VECHO% DFlags = '%DFLAGS%'
SET FFLAGS=/V /F /G /H /I /R /Y /Z
%_VECHO% FFlags = '%FFLAGS%'
SET ROOT=%~dp0\..
SET ROOT=%ROOT:\\=\%
%_VECHO% Root = '%ROOT%'
REM
REM NOTE: The first and only argument to this batch file should be the output
REM directory where the platform-specific binary directories should be
REM created.
REM
SET BINARYDIRECTORY=%1
IF NOT DEFINED BINARYDIRECTORY (
GOTO usage
)
%_VECHO% BinaryDirectory = '%BINARYDIRECTORY%'
SET DUMMY=%2
IF DEFINED DUMMY (
GOTO usage
)
REM
REM NOTE: From this point, we need a clean error level. Reset it now.
REM
CALL :fn_ResetErrorLevel
REM
REM NOTE: Change the current directory to the root of the source tree, saving
REM the current directory on the directory stack.
REM
%__ECHO2% PUSHD "%ROOT%"
IF ERRORLEVEL 1 (
ECHO Could not change directory to "%ROOT%".
GOTO errors
)
REM
REM NOTE: This batch file requires the ComSpec environment variable to be set,
REM typically to something like "C:\Windows\System32\cmd.exe".
REM
IF NOT DEFINED ComSpec (
ECHO The ComSpec environment variable must be defined.
GOTO errors
)
REM
REM NOTE: This batch file requires the VcInstallDir environment variable to be
REM set. Tyipcally, this means this batch file needs to be run from an
REM MSVC command prompt.
REM
IF NOT DEFINED VCINSTALLDIR (
ECHO The VCINSTALLDIR environment variable must be defined.
GOTO errors
)
REM
REM NOTE: If the list of platforms is not already set, use the default list.
REM
IF NOT DEFINED PLATFORMS (
SET PLATFORMS=x86 x86_amd64 x86_arm
)
%_VECHO% Platforms = '%PLATFORMS%'
REM
REM NOTE: Setup environment variables to translate between the MSVC platform
REM names and the names to be used for the platform-specific binary
REM directories.
REM
SET x86_NAME=x86
SET x86_amd64_NAME=x64
SET x86_arm_NAME=ARM
%_VECHO% x86_Name = '%x86_NAME%'
%_VECHO% x86_amd64_Name = '%x86_amd64_NAME%'
%_VECHO% x86_arm_Name = '%x86_arm_NAME%'
REM
REM NOTE: Check for the external tools needed during the build process ^(i.e.
REM those that do not get compiled as part of the build process itself^)
REM along the PATH.
REM
FOR %%T IN (gawk.exe tclsh85.exe) DO (
SET %%T_PATH=%%~dp$PATH:T
)
REM
REM NOTE: Set the TOOLPATH variable to contain all the directories where the
REM external tools were found in the search above.
REM
SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
%_VECHO% ToolPath = '%TOOLPATH%'
REM
REM NOTE: Check for MSVC 2012 because the Windows SDK directory handling is
REM slightly different for that version.
REM
IF "%VisualStudioVersion%" == "11.0" (
SET SET_NSDKLIBPATH=1
) ELSE (
CALL :fn_UnsetVariable SET_NSDKLIBPATH
)
REM
REM NOTE: This is the outer loop. There should be exactly one iteration per
REM platform.
REM
FOR %%P IN (%PLATFORMS%) DO (
REM
REM NOTE: Using the MSVC platform name, lookup the simpler platform name to
REM be used for the name of the platform-specific binary directory via
REM the environment variables setup earlier.
REM
CALL :fn_SetVariable %%P_NAME PLATFORMNAME
REM
REM NOTE: This is the inner loop. There should be exactly one iteration.
REM This loop is necessary because the PlatformName environment
REM variable was set above and that value is needed by some of the
REM commands contained in the inner loop. If these commands were
REM directly contained in the outer loop, the PlatformName environment
REM variable would be stuck with its initial empty value instead.
REM
FOR /F "tokens=2* delims==" %%D IN ('SET PLATFORMNAME') DO (
REM
REM NOTE: Attempt to clean the environment of all variables used by MSVC
REM and/or Visual Studio. This block may need to be updated in the
REM future to account for additional environment variables.
REM
CALL :fn_UnsetVariable DevEnvDir
CALL :fn_UnsetVariable ExtensionSdkDir
CALL :fn_UnsetVariable Framework35Version
CALL :fn_UnsetVariable FrameworkDir
CALL :fn_UnsetVariable FrameworkDir32
CALL :fn_UnsetVariable FrameworkVersion
CALL :fn_UnsetVariable FrameworkVersion32
CALL :fn_UnsetVariable FSHARPINSTALLDIR
CALL :fn_UnsetVariable INCLUDE
CALL :fn_UnsetVariable LIB
CALL :fn_UnsetVariable LIBPATH
CALL :fn_UnsetVariable Platform
REM CALL :fn_UnsetVariable VCINSTALLDIR
CALL :fn_UnsetVariable VSINSTALLDIR
CALL :fn_UnsetVariable WindowsSdkDir
CALL :fn_UnsetVariable WindowsSdkDir_35
CALL :fn_UnsetVariable WindowsSdkDir_old
REM
REM NOTE: Reset the PATH here to the absolute bare minimum required.
REM
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
REM
REM NOTE: Launch a nested command shell to perform the following steps:
REM
REM 1. Setup the MSVC environment for this platform using the
REM official batch file.
REM
REM 2. Make sure that no stale build output files are present.
REM
REM 3. Build the "sqlite3.dll" and "sqlite3.lib" binaries for this
REM platform.
REM
REM 4. Copy the "sqlite3.dll" and "sqlite3.lib" binaries for this
REM platform to the platform-specific directory beneath the
REM binary directory.
REM
"%ComSpec%" /C (
REM
REM NOTE: Attempt to setup the MSVC environment for this platform.
REM
%__ECHO% CALL "%VCINSTALLDIR%\vcvarsall.bat" %%P
IF ERRORLEVEL 1 (
ECHO Failed to call "%VCINSTALLDIR%\vcvarsall.bat" for platform %%P.
GOTO errors
)
REM
REM NOTE: If this batch file is not running in "what-if" mode, check to
REM be sure we were actually able to setup the MSVC environment as
REM current versions of their official batch file do not set the
REM exit code upon failure.
REM
IF NOT DEFINED __ECHO (
IF NOT DEFINED WindowsSdkDir (
ECHO Cannot build, Windows SDK not found for platform %%P.
GOTO errors
)
)
REM
REM NOTE: When using MSVC 2012, the native SDK path cannot simply use
REM the "lib" sub-directory beneath the location specified in the
REM WindowsSdkDir environment variable because that location does
REM not actually contain the necessary library files for x86.
REM This must be done for each iteration because it relies upon
REM the WindowsSdkDir environment variable being set by the batch
REM file used to setup the MSVC environment.
REM
IF DEFINED SET_NSDKLIBPATH (
CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
)
REM
REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
REM makefile to clean any stale build output from previous
REM iterations of this loop and/or previous runs of this batch
REM file, etc.
REM
IF NOT DEFINED NOCLEAN (
%__ECHO% nmake -f Makefile.msc clean
IF ERRORLEVEL 1 (
ECHO Failed to clean for platform %%P.
GOTO errors
)
) ELSE (
REM
REM NOTE: Even when the cleaning step has been disabled, we still need
REM to remove the build output for the files we are specifically
REM wanting to build for each platform.
REM
%__ECHO% DEL /Q sqlite3.dll sqlite3.lib sqlite3.pdb
)
REM
REM NOTE: Invoke NMAKE with the MSVC makefile to build the "sqlite3.dll"
REM binary. The x86 compiler will be used to compile the native
REM command line tools needed during the build process itself.
REM Also, disable looking for and/or linking to the native Tcl
REM runtime library.
REM
%__ECHO% nmake -f Makefile.msc sqlite3.dll "NCC=""%VCINSTALLDIR%\bin\cl.exe""" USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
IF ERRORLEVEL 1 (
ECHO Failed to build "sqlite3.dll" for platform %%P.
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.dll" file to the platform-specific directory
REM beneath the binary directory.
REM
%__ECHO% XCOPY sqlite3.dll "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.dll" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.lib" file to the platform-specific directory
REM beneath the binary directory.
REM
%__ECHO% XCOPY sqlite3.lib "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.lib" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
REM
REM NOTE: Copy the "sqlite3.pdb" file to the platform-specific directory
REM beneath the binary directory unless we are prevented from doing
REM so.
REM
IF NOT DEFINED NOSYMBOLS (
%__ECHO% XCOPY sqlite3.pdb "%BINARYDIRECTORY%\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "sqlite3.pdb" to "%BINARYDIRECTORY%\%%D\".
GOTO errors
)
)
)
)
REM
REM NOTE: Handle any errors generated during the nested command shell.
REM
IF ERRORLEVEL 1 (
GOTO errors
)
)
REM
REM NOTE: Restore the saved current directory from the directory stack.
REM
%__ECHO2% POPD
IF ERRORLEVEL 1 (
ECHO Could not restore directory.
GOTO errors
)
REM
REM NOTE: If we get to this point, we have succeeded.
REM
GOTO no_errors
:fn_ResetErrorLevel
VERIFY > NUL
GOTO :EOF
:fn_SetErrorLevel
VERIFY MAYBE 2> NUL
GOTO :EOF
:fn_SetVariable
SETLOCAL
IF NOT DEFINED %1 GOTO :EOF
IF "%2" == "" GOTO :EOF
SET __ECHO_CMD=ECHO %%%1%%
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
SET VALUE=%%V
)
ENDLOCAL && SET %2=%VALUE%
GOTO :EOF
:fn_UnsetVariable
IF NOT "%1" == "" (
SET %1=
CALL :fn_ResetErrorLevel
)
GOTO :EOF
:fn_AppendVariable
SET __ECHO_CMD=ECHO %%%1%%
IF DEFINED %1 (
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
SET %1=%%V%~2
)
) ELSE (
SET %1=%~2
)
SET __ECHO_CMD=
CALL :fn_ResetErrorLevel
GOTO :EOF
:usage
ECHO.
ECHO Usage: %~nx0 ^<binaryDirectory^>
ECHO.
GOTO errors
:errors
CALL :fn_SetErrorLevel
ENDLOCAL
ECHO.
ECHO Failure, errors were encountered.
GOTO end_of_file
:no_errors
CALL :fn_ResetErrorLevel
ENDLOCAL
ECHO.
ECHO Success, no errors were encountered.
GOTO end_of_file
:end_of_file
%__ECHO% EXIT /B %ERRORLEVEL%

419
tool/mkvsix.tcl Normal file
View File

@ -0,0 +1,419 @@
#!/usr/bin/tclsh
#
# This script is used to generate a VSIX (Visual Studio Extension) file for
# SQLite usable by Visual Studio.
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\]"
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 ""
}
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
# with the substituted data.
#
return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
}
proc replacePlatform { fileName platformName } {
#
# NOTE: Returns the specified file name containing the platform name instead
# of platform placeholder tokens.
#
return [string map [list <platform> $platformName] $fileName]
}
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 != 2} 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"
}
###############################################################################
#
# 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 sqlite-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 the master file list data, including the necessary flags.
#
if {![info exists fileNames(source)]} then {
set fileNames(source) [list "" "" "" \
[file join $sourceDirectory sqlite3.h] \
[file join $binaryDirectory <platform> sqlite3.lib] \
[file join $binaryDirectory <platform> sqlite3.dll]]
if {![info exists no(symbols)]} then {
lappend fileNames(source) \
[file join $binaryDirectory <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 CommonConfiguration \
<platform> SQLite.WinRT.props] \
[file join $stagingDirectory DesignTime CommonConfiguration \
<platform> sqlite3.h] \
[file join $stagingDirectory DesignTime CommonConfiguration \
<platform> sqlite3.lib] \
[file join $stagingDirectory Redist CommonConfiguration \
<platform> sqlite3.dll]]
if {![info exists no(symbols)]} then {
lappend fileNames(destination) \
[file join $stagingDirectory Redist Debug \
<platform> sqlite3.pdb]
}
}
if {![info exists fileNames(neutral)]} then {
set fileNames(neutral) [list 1 1 1 1 0 0]
if {![info exists no(symbols)]} then {
lappend fileNames(neutral) 0
}
}
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 platforms supported by this script.
#
if {![info exists platformNames]} 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 package to the
# staging directory.
#
set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
#
# NOTE: Extract the template 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: 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 {$isNeutral ? [list neutral] : $platformNames}] {
#
# NOTE: Use the actual platform name in the destination file name.
#
set newDestinationFileName [replacePlatform $destinationFileName \
$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.
#
file copy [replacePlatform $sourceFileName $platformName] \
$newDestinationFileName
}
#
# 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 package in the
# output directory.
#
set archiveCommand [list exec -- $zip -r $outputFile *]
#
# NOTE: Build the final 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

BIN
tool/win/sqlite.vsix Normal file

Binary file not shown.