multiple definition of `err_sys' 《UNIX環境高級編程》

本文地址:http://www.cnblogs.com/yhLinux/p/4079930.htmlhtml

 

問題描述:linux

[點擊此處直接看解決方案]編程

在練習《UNIX環境高級編程》APUE程序清單8-7的時候,codelist8-7.c中用到了codelist15-3.c中的函數TELL_WAIT(),WAIT_PARENT()及TELL_CHILD()。bash

codelist8-7.c:ide

 1 #include "apue.h"
 2 
 3 static void charatatime(char *);
 4 
 5 int main(void)
 6 {
 7     pid_t    pid;
 8     TELL_WAIT();
 9 
10     if ((pid = fork()) < 0) {
11         err_sys("fork error");
12     } else if (pid == 0) {
13         WAIT_PARENT();    /* parent goes first */
14         charatatime("output from child\n");
15     } else {
16         charatatime("output from parent\n");
17         TELL_CHILD(pid);
18     }
19     exit(0);
20 }
21 
22 static void charatatime(char *str)
23 {
24     char    *ptr;
25     int    c;
26 
27     setbuf(stdout, NULL);    /* set unbuffered */
28     for (ptr = str; (c = *ptr++) != 0; )
29         putc(c, stdout);
30 }
codelist8-7.c

codelist15-3.c:函數

 1 #include "apue.h"
 2 
 3 static int    pfd1[2], pfd2[2];
 4 
 5 void TELL_WAIT(void)
 6 {
 7     if (pipe(pfd1) < 0 || pipe(pfd2) < 0)
 8         err_sys("pipe error");
 9 }
10 
11 void TELL_PARENT(pid_t pid)
12 {
13     if (write(pfd2[1], "c", 1) != 1)
14         err_sys("write error");
15 }
16 
17 void WAIT_PARENT(void)
18 {
19     char    c;
20 
21     if (read(pfd1[0], &c, 1) != 1)
22         err_sys("read error");
23     
24     if (c != 'p')
25         err_quit("WAIT_PARENT: incorrect data");
26 }
27 
28 void TELL_CHILD(pid_t pid)
29 {
30     if (write(pfd1[1], "p", 1) != 1)
31         err_sys("write error");
32 }
33 
34 void WAIT_CHILD(void)
35 {
36     char    c;
37 
38     if (read(pfd2[0], &c, 1) != 1)
39         err_sys("read error");
40     
41     if (c != 'c')
42         err_quit("WAIT_CHILD: incorrect data");
43 }
View Code

在使用命令編譯8-7時,提示如下錯誤:post

$ gcc codelist8-7.c codelist15-3.c -o 8-7
/tmp/ccMDAwpv.o: In function `err_ret':
codelist15-3.c:(.text+0x0): multiple definition of `err_ret'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0x0): first defined here
/tmp/ccMDAwpv.o: In function `err_sys':
codelist15-3.c:(.text+0xa9): multiple definition of `err_sys'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0xa9): first defined here
/tmp/ccMDAwpv.o: In function `err_exit':
codelist15-3.c:(.text+0x15a): multiple definition of `err_exit'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0x15a): first defined here
/tmp/ccMDAwpv.o: In function `err_dump':
codelist15-3.c:(.text+0x209): multiple definition of `err_dump'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0x209): first defined here
/tmp/ccMDAwpv.o: In function `err_msg':
codelist15-3.c:(.text+0x2b5): multiple definition of `err_msg'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0x2b5): first defined here
/tmp/ccMDAwpv.o: In function `err_quit':
codelist15-3.c:(.text+0x360): multiple definition of `err_quit'
/tmp/ccXi2EPL.o:codelist8-7.c:(.text+0x360): first defined here
collect2: ld 返回 1

查找網上意見以下:ui

1. http://bbs.chinaunix.net/thread-3699788-1-1.htmlurl

    我想是否是由於我在apue.h頭文件中,添加了#include "error.c",雖然apue.h中

    #ifndef __APUE_H__
    #define __APUE_H__

複製代碼
可是編譯器對每一個文件是分別編譯的,因此在文件wait.c和14.6.c中都#include "apue.h",就會包含兩份error.c文件,
而在error.c文件中是函數的定義(並非聲明),因此纔會出現這樣的狀況。 因此我刪除在apue.h中#include
"error.c",makefile文件以下: inc=/home/lee/program/apue/apue.2e/include/ error=/home/lee/program/apue/apue.2e/include/error.c a.out:14.6.c wait.c gcc -I $(inc) -o a.out 14.6.c wait.c $(error) 複製代碼 apue.h文件中/home/lee/program/apue/apue.2d/include/目錄下。 這樣就沒有問題了。 不知是否是如我想的這樣。

#沒錯,並且沒有充分理由時儘可能不要 include c 文件

以上這條討論講得比較到位吧,原來,我以前按這篇文章的方法[http://blog.csdn.net/quan9ing007/article/details/9929659此方法很差]把 apue.herror.h 都拷貝到 /usr/include 文件夾下了。spa

其實按上面的說法,不應把在apue.h中#include "error.c",並把 error.c 放到 /usr/include 目錄下的,在每一次編譯時添加error.c就好。

 

解決方案(推薦)

所以,只把 apue.h 放到/usr/include目錄下,而因爲要常常用到error.c,咱們將定義一個error環境變量,這樣就沒必要每次都把error.c拷貝到相關文件夾下參與編譯。

這裏假定當前用戶是Lee,error.c存放在/home/Lee/code_Lee/APUE/part_of_source/:

sudo cp /home/Lee/code_Lee/APUE/part_of_source/apue.h /usr/include/apue.h

sudo chmod a+r /usr/include/apue.h

vi /home/Lee/.bashrc 在.bashrc文末添加apue_error變量:

  apue_error=/home/Lee/code_Lee/APUE/part_of_source/error.c

source ~/.bashrc      /* 這很重要,必定要執行 */

echo ${apue_error}

  /home/Lee/code_Lee/APUE/part_of_source/error.c

gcc codelist8-6.c ${apue_error} -o 8-6 成功! 
gcc codelist8-7.c codelist15-3.c ${apue_error} -o 8-7  成功!!

 

(完)

參考資料:

1. Linux的環境變量

   http://www.cnblogs.com/Neddy/archive/2011/03/01/1968018.html

2. linux環境變量(轉)

   http://www.cnblogs.com/growup/archive/2011/07/02/2096142.html

相關文章
相關標籤/搜索