Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling SQLite for Windows (64-bit)

I have MinGW and I wish to compile the SQLite amalgamation source into a 64-bit dll. I'm fairly new to this sort of compilation and my efforts so far have resulted in failure. (I first started using the autoconf amalgamation and used the configure & make tool on Linux. But apparently that will never work for Windows binaries.)

Anyway, I've been told I need the following preprocessor defines:

Here are the compiler pre-processor defines I use for a 64-bit release build:

  • WIN64 NDEBUG
  • _WINDOWS
  • _USRDLL
  • NO_TCL
  • _CRT_SECURE_NO_DEPRECATE
  • THREADSAFE=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

Here are the compiler pre-processor defines I use for a 32-bit release build:

  • WIN32
  • NDEBUG
  • _WINDOWS
  • _USRDLL
  • NO_TCL
  • _CRT_SECURE_NO_DEPRECATE
  • THREADSAFE=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

I had no idea where to put these in. I eventually took an educated guess, made a new file (for neatness) called sqlite3w64.h and pasted in the following:

#define WIN64 NDEBUG
#define _WINDOWS
#define _USRDLL
#define NO_TCL
#define _CRT_SECURE_NO_DEPRECATE
#define THREADSAFE 1
#define TEMP_STORE 1
#define SQLITE_MAX_EXPR_DEPTH 0

I then compiled the source with the following command:

gcc sqlitew64.h sqlite3.h sqlite3ext.h shell.c sqlite3.c -o sqlite_x64.dll

What resulted was a 733KB DLL file. Nice! Did it actually work? Did it nuts - I got a BadImageFormatException. I also then tried doing an x86 compilation using the same method. Once again, I got a 733KB DLL file (that's odd?) and once again, I got a BadImageFormatException.

Help.

Update

Used the following command instead:

gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -I. shell.c sqlite3.c -o sqlite_x64.dll -Wl,--out-implib,sqlite3.a

Resulted in a 740KB DLL file which still gives a BadImageFormatException.

Final Update

Turns out my MinGW build was 32-bit only. Getting a 64-bit version then allowed me to make SQLite for 64-bit. Adding the flag -m64 sets the compiler into 64-bit mode.

64-bit:

gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m64 -I. shell.c sqlite3.c -o sqlite3_x64.dll -Wl,--out-implib,sqlite3_x64.a

32-bit:

gcc -shared -DWIN32 -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m32 -I. shell.c sqlite3.c -o sqlite3_x86.dll -Wl,--out-implib,sqlite3_x86.a

MinGW-64 Precompiled: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/mingw-w64-bin_i686-mingw_20111220.zip/download?use_mirror=ignum

Installation Instructions: http://code.google.com/p/tonatiuh/wiki/InstallingMinGWForWindows64

like image 304
Chris Watts Avatar asked Jun 11 '12 10:06

Chris Watts


People also ask

How do I install SQLite on Windows 64 bit?

First, go to SQLite's official website download page and download precompiled binaries from Windows section. Once the download is completed, you should see the downloaded file in the Windows Downloads directory. Next, right click on the downloaded file and extract it inside the C:\sqlite directory.

What is SQLite amalgamation?

The amalgamation is a single file of ANSI-C code that implements the entire SQLite library. The amalgamation is much easier to deal with. Everything is contained within a single code file, so it is easy to drop into the source tree of a larger C or C++ program.


2 Answers

You are compiling to an EXE. Calling it a DLL won't magically make it a DLL.

You need to pass special linker options to gcc to make it create DLLs. Quoted from Mingw site: (Sort of, I replaced g++ with gcc)

gcc -c -DBUILDING_EXAMPLE_DLL example_dll.cpp
gcc -shared -o example_dll.dll example_dll.o -Wl,--out-implib,libexample_dll.a

The page also explains that functions you want your DLL to export, must be declared with __declspec(dllexport). (Further down, there is an example on how to export all global functions to the DLL, like usually happens in Unix.)

The -Wl argument to gcc is what tells gcc to pass on the further arguments --out-implib,libexample_dll.a to the linker.

I would also make 100% sure that the built DLL is actually a 64 bit DLL and not a 32 bit DLL. Do you have any way to check that? On Linux you can run the "file" command.

You can also try adding the -m64 option to the gcc commandline, that should force gcc to target the amd64 target.

If that doesn't work, you may have the wrong compiler altogether. Make sure you have the x86_64/amd64 version of the Mingw toolchain. Installation is as simple as finding the right ZIP, unpacking it, and setting the path.

If all of that fails, or if you just want to verify against a supposedly correctly compiled setup, try precompiled 64-bit binaries here or from here.

like image 90
Prof. Falken Avatar answered Sep 18 '22 00:09

Prof. Falken


What would work in your case is this single link-and-compile command:

g++ -shared
-DWIN64
-DNDEBUG
-D_WINDOWS
-D_USRDLL
-DNO_TCL
-D_CRT_SECURE_NO_DEPRECATE
-DTHREADSAFE=1
-DTEMP_STORE=1
-DSQLITE_MAX_EXPR_DEPTH=0
-I.
shell.c sqlite3.c
-o sqlite_x64.dll
-Wl,--out-implib,libsqllite_x64.dll.a

The compile and link stage will be performed at once. The defined can be added on the commandline. The headers need not be compiled, but you need to pass the current directory as a header search directory, and specify the names of the dll and import file.

like image 21
rubenvb Avatar answered Sep 18 '22 00:09

rubenvb