为 Windows(64 位)编译 SQLite

2021-11-25 00:00:00 windows gcc c 64-bit sqlite

我有 MinGW,我希望将 SQLite 合并源 编译成 64 位 dll.我对这种编译相当陌生,到目前为止我的努力都以失败告终.(我首先开始使用 autoconf 合并并在 Linux 上使用 configure & make 工具.但显然这对 Windows 二进制文件永远不起作用.)

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:

以下是我用于 64 位发布版本的编译器预处理器定义:

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
  • 线程安全=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

以下是我用于 32 位版本构建的编译器预处理器定义:

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
  • 线程安全=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

我不知道把这些放在哪里.我最终做了一个有根据的猜测,制作了一个名为 sqlite3w64.h 的新文件(为了整洁)并粘贴到以下内容中:

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

结果是一个 733KB 的 DLL 文件.好的!它真的起作用了吗?它疯了 - 我得到了一个 BadImageFormatException.然后我还尝试使用相同的方法进行 x86 编译.再一次,我得到了一个 733KB 的 DLL 文件(这很奇怪?),我再一次得到一个 BadImageFormatException.

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.

帮助.

改为使用以下命令:

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

产生了一个 740KB 的 DLL 文件,但仍然给出了 BadImageFormatException.

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

原来我的 MinGW 版本只有 32 位.获得 64 位版本然后允许我为 64 位制作 SQLite.添加标志 -m64 将编译器设置为 64 位模式.

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 位:

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 位:

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 预编译:http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/mingw-w64-bin_i686-mingw_20111220.zip/download?use_mirr=ignum

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

安装说明:http://code.google.com/p/tonatiuh/wiki/InstallingMinGWForWindows64

推荐答案

您正在编译为 EXE.将其称为 DLL 不会神奇地使其成为 DLL.

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

您需要将特殊链接器选项传递给 gcc 以使其创建 DLL.引自 Mingw 网站:(有点,我用 gcc 替换了 g++)

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

该页面还说明了您希望 DLL 导出的函数,必须使用 __declspec(dllexport) 声明.(再往下,有一个关于如何将所有全局函数导出到 DLL 的示例,就像在 Unix 中通常发生的那样.)

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.)

gcc 的 -Wl 参数告诉 gcc 将进一步的参数 --out-implib,libexample_dll.a 传递给链接器.

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

我还会100%确保构建的 DLL 实际上是 64 位 DLL 而不是 32 位 DLL.你有什么办法检查吗?在 Linux 上,您可以运行文件"命令.

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.

您也可以尝试将 -m64 选项添加到 gcc 命令行,这应该强制 gcc 以 amd64 目标为目标.

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

如果那个不起作用,那么您可能完全使用了错误的编译器.确保您拥有 Mingw 工具链的 x86_64/amd64 版本.安装就像找到合适的ZIP,解压一样简单它,并设置路径.

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.

如果所有这些都失败了,或者如果您只想验证一个所谓正确编译的设置,请尝试 此处为预编译的 64 位二进制文​​件 或此处.

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.

相关文章