如何告诉 Make 搜索头文件
How to tell Make to search for header files
如果我想编译一个简单的 AVR C 程序,我会直接去:
avr-gcc -mmcu=atmega2560 -Os avr.c -o avr.o
并且代码编译时没有错误。但是,一旦我将上述命令放入 Makefile 中,就会出现编译错误,指出 DDRC
、PC2
和 PORTC
未声明(请参阅底部的错误块) .由于这些常量是在 avr/io.h 中定义的,所以我尝试使用 -I 参数来指向头文件,但没有成功。这是我的 Makefile:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
$(CC) -mmcu=atmega2560 -Os avr.c -o avr.o
我发现了类似的问题 ,但我没有幸运地应用该解决方案。我认为问题在于 avr-gcc
无法找到所需的库,我认为 -I
指令可以解决这个问题。但似乎我正在犯一些我找不到的愚蠢错误。告诉 Makefile 头文件在哪里的正确方法是什么?
仅在调用时出现的错误信息make build
:
avr.c: In function 'main':
avr.c:17:5: error: 'DDRC' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~~
avr.c:17:5: note: each undeclared identifier is reported only once for each function it appears in
avr.c:17:16: error: 'PC2' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~
avr.c:19:9: error: 'PORTC' undeclared (first use in this function)
PORTC &= ~(1<<PC2);/* PC2 LOW */
^~~~~
make: *** [<builtin>: avr.o] Error 1
*** Failure: Exit code 2 ***
avr.c
我正在尝试使用 make
:
进行编译
#define F_CPU 100000000
#include <avr/io.h>
#include <util/delay.h>
void sleep(uint8_t millisec)
{
while (millisec) {
_delay_ms(1);/* 1 ms delay */
millisec--;
}
}
int main()
{
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
while (1) {
PORTC &= ~(1<<PC2);/* PC2 LOW */
sleep(100);/* 100 ms delay */
PORTC |=(1<<PC2); /* PC2 HIGH */
sleep(100);/* 100 ms delay */
}
return 0;
}
您的 makefile 中的这一行是导致您出现问题的原因:
build: avr.o
这是什么意思?它告诉 make 为了创建一个名为 build
的目标,它应该寻找一个名为 avr.o
的目标,或者已经存在,或者如果它不存在,那么 make 应该构建它(如果它可以弄清楚如何这样做)。
因此,在 make 甚至尝试 运行 此规则的配方之前,它将 FIRST 尝试创建一个文件 avr.o
.
好吧,您还没有告诉它如何创建这样的文件,但幸运的是(或者对您来说不幸的是)make 有一组内置规则,它可以使用这些规则来创建它知道的某些类型的文件关于。其中一个内置规则说,如果 make 想要构建一个文件 *.o
(对于某些字符串匹配 *
),它可以找到一个文件 *.c
(其中 *
与 *.o
中的相同),然后它可以使用此配方创建 *.o
:
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
这是如何扩展的?好吧,您已将 CC
设置为 avr-cc
,因此它将使用该编译器。您还没有设置 CFLAGS
、CXXFLAGS
或 TARGET_ARCH
,因此它将使用这些变量的默认值,这没什么。所以,它将 运行 这个编译行:
avr-cc -c -o avr.o avr.c
如果您查看错误消息列表的顶部,make 将打印编译行 运行s 并且您会发现它不是您想要的编译行 运行.
所以,您有很多方法可以解决这个问题。
一种选择是保留您的变量并修复您的规则:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o
在这里,我们将 build
先决条件列为 avr.c
而不是 avr.o
,因为这是您的配方所期望的(它从 .c 构建 .o,因此 .c是前提)。然而,这确实是一个非常糟糕的 makefile;这是一个 "useless use of make" 因为每次你键入 make
它都会重建 avr.o
文件。
更好的方法是修复您的 makefile 以使用标准的预定义变量设置而不是您自己的变量,并让 make 使用其内置规则构建目标文件:
CC = avr-gcc
CPPFLAGS = -I/usr/avr/include
CFLAGS = -mmcu=atmega2560 -Os
build: avr.o
这就是你要做的(你说 "build a simple AVR C program" 但是你的 makefile 只编译一个目标文件,它不调用链接器,所以我不知道你到底想做什么)。
如果你真的想保留自己的规则而不使用内置规则,那么至少要正确编写,以便配方构建的文件是makefile规则中的目标:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
avr.o: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o
如果我想编译一个简单的 AVR C 程序,我会直接去:
avr-gcc -mmcu=atmega2560 -Os avr.c -o avr.o
并且代码编译时没有错误。但是,一旦我将上述命令放入 Makefile 中,就会出现编译错误,指出 DDRC
、PC2
和 PORTC
未声明(请参阅底部的错误块) .由于这些常量是在 avr/io.h 中定义的,所以我尝试使用 -I 参数来指向头文件,但没有成功。这是我的 Makefile:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
$(CC) -mmcu=atmega2560 -Os avr.c -o avr.o
我发现了类似的问题 avr-gcc
无法找到所需的库,我认为 -I
指令可以解决这个问题。但似乎我正在犯一些我找不到的愚蠢错误。告诉 Makefile 头文件在哪里的正确方法是什么?
仅在调用时出现的错误信息make build
:
avr.c: In function 'main':
avr.c:17:5: error: 'DDRC' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~~
avr.c:17:5: note: each undeclared identifier is reported only once for each function it appears in
avr.c:17:16: error: 'PC2' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~
avr.c:19:9: error: 'PORTC' undeclared (first use in this function)
PORTC &= ~(1<<PC2);/* PC2 LOW */
^~~~~
make: *** [<builtin>: avr.o] Error 1
*** Failure: Exit code 2 ***
avr.c
我正在尝试使用 make
:
#define F_CPU 100000000
#include <avr/io.h>
#include <util/delay.h>
void sleep(uint8_t millisec)
{
while (millisec) {
_delay_ms(1);/* 1 ms delay */
millisec--;
}
}
int main()
{
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
while (1) {
PORTC &= ~(1<<PC2);/* PC2 LOW */
sleep(100);/* 100 ms delay */
PORTC |=(1<<PC2); /* PC2 HIGH */
sleep(100);/* 100 ms delay */
}
return 0;
}
您的 makefile 中的这一行是导致您出现问题的原因:
build: avr.o
这是什么意思?它告诉 make 为了创建一个名为 build
的目标,它应该寻找一个名为 avr.o
的目标,或者已经存在,或者如果它不存在,那么 make 应该构建它(如果它可以弄清楚如何这样做)。
因此,在 make 甚至尝试 运行 此规则的配方之前,它将 FIRST 尝试创建一个文件 avr.o
.
好吧,您还没有告诉它如何创建这样的文件,但幸运的是(或者对您来说不幸的是)make 有一组内置规则,它可以使用这些规则来创建它知道的某些类型的文件关于。其中一个内置规则说,如果 make 想要构建一个文件 *.o
(对于某些字符串匹配 *
),它可以找到一个文件 *.c
(其中 *
与 *.o
中的相同),然后它可以使用此配方创建 *.o
:
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
这是如何扩展的?好吧,您已将 CC
设置为 avr-cc
,因此它将使用该编译器。您还没有设置 CFLAGS
、CXXFLAGS
或 TARGET_ARCH
,因此它将使用这些变量的默认值,这没什么。所以,它将 运行 这个编译行:
avr-cc -c -o avr.o avr.c
如果您查看错误消息列表的顶部,make 将打印编译行 运行s 并且您会发现它不是您想要的编译行 运行.
所以,您有很多方法可以解决这个问题。
一种选择是保留您的变量并修复您的规则:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o
在这里,我们将 build
先决条件列为 avr.c
而不是 avr.o
,因为这是您的配方所期望的(它从 .c 构建 .o,因此 .c是前提)。然而,这确实是一个非常糟糕的 makefile;这是一个 "useless use of make" 因为每次你键入 make
它都会重建 avr.o
文件。
更好的方法是修复您的 makefile 以使用标准的预定义变量设置而不是您自己的变量,并让 make 使用其内置规则构建目标文件:
CC = avr-gcc
CPPFLAGS = -I/usr/avr/include
CFLAGS = -mmcu=atmega2560 -Os
build: avr.o
这就是你要做的(你说 "build a simple AVR C program" 但是你的 makefile 只编译一个目标文件,它不调用链接器,所以我不知道你到底想做什么)。
如果你真的想保留自己的规则而不使用内置规则,那么至少要正确编写,以便配方构建的文件是makefile规则中的目标:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
avr.o: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o