2013-03-01 84 views
12

如何解決編譯一個靜態的二進制文件,代碼包含一個函數調用gethostbyname如果編譯時沒有警告這樣的:編譯靜態二進制文件,代碼中有一個函數調用gethostbyname

警告:在靜態鏈接的應用程序中使用「的gethostbyname」 需要在運行時從使用 glibc的版本的共享庫用於鏈接

我編譯在Ubuntu 12.04與命令:

$ gcc -static lookup.c -o lookup 

這是lookup.c代碼:

/* lookup.c */ 

    #include <stdio.h> 
    #include <unistd.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <errno.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <arpa/inet.h> 
    #include <netdb.h> 

    extern int h_errno; 

    int main(int argc,char **argv) { 
    int x, x2; 
    struct hostent *hp; 

    for (x=1; x<argc; ++x) { 
     hp = gethostbyname(argv[x]); 
     if (!hp) { 
      fprintf(stderr, 
        "%s: host '%s'\n", 
        hstrerror(h_errno), 
        argv[x]); 
      continue; 
     } 

     printf("Host %s : \n" ,argv[x]); 
     printf(" Officially:\t%s\n", hp->h_name); 
     fputs(" Aliases:\t",stdout); 
     for (x2=0; hp->h_aliases[x2]; ++x2) { 
      if (x2) { 
       fputs(", ",stdout); 
      } 
     fputs(hp->h_aliases[x2],stdout); 
     }  
     fputc('\n',stdout); 
     printf(" Type:\t\t%s\n", 
       hp->h_addrtype == AF_INET 
       ? "AF_INET" : "AF_INET6"); 
     if (hp->h_addrtype == AF_INET) { 
      for (x2=0; hp->h_addr_list[x2]; ++x2) { 
       printf(" Address:\t%s\n", 
        inet_ntoa(*(struct in_addr *) 
         hp->h_addr_list[x2])); 
      } 
     } 
    putchar('\n'); 
    } 
    return 0; 
    } 

我想,如果我通過$ file lookup檢查將獲得的輸出是這樣的:

查找:ELF 32位LSB的可執行文件,英特爾80386版本1(GNU/Linux的), 靜態鏈接,用於GNU/Linux 2.6.24, BuildID [SHA1] = 0x6fcb2684ad8e5e842036936abb50911cdde47c73,不剝離

不喜歡這樣的:

查找:ELF 32位LSB的可執行文件,英特爾公司的80386,版本1(SYSV) 動態鏈接(使用共享庫),用於GNU/Linux 2.6.24, BuildID [ SHA1] = 0xf9f18671751927bea80de676d207664abfdcf5dc,不可剝離

如果您有建議我必須不帶靜電使用評論,因爲不同的libc每次我知道Linux的,我希望你不需要發表評論。 爲什麼我堅持靜態? 因爲我需要做強制使用靜態,二進制文件必須是靜態的,而不是動態的。

我有超過2個星期尋找這個,但到目前爲止還沒有成功。

感謝您幫助我解決我的沉重問題。

+2

總之:不要靜態鏈接這樣一個程序。像往常一樣動態鏈接到你的'libc.so' – 2013-03-01 19:53:20

+0

Hello Basile。爲什麼? – 2013-03-01 19:58:29

+0

如何做到這一點?什麼與-Bdynamic -lc -Wl? – 2013-03-01 19:59:26

回答

0

我有2個答案 -

  1. 保持你的程序靜態鏈接的主要部分,並分離出單一功能程序只是調用gethostbyname()。允許後者動態鏈接。使用fork然後exec執行這個單獨的程序來獲取域名的地址。除了fork之外,exec可以使用system(),儘管它需要更長的時間(整個毫秒),不應該擔心,因爲無論如何你都要在互聯網上搜索域名服務器,這需要一段時間。

  2. 編寫源代碼來完成DNS,就像我所做的那樣。將其編譯到檔案(.a)中,並在靜態鏈接中進行搜索。

5

我得到了同樣的警告,並解決它我重新編譯glibc。配置使其開啓時,打開開關--enable-static-nss

相關問題