当 GNU Make 执行 gcc 时,gcc 无法找到 stdio.h 函数和身份的定义

问题描述 投票:0回答:2

我正在学习 GNU Make 和 makefile 是如何工作的。
我有一个包含 7 个 *.c 和 *.h 文件以及一个 main.c 文件的小项目。


这是生成文件:

CC = "gcc"
CFLAGS = "-std=c11"

#PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
# the PATH variable is set after I got the error. But adding this didnt change the result

src := src/lib
bin := bin

project:        $(bin)/aaa.o $(bin)/bbb.o $(bin)/ccc.o $(bin)/ddd.o $(bin)/eee.o $(bin)/fff.o $(bin)/main.o
                $(CC) $(CFLAGS) $(bin)/aaa.o $(bin)/bbb.o $(bin)/ccc.o $(bin)/ddd.o $(bin)/eee.o $(bin)/fff.o $(bin)/main.o -o $(bin)/project


$(bin)/aaa.o:   $(src)/aaa.c $(src)/ddd.h
                $(CC) $(CFLAGS) -c $(src)/aaa.c

$(bin)/bbb.o:   $(src)/bbb.c $(src)/aaa.h $(src)/bbb.h $(src)/ddd.h $(src)/fff.h
                $(CC) $(CFLAGS) -c $(src)/bbb.c

$(bin)/ccc.o:   $(src)/ccc.c $(src)/aaa.h $(src)/fff.h
                $(CC) $(CFLAGS) -c $(src)/ccc.c


# ... (and so on for all other .o files


clean:          
                rm $(bin)/*

#包含在文件中

aaa.c

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "aaa.h"
#include "ddd.h"

bbb.c

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aaa.h"
#include "bbb.h"
#include "ddd.h"
#include "fff.h"

ccc.c

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

#include "aaa.h"
#include "fff.h"

运行时,它给了我这个错误:

"gcc" "-std=c11" -c src/lib/aaa.c
src/lib/aaa.c: In function ‘init_fileSize’:
src/lib/aaa.c:103:14: warning: implicit declaration of function ‘fileno’ [-Wimplicit-function-declaration]
  103 |     if((fd = fileno(arg->srcstream)) == -1)
      |              ^~~~~~
"gcc" "-std=c11" -c src/lib/bbb.c
"gcc" "-std=c11" -c src/lib/ccc.c
src/lib/ccc.c: In function ‘closeProgram’:
src/lib/ccc.c:10:15: error: ‘STDIN_FILENO’ undeclared (first use in this function)
   10 |     tcsetattr(STDIN_FILENO, TCSANOW, &(trml->termios_default));
      |               ^~~~~~~~~~~~
src/lib/ccc.c:10:15: note: each undeclared identifier is reported only once for each function it appears in
make: *** [makefile:19: bin/ccc.o] Error 1

从错误消息中,我得出结论,gcc 无法找到在标准头文件(如 stdio.h)中声明的函数和其他标识的定义。

如何解决这个问题?

c gcc makefile gnu-make c-standard-library
2个回答
3
投票

这些预处理器符号和函数不是标准 C 的一部分。它们在 POSIX 标准中定义。

在程序启动时,与 流 stdin、stdout 和 stderr 是 0、1 和 2, 分别。 预处理器符号STDIN_FILENO, STDOUT_FILENO 和 STDERR_FILENO 是用这些值定义的 .

所以你失踪了:

#include <unistd.h>

对于宏。

fileno(3)
(在
stdio.h
中声明),需要定义一个特性测试宏:

/* Before including any headers, define this at the top. */
#define _POSIX_C_SOURCE 200819L

/* Now include the headers. */

或者,您可以将

-std=cXX
替换为
-std=gnuXX
,这将包括对语言的各种扩展。


1
投票

从错误消息中,我得出结论,gcc 无法找到在标准头文件(如 stdio.h)中声明的函数和其他标识的定义。

是的,但这与找不到

stdio.h
本身不同。如果它找不到标头,那么它也会发出有关该标头的诊断信息。

第一期在这里:

CFLAGS = "-std=c11"

告诉编译器不要对 C 语言启用句法和语义扩展。它告诉编译器默认不启用任何标准库扩展。标准库中与整数文件句柄有关的所有内容都属于后一类,特别包括

fileno()
函数和
STDIN_FILENO
宏。

此外,

stdio.h
不是
STDIN_FILENO
宏的记录位置。如果启用了适当的功能,您仍然可以从
stdio.h
获得它,但是该宏的 (POSIX) 标准位置是标头
unistd.h
。整个标题是一个扩展。

在您想要使用

-std=c11
选项编译并且还想访问这些库功能的源文件中,您需要在任何
#include
指令之前定义适当的功能测试宏。并且您应该包括记录的标头以提供您需要的任何特定功能,而不是依赖于从未记录的来源获取它们。例如,

#define _POSIX_C_SOURCE 200809L

// ...

#include <stdio.h>
#include <unistd.h>

// ...

.

© www.soinside.com 2019 - 2024. All rights reserved.