程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 基於Windows平台編譯libmemcached的步驟

基於Windows平台編譯libmemcached的步驟

編輯:關於C語言

 

1. 下載MinGW32到本地,以便能夠使用gcc編譯器以及和linux相關的一些庫文件。

2. 由於libmemcached的測試程序需要依賴memcached.exe本身,如果需要將memcached在win32下編譯,需要修改部分和socket相關的code,而又考慮到僅僅是測試用例需要,因此決定通過修改configure(由autoconfig用於生成makefile的配置信息檢查的shell文件)文件,以使libmemcached的編譯不在依賴memcached。

3. 為了完成第二步,需要手工修改configure文件,將如下shell代碼注釋掉,以便在執行./configure的時候不再將memcached.exe作為一個必須的配置檢查條件。注: 在該文件中搜索--with-memcached即可找到以下code

# 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

 

 

  # just ignore the user if --without-memcached is passed.. it is

  # only used by make test

#  if test "x$withval" = "xno"; then :

#

#      ac_cv_with_memcached=memcached

#      MEMC_BINARY=memcached

 

#else

#

#       if test -f "$withval"; then :

#

#           ac_cv_with_memcached=$withval

#           MEMC_BINARY=$withval

#

#else

#

           # Extract the first word of "$ac_cv_with_memcached", so it can be a program name with args.

#set dummy $ac_cv_with_memcached; ac_word=$2

#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

#$as_echo_n "checking for $ac_word... " >&6; }

#if test "${ac_cv_path_MEMC_BINARY+set}" = set; then :

#  $as_echo_n "(cached) " >&6

#else

#  case $MEMC_BINARY in

#  [\\/]* | ?:[\\/]*)

#  ac_cv_path_MEMC_BINARY="$MEMC_BINARY" # Let the user override the test with a path.

#  ;;

#  *)

#  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR

#for as_dir in $PATH

#do

#  IFS=$as_save_IFS

#  test -z "$as_dir" && as_dir=.

#    for ac_exec_ext in '' $ac_executable_extensions; do

#  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then

#    ac_cv_path_MEMC_BINARY="$as_dir/$ac_word$ac_exec_ext"

#    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5

#    break 2

#  fi

#done

#  done

#IFS=$as_save_IFS

 

#  test -z "$ac_cv_path_MEMC_BINARY" && ac_cv_path_MEMC_BINARY=""no""

#  ;;

#esac

#fi

#MEMC_BINARY=$ac_cv_path_MEMC_BINARY

#if test -n "$MEMC_BINARY"; then

#  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MEMC_BINARY" >&5

#$as_echo "$MEMC_BINARY" >&6; }

#else

#  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5

#$as_echo "no" >&6; }

#fi

#

#

#           if test "x$MEMC_BINARY" = "xno"; then :

#  as_fn_error $? "\"could not find memcached binary\"" "$LINENO" 5

#fi

#

#fi

#

#fi

 

#cat >>confdefs.h <<_ACEOF

#define MEMCACHED_BINARY "$MEMC_BINARY"

#_ACEOF

4.  從以上代碼中可以發現MEMCACHED_BINARY宏是需要在程序中用到的,此時需要手工將用到該宏的地方進行修改,如下: (請參見libtest/server.c,同時搜索字符串MEMCACHED_BINARY)

        if (x == 0)

        {

//            原有代碼

//          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]);

//            修改為

            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(buffer, sizeof(buffer), "%s -d -P %s -t 1 -p %u -U %u",

//                   MEMCACHED_BINARY, construct->pid_file[x], construct->port[x], construct->port[x]);

//            修改為

            snprintf(buffer, sizeof(buffer), "-d -P %s -t 1 -p %u -U %u",

                     construct->pid_file[x], construct->port[x], construct->port[x]);

        }

5. 將./libmemcached/options/server.h中的//#include <arpa/inet.h>代碼注釋掉,因為win32中沒有該文件。

6. 由於最初已經決定不編譯測試用例,因此需要將./libtest/server.c文件中的部分代碼注釋掉,我這裡的做法是將部分和linux相關的code使用如下方式注釋掉:(注:不能將該文件全部注釋掉,因為其他的測試文件需要依賴這裡聲明的函數,如果全部注釋,將會導致其他的測試文件無法正常鏈接)

#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

}

 

7. 修改./libmemcached/options/目錄下面的三個文件parser.cc, parser.h, scanner.cc,這3個文件中均包含ERROR,TRUE,FALSE 和FLOAT等4個枚舉的成員,由於和win32中的相應的宏沖突了,結果導致無法編譯通過,特別還會report與yacc和lex相關的錯誤,我這裡的做法是在這3個文件中,將所有和這四個枚舉相關的地方均改為ERROR1,TRUE1,FALSE1和FLOAT1。(注意大小寫敏感)

   //1. 該段代碼位於parser.h

    enum yytokentype {

     COMMENT = 258,

     END = 259,

     ERROR1 = 260,

     ... ...

     TRUE1 = 315,

     FALSE1 = 316,

     FLOAT1 = 317,

     ... ...

    }

 

    //2. 該段代碼位於parser.cc

    enum yytokentype {

     COMMENT = 258,

     END = 259,

     ERROR1 = 260,

     ... ...

     TRUE1 = 315,

     FALSE1 = 316,

     FLOAT1 = 317,

     ... ...

    }

 

    static const char *const yytname[] =

    {

        "$end", "error", "$undefined", "COMMENT", "END", "ERROR1",

         ... ...

        "TRUE1", "FALSE1", "','", "'='", "FLOAT1", ... ..., 0

    };

 

    //3. 該段代碼位於scanner.cc

    case 44:

        YY_RULE_SETUP

        #line 133 "libmemcached/options/scanner.l"

        { yyextra->begin= yytext; return ERROR1; }

    YY_BREAK

    case 45:

        YY_RULE_SETUP

        #line 135 "libmemcached/options/scanner.l"

        { return TRUE1; }

    YY_BREAK

    case 46:

        YY_RULE_SETUP

        #line 136 "libmemcached/options/scanner.l"

        { return FALSE1; }

    YY_BREAK

8. 注釋掉./clients/memslap.c中的如下代碼//#include <sys/mman.h>,因為該文件為linux中內存管理的文件,win32並未提供相應的文件,因此可以直接注釋掉。

9. 最後修改./tests/parser.cc中和access相關的3個函數(access是linux中文件相關的函數),其中的#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;

 

  memcached_st *memc_ptr;

  memc_ptr= memcached(STRING_WITH_LEN("--CONFIGURE-FILE=\"support/example.cnf\""));

  test_true_got(memc_ptr, memcached_last_error_message(memc_ptr));

  memcached_free(memc_ptr);

#endif

 

  return TEST_SUCCESS;

}

 

test_return_t libmemcached_check_configuration_with_filename_test(memcached_st*)

{

#ifndef WIN32

  if (access(SUPPORT_EXAMPLE_CNF, R_OK))

    return TEST_SKIPPED;

 

  memcached_return_t rc;

  char buffer[BUFSIZ];

 

  rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=\"support/example.cnf\""), buffer, sizeof(buffer));

  test_true_got(rc == MEMCACHED_SUCCESS, buffer);

 

  rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=support/example.cnf"), buffer, sizeof(buffer));

  test_false_with(rc == MEMCACHED_SUCCESS, buffer);

 

  rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=\"bad-path/example.cnf\""), buffer, sizeof(buffer));

  test_true_got(rc == MEMCACHED_ERRNO, buffer);

#endif

  return TEST_SUCCESS;

}

 

test_return_t test_include_keyword(memcached_st*)

{

#ifndef WIN32

  if (access(SUPPORT_EXAMPLE_CNF, R_OK))

    return TEST_SKIPPED;

 

  char buffer[BUFSIZ];

  memcached_return_t rc;

  rc= libmemcached_check_configuration(STRING_WITH_LEN("INCLUDE \"support/example.cnf\""), buffer, sizeof(buffer));

  test_true_got(rc == MEMCACHED_SUCCESS, buffer);

#endif

  return TEST_SUCCESS;

}

10. 記著編譯成功後make install.

摘自 Stephen_Liu

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved