MinGW静态编译MYSQL程序

开发环境

  1. MINGW构建openssl-1.1.1需要在Unix环境下使用perl构建,这里选择MSYS2环境
  2. 先安装软件MSYS2,然后将MinGW64解压到MSYS2安装目录下的mingw64中
  3. 下载cmake解压到MSYS2安装目录里的mingw64/cmake中或者直接放到mingw64目录下
  4. 运行MSYS2目录下的mingw64.exe(不要用msys2.exe),后续操作全部在这个环境下执行
1
2
3
4
# 先安装一下其他工具
pacman -Syu # 先更新,如果它提示需要安装XXX可以不需要安装
pacman -S patch perl # openssl需要perl构建
export PATH=/mingw64/cmake/bin:$PATH # mariadb需要cmake构建

静态编译ZLIB

1
2
3
4
5
6
7
8
9
wget https://zlib.net/current/zlib-1.2.11.tar.gz

make -f win32/Makefile.gcc
make test testdll -f win32/Makefile.gcc

make -f win32/Makefile.gcc install \
INCLUDE_PATH=/home/leux/zlib/include \
LIBRARY_PATH=/home/leux/zlib/lib \
BINARY_PATH=/home/leux/zlib/bin

静态编译OPENSSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar -xzvf openssl-1.1.1d.tar.gz
cd openssl-1.1.1d
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-openssl/openssl-1.1.1-relocation.patch
patch -p1 -i openssl-1.1.1-relocation.patch
mkdir build & cd build

../Configure mingw64 -fPIC -static no-shared \
--prefix=/home/leux/openssl --openssldir=ssl \
zlib --with-zlib-lib=/home/leux/zlib/lib \
--with-zlib-include=/home/leux/zlib/include \
-DOPENSSLBIN=\"\\\"/home/leux/openssl/bin\\\"\" \
-D__MINGW_USE_VC2005_COMPAT

make depend all
make VERBOSE=1 test
make install

静态编译MariaDB驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
wget http://mirrors.nav.ro/mariadb//connector-c-2.3.7/mariadb-connector-c-2.3.7-src.tar.gz
tar -xzvf mariadb-connector-c-2.3.7-src.tar.gz
cd mariadb-connector-c-2.3.7-src/

wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/001-2.2.3-fix-libnames-mingw.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/002-check-also-for-__MINGW64__-definition-to-decide-targ.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/use_fopen_for_xp_compatibility.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/fix-size-t-defined.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/fix-redefinitions.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/fix-pthread.patch
wget https://raw.githubusercontent.com/msys2/MINGW-packages/master/mingw-w64-libmariadbclient/add-mariadb_config.patch

patch -p1 -i 001-2.2.3-fix-libnames-mingw.patch
patch -p1 -i 002-check-also-for-__MINGW64__-definition-to-decide-targ.patch
patch -p1 -i use_fopen_for_xp_compatibility.patch
patch -p1 -i fix-size-t-defined.patch
patch -p1 -i fix-redefinitions.patch
patch -p1 -i fix-pthread.patch
patch -p1 -i add-mariadb_config.patch

mkdir build & cd build

cmake .. -G "MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX=/home/leux/mysql -DPREFIX_INSTALL_DIR=/home/leux/mysql \
-DWITH_OPENSSL=ON -DWITH_EXTERNAL_ZLIB=ON -DOPENSSL_ROOT_DIR=/home/leux/openssl \
-DOPENSSL_CRYPTO_LIBRARY=/home/leux/openssl/lib/libcrypto.a \
-DOPENSSL_SSL_LIBRARY=/home/leux/openssl/lib/libssl.a \
-DCMAKE_BUILD_TYPE=RELEASE -DWITH_MYSQLCOMPAT=OFF

make & make install

出现问题

  1. MariaDB执行cmake时报错:CMAKE_MAKE_PROGRAM is not set。找不到make程序造成的,到mingw安装目录下将mingw32-make.exe重命名为make.exe

  2. MinGW如何链接MSVC的.lib库:例如libx.lib和liby.lib可以使用gcc … -llibx -lliby来链接

  3. Linking C shared library mariadb.dll 报错:undefined reference to XXX

1
2
3
4
5
undefined reference to `__imp_WSASetLastError`		  # 添加-lws2_32到build.make文件gcc行 
undefined reference to `__imp_CertFreeCertificateContext` # 添加-lcrypt32到build.make文件gcc行

解决:修改build\libmariadb\CMakeFiles\mariadb.dir\build.make文件的279行,在 gcc ... -o mariadb.dll ... 这行的最后面添加要包含的库。
例如:[...] gcc.exe [...] -shared -o mariadb.dll [...] @CMakeFiles/mariadb.dir/linklibs.rsp -lws2_32 -lcrypt32
  1. 若链接其他程序时出现未定义:

undefined reference to OPENSSL.....,需要链接库:-lssl
undefined reference to CRYPTO......,需要链接库:-lcrypto
undefined reference to __imp_WSA...,需要链接库:-lws2_32
undefined reference to __imp_Cert..,需要链接库:-lcrypt32
undefined reference to inflate.....,需要链接库:-lz

静态编译程序程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 注意32位GCC只能用32位的MySQL驱动,64位亦然,否则ld时会报错
// 静态需要链接的程序库:MySQL库-lmariadbclient,OPENSSL库-lssl -lcrypto
// 还需要 Windows系统库:网络接口库-lws2_32,加密API库-lcrypt32
// 编译命令:gcc -o main.exe main.c -static -ID:\mysql\include -LD:\mysql\lib -LD:\openssl\lib -lmariadbclient -lssl -lcrypto -lws2_32 -lcrypt32

// Windows下C语言连接操作MySQL示例
#include <stdio.h>
#include <winsock.h>
#include <mariadb/mysql.h>

void main(int argc, char *argv[])
{

// 初始化并连接数据库
MYSQL *conn = mysql_init(NULL);

// 判断连接是否成功,如果连接失败输出原因
if (!mysql_real_connect(conn, "HOST", "USER", "PASSWD", "DATABASES", 3306, 0, 0))
{
printf("Connect Error: %s", mysql_error(conn));
exit(-1);
}

// 输出客户端和服务端的版本号
printf("\nClient_Version: %d\tServer_Version: %d\n", mysql_get_client_version(), mysql_get_server_version(conn));

// 关闭连接
mysql_close(conn);
}