本文地址:http://www.CUOXin.com/yhlinux/p/4079930.html
問(wèn)題描述:
[點(diǎn)擊此處直接看解決方案]
在練習(xí)《UNIX環(huán)境高級(jí)編程》APUE程序清單8-7的時(shí)候,codelist8-7.c中用到了codelist15-3.c中的函數(shù)TELL_WAIT(),WAIT_PARENT()及TELL_CHILD()。
codelist8-7.c:
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時(shí),提示以下錯(cuò)誤:
$ 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 herecollect2: ld 返回 1
查找網(wǎng)上意見(jiàn)如下:
1. http://bbs.chinaunix.net/thread-3699788-1-1.html
我想是不是因?yàn)槲以赼pue.h頭文件中,添加了#include "error.c",雖然apue.h中 #ifndef __APUE_H__ #define __APUE_H__復(fù)制代碼但是編譯器對(duì)每個(gè)文件是分別編譯的,所以在文件wait.c和14.6.c中都#include "apue.h",就會(huì)包含兩份error.c文件,而在error.c文件中是函數(shù)的定義(并不是聲明),所以才會(huì)出現(xiàn)這樣的情況。所以我刪除在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)復(fù)制代碼apue.h文件中/home/lee/program/apue/apue.2d/include/目錄下。這樣就沒(méi)有問(wèn)題了。不知是不是如我想的這樣。#沒(méi)錯(cuò),而且沒(méi)有充分理由時(shí)盡量不要 include c 文件
以上這條討論講得比較到位吧,原來(lái),我之前按這篇文章的方法[http://blog.csdn.net/quan9ing007/article/details/9929659此方法不好]把 apue.h 和 error.h 都拷貝到 /usr/include 文件夾下了。
其實(shí)按上面的說(shuō)法,不該把在apue.h中#include "error.c",并把 error.c 放到 /usr/include 目錄下的,在每一次編譯時(shí)添加error.c就好。
解決方案(推薦):
因此,只把 apue.h 放到/usr/include目錄下,而由于要經(jīng)常用到error.c,我們將定義一個(gè)error環(huán)境變量,這樣就不必每次都把error.c拷貝到相關(guān)文件夾下參與編譯。
這里假定當(dāng)前用戶是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.hsudo chmod a+r /usr/include/apue.hvi /home/Lee/.bashrc 在.bashrc文末添加apue_error變量: apue_error=/home/Lee/code_Lee/APUE/part_of_source/error.csource ~/.bashrc /* 這很重要,一定要執(zhí)行 */echo ${apue_error} /home/Lee/code_Lee/APUE/part_of_source/error.cgcc codelist8-6.c ${apue_error} -o 8-6 成功! gcc codelist8-7.c codelist15-3.c ${apue_error} -o 8-7 成功!!
(完)
參考資料:
1. Linux的環(huán)境變量
http://www.CUOXin.com/Neddy/archive/2011/03/01/1968018.html
2. linux環(huán)境變量(轉(zhuǎn))
http://www.CUOXin.com/growup/archive/2011/07/02/2096142.html
新聞熱點(diǎn)
疑難解答
圖片精選