文章目录
- Error: unable to disambiguate: -dylib (did you mean --dylib ?)
- undefined reference to `major'
- error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
- error: ‘FILE’ has no member named ‘_flag’; did you mean ‘_flags’?
- error: ‘FILE’ has no member named ‘_base’, ‘_ptr’
- /usr/bin/ld: cannot find -lbsd: No such file or directory
- 后续
- 参考
下载这本书《Advanced Programming in the UNIX Environment》的源代码,解压后的文件夹名字为apue.3e,然后使用make编译,遇到的各种问题汇总
Error: unable to disambiguate: -dylib (did you mean --dylib ?)
请参考笔者的另一篇博文:WSL中/usr/bin/ld: Error: unable to disambiguate: -dylib (did you mean --dylib ?)解决方案
undefined reference to `major’
遇到问题:
making filedir
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/filedir'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE access.c -o access -L../lib -lapue
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE cdpwd.c -o cdpwd -L../lib -lapue
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE changemod.c -o changemod -L../lib -lapue
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE devrdev.c -o devrdev -L../lib -lapue
devrdev.c: In function ‘main’:
devrdev.c:19:39: warning: implicit declaration of function ‘major’ [-Wimplicit-function-declaration]
19 | printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
| ^~~~~
devrdev.c:19:59: warning: implicit declaration of function ‘minor’ [-Wimplicit-function-declaration]
19 | printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
| ^~~~~
/usr/bin/ld: /tmp/ccASensu.o: in function `main':
devrdev.c:(.text+0xcb): undefined reference to `minor'
/usr/bin/ld: devrdev.c:(.text+0xe1): undefined reference to `major'
/usr/bin/ld: devrdev.c:(.text+0x131): undefined reference to `minor'
/usr/bin/ld: devrdev.c:(.text+0x147): undefined reference to `major'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:18: devrdev] Error 1
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/filedir'
make: *** [Makefile:6: all] Error 1
解决方法
打开devrdev.c文件,在#endif
下面添加#include <sys/sysmacros.h>
头文件,然后再执行make编译。
对sys/sysmacros.h
的介绍
sys/sysmacros.h
头文件包含了一些宏(macros)和函数原型,通常用于处理文件系统相关的信息。这个头文件在 POSIX 操作系统(包括Linux)上比较常见。下面是一些可能包含在 sys/sysmacros.h
头文件中的内容:
-
宏定义:
major(dev)
:从设备号中提取主设备号。minor(dev)
:从设备号中提取次设备号。makedev(major, minor)
:根据主次设备号创建设备号。
-
函数原型:
dev_t makedev(int major, int minor)
:根据主次设备号创建设备号。这个函数的功能类似于宏makedev
。
这些宏和函数通常用于解析设备号,这在处理设备文件和文件系统时可能很有用。设备号是一个整数,包含主设备号和次设备号,用于唯一标识设备。这些宏和函数使得从设备号中提取主次设备号更加方便。
请注意,具体的宏和函数可能会因系统而异。在编写代码时,最好查看相关平台的文档,以确保正确使用这些宏和函数。
error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
遇到问题
making stdio
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE buf.c -o buf -L../lib -lapue
buf.c: In function ‘is_unbuffered’:
buf.c:90:15: error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
90 | #define _flag __pad[4]
| ^~~~~
buf.c:98:20: note: in expansion of macro ‘_flag’
98 | return(fp->_flag & _IONBF);
| ^~~~~
buf.c: In function ‘is_linebuffered’:
buf.c:90:15: error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
90 | #define _flag __pad[4]
| ^~~~~
buf.c:104:20: note: in expansion of macro ‘_flag’
104 | return(fp->_flag & _IOLBF);
| ^~~~~
buf.c: In function ‘buffer_size’:
buf.c:92:15: error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
92 | #define _base __pad[2]
| ^~~~~
buf.c:111:20: note: in expansion of macro ‘_base’
111 | return(fp->_base - fp->_ptr);
| ^~~~~
buf.c:91:14: error: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?
91 | #define _ptr __pad[1]
| ^~~~~
buf.c:111:32: note: in expansion of macro ‘_ptr’
111 | return(fp->_base - fp->_ptr);
| ^~~~
buf.c: In function ‘is_unbuffered’:
buf.c:99:1: warning: control reaches end of non-void function [-Wreturn-type]
99 | }
| ^
buf.c: In function ‘is_linebuffered’:
buf.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
105 | }
| ^
buf.c: In function ‘buffer_size’:
buf.c:115:1: warning: control reaches end of non-void function [-Wreturn-type]
115 | }
| ^
make[1]: *** [Makefile:16: buf] Error 1
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
make: *** [Makefile:6: all] Error 1
解决方案
删除这5行
#ifdef _LP64
#define _flag __pad[4]
#define _ptr __pad[1]
#define _base __pad[2]
#endif
如下图所示
然后make遇到如下的问题
error: ‘FILE’ has no member named ‘_flag’; did you mean ‘_flags’?
遇到问题
making stdio
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE buf.c -o buf -L../lib -lapue
buf.c: In function ‘is_unbuffered’:
buf.c:94:20: error: ‘FILE’ has no member named ‘_flag’; did you mean ‘_flags’?
94 | return(fp->_flag & _IONBF);
| ^~~~~
| _flags
buf.c: In function ‘is_linebuffered’:
buf.c:100:20: error: ‘FILE’ has no member named ‘_flag’; did you mean ‘_flags’?
100 | return(fp->_flag & _IOLBF);
| ^~~~~
| _flags
buf.c: In function ‘buffer_size’:
buf.c:107:18: error: ‘FILE’ has no member named ‘_base’
107 | return(fp->_base - fp->_ptr);
| ^~
buf.c:107:30: error: ‘FILE’ has no member named ‘_ptr’
107 | return(fp->_base - fp->_ptr);
| ^~
buf.c: In function ‘is_unbuffered’:
buf.c:95:1: warning: control reaches end of non-void function [-Wreturn-type]
95 | }
| ^
buf.c: In function ‘is_linebuffered’:
buf.c:101:1: warning: control reaches end of non-void function [-Wreturn-type]
101 | }
| ^
buf.c: In function ‘buffer_size’:
buf.c:111:1: warning: control reaches end of non-void function [-Wreturn-type]
111 | }
| ^
make[1]: *** [Makefile:16: buf] Error 1
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
make: *** [Makefile:6: all] Error 1
解决方法
将下面代码中的flag修改为flags
#elif defined(_IONBF)
ints
is_unbuffered(FILE *fp)
{
return(fp->_flags & _IONBF); //修改此处
}
int
is_linebuffered(FILE *fp)
{s
return(fp->_flags & _IOLBF); // 修改此处
}
int
buffer_size(FILE *fp)
{
#ifdef _LP64
return(fp->_base - fp->_ptr);
#else
return(BUFSIZ); /* just a guess */
#endif
}
#else
#error unknown stdio implementation!
#endif
修改的位置如下图所示
然后发现报错
error: ‘FILE’ has no member named ‘_base’, ‘_ptr’
making stdio
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE buf.c -o buf -L../lib -lapue
buf.c: In function ‘buffer_size’:
buf.c:107:18: error: ‘FILE’ has no member named ‘_base’
107 | return(fp->_base - fp->_ptr);
| ^~
buf.c:107:30: error: ‘FILE’ has no member named ‘_ptr’
107 | return(fp->_base - fp->_ptr);
| ^~
buf.c:111:1: warning: control reaches end of non-void function [-Wreturn-type]
111 | }
| ^
make[1]: *** [Makefile:16: buf] Error 1
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/stdio'
make: *** [Makefile:6: all] Error 1
解决方法
替换这里:
return(fp->_base - fp->_ptr);
替换为
return(fp->_IO_buf_end - fp->_IO_buf_base);
未修改之前如下图:
修改之后如下图:
/usr/bin/ld: cannot find -lbsd: No such file or directory
遇到问题
making threadctl
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/threadctl'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE atfork.c -o atfork -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE suspend.c -o suspend -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o detach.o detach.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o getenv1.o getenv1.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o getenv2.o getenv2.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o getenv3.o getenv3.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o timeout.o timeout.c
timeout.c: In function ‘main’:
timeout.c:119:12: warning: ‘condition’ may be used uninitialized [-Wmaybe-uninitialized]
119 | if (condition) {
| ^
timeout.c:125:48: warning: ‘arg’ may be used uninitialized [-Wmaybe-uninitialized]
125 | timeout(&when, retry, (void *)((unsigned long)arg));
| ~^~~~~~~~~~~~~~~~~~~
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/threadctl'
making threads
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/threads'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE badexit2.c -o badexit2 -L../lib -lapue -pthread -lrt -lbsd
/usr/bin/ld: cannot find -lbsd: No such file or directory
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:31: badexit2] Error 1
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/threads'
make: *** [Makefile:6: all] Error 1
解决方法
sudo apt-get install -y libbsd-dev
会安装 libbsd-dev
和libmd-dev
。
后续
继续make,会遇到sprintf的警告,可以不用管。
making printer
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/printer'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o print.o print.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o util.o util.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -o print print.o util.o ../sockets/clconn2.o -L../lib -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o printd.o printd.c
printd.c: In function ‘build_qonstart’:
printd.c:362:39: warning: ‘%s’ directive writing up to 255 bytes into a region of size 40 [-Wformat-overflow=]
362 | sprintf(fname, "%s/%s/%s", SPOOLDIR, REQDIR, entp->d_name);
| ^~
printd.c:362:17: note: ‘sprintf’ output between 25 and 280 bytes into a destination of size 64
362 | sprintf(fname, "%s/%s/%s", SPOOLDIR, REQDIR, entp->d_name);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
printd.c:375:47: warning: ‘%s’ directive writing up to 255 bytes into a region of size 40 [-Wformat-overflow=]
375 | sprintf(fname, "%s/%s/%s", SPOOLDIR, DATADIR,
| ^~
printd.c:375:25: note: ‘sprintf’ output between 25 and 280 bytes into a destination of size 64
375 | sprintf(fname, "%s/%s/%s", SPOOLDIR, DATADIR,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
376 | entp->d_name);
| ~~~~~~~~~~~~~
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -o printd printd.o util.o ../sockets/clconn2.o ../sockets/initsrv2.o \
-L../lib -L../lib -lapue -pthread
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/printer'
最后编译成功的样子
making exercises
make[1]: Entering directory '/mnt/d/lishizheng/apue/apue.3e/exercises'
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE bo.c -o bo -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE fifo1.c -o fifo1 -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE getlogin.c -o getlogin -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE goodexit.c -o goodexit -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE longpath.c -o longpath -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE pendlock.c -o pendlock -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE prtime.c -o prtime -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE sizepipe.c -o sizepipe -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE vfork3.c -o vfork3 -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE zombie.c -o zombie -L../lib -lapue -pthread
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o asyncsocket.o asyncsocket.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o openmax.o openmax.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o sleep.o sleep.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o sleepus_poll.o sleepus_poll.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE -c -o sleepus_select.o sleepus_select.c
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE getpwsvr4.c -o getpwsvr4 -L../lib -lapue -pthread
make[1]: Leaving directory '/mnt/d/lishizheng/apue/apue.3e/exercises'
参考
[1]《Unix环境高级编程》第三版源代码在CentOS 7、Ubuntu 20.04和Ubuntu 22.04上编译