libmemcached 是 C/C++ 訪問 Memcached 叢集的標準客戶端庫,官方主要針對 Linux 發布。在 Windows 上使用 MinGW 編譯時,會面臨:依賴 memcached.exe 執行測試、缺少 POSIX 標頭(arpa/inet.h、sys/mman.h)、Bison/Flex 生成的解析器符號與 Windows 巨集衝突(ERROR/TRUE/FALSE/FLOAT)、測試代碼使用 access() 等 POSIX 函數 等問題。本文記錄一次成功編譯安裝的完整修改流程,供後人參考。
x86_64-8.1.0-posix-seh-rt_v6-rev0 或更新版),確保 gcc、make、autoconf、libtool 在 PATH 中。1.0.18)configure)configure 腳本會檢測 --with-memcached,若無則報錯。由於僅需庫不需測試,直接屏蔽該檢測邏輯:
--with-memcached 關鍵字# Check whether --with-memcached was given. 到 #fi 結束的**整個檢測塊**(約 80 行)全部註釋掉(行首加 #)as_fn_error $? "could not find memcached binary" 錯誤退出效果:./configure 不再要求提供 memcached 二進制路徑。
MEMCACHED_BINARY 巨集引用(libtest/server.c)配置腳本原本會定義 #define MEMCACHED_BINARY "...",現已註釋檢測,但 server.c 仍在使用。修改兩處 snprintf:
// 原代碼
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 分支的另一處 snprintf。
libmemcached/options/server.h:註釋 #include <arpa/inet.h>(Windows 用 winsock2.h 替代,但該處僅用於測試,直接屏蔽即可)。clients/memslap.c:註釋 #include <sys/mman.h>(記憶體映射,Windows 無對應,測試代碼可忽略)。parser.h、parser.cc、scanner.cc 中定義了 enum yytokentype { ..., ERROR, TRUE, FALSE, FLOAT, ... },與 windows.h / windef.h 中的巨集 #define ERROR 0、#define TRUE 1 等**嚴重衝突**,導致編譯報錯(往往誤報為 yacc/lex 語法錯誤)。
解決方案:在三個文件中統一重命名這四個枚舉值:
ERROR → ERROR1
TRUE → TRUE1
FALSE → FALSE1
FLOAT → FLOAT1
具體修改點:
parser.h:enum yytokentype 定義處parser.cc:enum yytokentype 定義處 + static const char *const yytname[] 字串表中對應項scanner.cc:case XX: 中的 return ERROR; 等 → return ERROR1;注意:大小寫敏感,需全局替換,避免遺漏。
access() 呼叫(tests/parser.cc)三個測試函數使用 access(SUPPORT_EXAMPLE_CNF, R_OK) 檢查配置文件。包裹在 #ifndef WIN32 中:
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
libtest/server.c)為保留其他測試所需的符號定義,僅將 Linux 專用實現包裹在 #ifndef WIN32:
#ifndef WIN32
static struct timespec global_sleep_value = { .tv_sec= 0, .tv_nsec= 50000 };
#endif
static void kill_file(const char *file_buffer) {
#ifndef WIN32
// ... 原實現 ...
#endif
}
void server_startup(server_startup_st *construct) {
#ifndef WIN32
// ... 原實現 ...
#endif
}
cd libmemcached-1.0.18
./configure --prefix=/your/install/path --disable-sasl # 視需求關閉 SASL
make -j$(nproc)
make install
若 configure 提示缺少 autoconf/libtool,先執行 autoreconf -fiv 重新生成構建腳本。
parser.h/cc、scanner.cc 是否有遺漏的 ERROR/TRUE/FALSE/FLOAT。make install 失敗:確保 --prefix 路徑可寫,或以管理員身份運行。libmemcached.dll、libsasl2.dll(若啟用)放入應用目錄或系統 PATH。libmemcached.lib,調用 memcached_create()、memcached_set()、memcached_get() 確認功能正常。Windows 下編譯 libmemcached 的核心在於:斷開對 memcached.exe 的構建時依賴、屏蔽/替換缺失的 POSIX 標頭與函數、徹底解決解析器生成符號與 Windows SDK 巨集的命名空間衝突。上述修改均屬「最小侵入性」,不改變庫核心邏輯,編譯出的庫在生產環境穩定可用。