首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Windows 平台編譯 libmemcached 完整指南:MinGW、configure 修補與原生碼適配

     編輯:關於C

專案背景

`libmemcached` 是 C 語言的 Memcached 客戶端庫,官方主要支援類 Unix 系統。在 Windows 上使用 MinGW 編譯需解決:缺少 Unix 標頭檔、`configure` 腳本強制檢測 `memcached` 二進位、yacc/lex 產生的符號衝突、測試代碼依賴 POSIX API 等問題。本文記錄完整修補流程。

環境準備

  • MinGW-w64:提供 `gcc`、`ar`、`ranlib`、`make`、POSIX 兼容層(`pthread`、`socket` 等)
  • MSYS2 或 **Git Bash**:執行 `./configure`、`make` 所需 Shell 環境
  • 原始碼:`libmemcached-1.0.18.tar.gz`(或較新版)

步驟 1:修補 `configure` 移除強制 `memcached` 檢測

`configure` 由 `autoconf` 產生,包含一段檢測 `--with-memcached` 的邏輯,找不到二進位會直接報錯退出。由於 Windows 上通常不編譯 `memcached`,需**註釋整段檢測邏輯**。

定位代碼段(搜尋 `with_memcached`)


# Check whether --with-memcached was given.
if test "${with_memcached+set}" = set; then :
  withval=$with_memcached; ac_cv_with_memcached="$withval"
else
  ac_cv_with_memcached=memcached
fi
... # 後續一長串路徑搜尋、MEMC_BINARY 設定、錯誤處理
# 結尾定義宏
cat >>confdefs.h <<_ACEOF
#define MEMCACHED_BINARY "$MEMC_BINARY"
_ACEOF

修補策略:整段註釋,手動定義 `MEMCACHED_BINARY`


# 1. 將上述整段 if-else 檢測邏輯以 # 註釋
# 2. 在 confdefs.h 追加區塊前,手動寫入預設值(或留空)
cat >>confdefs.h <<_ACEOF
#define MEMCACHED_BINARY ""
_ACEOF

或更簡單:在 `configure.ac` 修改後重新 `autoreconf -fiv`(需安裝 autotools)。直接改 `configure` 較快但不可維護。

步驟 2:修正原始碼中引用 `MEMCACHED_BINARY` 的位置

搜尋 `MEMCACHED_BINARY`,主要在 `libtest/server.c`:


// 原代碼
snprintf(buffer, sizeof(buffer), "%s -d -P %s -t 1 -p %u -U %u -m 128",
         MEMCACHED_BINARY, construct->pid_file[x], construct->port[x], construct->port[x]);

// 修正:移除 %s 與 MEMCACHED_BINARY
snprintf(buffer, sizeof(buffer), "-d -P %s -t 1 -p %u -U %u -m 128",
         construct->pid_file[x], construct->port[x], construct->port[x]);

同理修正 `else` 分支。這樣測試啟動命令不再依賴外部 `memcached` 路徑。

步驟 3:排除 Unix 專用標頭檔

  • `libmemcached/options/server.h`:註釋 `#include `(Windows 用 `winsock2.h`/`ws2tcpip.h`)
  • `clients/memslap.c`:註釋 `#include `(記憶體映射,Windows 用 `MapViewOfFile` 等不同 API)

步驟 4:解決 yacc/lex 產生符號衝突(ERROR/TRUE/FALSE/FLOAT)

`libmemcached/options/` 下 `parser.h`、`parser.cc`、`scanner.cc` 由 Bison/Flex 產生,枚舉值 `ERROR`、`TRUE`、`FALSE`、`FLOAT` 與 Windows 標頭檔(`wingdi.h`、`windef.h` 等)巨集衝突。

修補三檔案:統一重命名


// parser.h / parser.cc
enum yytokentype {
    COMMENT = 258, END = 259,
    ERROR1 = 260,   // ERROR → ERROR1
    ...
    TRUE1 = 315,    // TRUE → TRUE1
    FALSE1 = 316,   // FALSE → FALSE1
    FLOAT1 = 317,   // FLOAT → FLOAT1
    ...
};

// parser.cc 字串表同步修改
static const char *const yytname[] = {
    "$end", "error", "$undefined", "COMMENT", "END", "ERROR1",
    ...
    "TRUE1", "FALSE1", "','", "'='", "FLOAT1", ..., 0
};

// scanner.cc 規則動作同步
case 44: ... { return ERROR1; }
case 45: ... { return TRUE1; }
case 46: ... { return FALSE1; }
...

注意:大小寫敏感,需全域替換所有出現處。

步驟 5:隔離測試代碼的 POSIX 依賴

`libtest/server.c` 使用 `timespec`、`kill()`、`fork()`、`access()` 等。用 `#ifndef WIN32` 包裹:


#ifndef WIN32
static struct timespec global_sleep_value = {0, 50000};
#endif

static void kill_file(const char *file_buffer) {
#ifndef WIN32
    // 原 POSIX 實作
#endif
}

void server_startup(server_startup_st *construct) {
#ifndef WIN32
    // 原 POSIX 實作
#endif
}

**關鍵**:不能整個檔案註釋,因其他測試檔需連結其中的函式聲明(如 `server_startup`)。保留空實現或存根即可。

步驟 6:修補測試套件 `tests/parser.cc` 的 `access()` 呼叫


test_return_t memcached_create_with_options_with_filename(memcached_st*) {
#ifndef WIN32
    if (access(SUPPORT_EXAMPLE_CNF, R_OK)) return TEST_SKIPPED;
    // ... 原邏輯
#endif
    return TEST_SUCCESS;
}
// 同理處理 libmemcached_check_configuration_with_filename_test、test_include_keyword

步驟 7:編譯與安裝


# 在 MSYS2/MinGW Shell 中
./configure --prefix=/mingw64 --disable-sasl  # 禁用 SASL 簡化依賴
make -j$(nproc)
make install

產出:`libmemcached.dll`、`libmemcached.a`、標頭檔至 `--prefix` 目錄。

常見編譯錯誤與對策

錯誤訊息原因解決
`arpa/inet.h: No such file`Unix socket 標頭註釋或改 `#include `
`'ERROR' redefined`yacc 符號衝突重命名為 `ERROR1` 等
`memcached binary not found`configure 強制檢測註釋 configure 檢測段,手動定義宏
`sys/mman.h not found`POSIX mmap註釋 memslap.c 包含
`access undefined`測試代碼用 POSIX access`#ifndef WIN32` 包裹
連結錯誤 `server_startup`測試檔需此符號保留函式簽名,實現留空

驗證安裝


# 編譯簡單測試程式
gcc test_memc.c -o test_memc -I/mingw64/include -L/mingw64/lib -lmemcached
./test_memc

總結

Windows 編譯 `libmemcached` 核心在於:**屏蔽測試代碼的 POSIX 依賴**、**解決 yacc/lex 符號污染**、**繞過 configure 的運行時依賴檢測**。建議將修補封裝為 `patch` 檔案(`git diff > win32-fixes.patch`),納入專案版本控制,實現可重現構建。若專案僅需客戶端功能,亦可考慮使用更輕量、純 C99 實現的替代庫(如 `libmemcached-awesome` fork),減少移植成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved