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

Windows 平台編譯 libmemcached 完整實戰指南(MinGW + 修改 configure + 解決符號衝突)

     編輯:關於C語言

背景與挑戰

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 函數 等問題。本文記錄一次成功編譯安裝的完整修改流程,供後人參考。

環境準備

  • Windows 7/10/11
  • MinGW-w64(推薦 x86_64-8.1.0-posix-seh-rt_v6-rev0 或更新版),確保 gcc、make、autoconf、libtool 在 PATH 中。
  • libmemcached 源碼(如 1.0.18)

核心修改步驟(按執行順序)

1. 移除對 memcached.exe 的強制依賴(修改 configure)

configure 腳本會檢測 --with-memcached,若無則報錯。由於僅需庫不需測試,直接屏蔽該檢測邏輯:

  • 搜尋 --with-memcached 關鍵字
  • 將從 # Check whether --with-memcached was given. 到 #fi 結束的**整個檢測塊**(約 80 行)全部註釋掉(行首加 #)
  • 關鍵點:同時註釋掉最後的 as_fn_error $? "could not find memcached binary" 錯誤退出

效果:./configure 不再要求提供 memcached 二進制路徑。

2. 修正 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。

3. 屏蔽缺失的 POSIX 標頭

  • libmemcached/options/server.h:註釋 #include <arpa/inet.h>(Windows 用 winsock2.h 替代,但該處僅用於測試,直接屏蔽即可)。
  • clients/memslap.c:註釋 #include <sys/mman.h>(記憶體映射,Windows 無對應,測試代碼可忽略)。

4. 解決 Bison/Flex 生成符號與 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

具體修改點:

  1. parser.h:enum yytokentype 定義處
  2. parser.cc:enum yytokentype 定義處 + static const char *const yytname[] 字串表中對應項
  3. scanner.cc:case XX: 中的 return ERROR; 等 → return ERROR1;

注意:大小寫敏感,需全局替換,避免遺漏。

5. 屏蔽測試代碼中的 POSIX 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

6. 部分測試代碼條件編譯(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 路徑可寫,或以管理員身份運行。
  • 運行時找不到 DLL:將 libmemcached.dll、libsasl2.dll(若啟用)放入應用目錄或系統 PATH。
  • 驗證:編寫簡單測試程式鏈接 libmemcached.lib,調用 memcached_create()、memcached_set()、memcached_get() 確認功能正常。

總結

Windows 下編譯 libmemcached 的核心在於:斷開對 memcached.exe 的構建時依賴、屏蔽/替換缺失的 POSIX 標頭與函數、徹底解決解析器生成符號與 Windows SDK 巨集的命名空間衝突。上述修改均屬「最小侵入性」,不改變庫核心邏輯,編譯出的庫在生產環境穩定可用。

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