Makefile 如何告诉Make搜索头文件

Makefile 如何告诉Make搜索头文件,makefile,avr,avr-gcc,Makefile,Avr,Avr Gcc,如果我想编译一个简单的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+=$(I

如果我想编译一个简单的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 ***

生成文件中的这一行是问题的原因:

build: avr.o
这是什么意思?它告诉make,为了创建名为
build
的目标,它应该查找名为
avr.o
的目标,该目标可能已经存在,或者如果不存在,make应该构建它(如果它能够弄清楚如何做)

因此,在make-even尝试运行此规则的配方之前,它将首先尝试创建一个文件
avr.o

好吧,您还没有告诉它如何创建这样一个文件,但幸运的是(或不幸的是)make有一组内置规则,它可以使用这些规则创建它知道的某些类型的文件。其中一个内置规则说,如果make想要构建一个文件
*.o
(对于一些匹配
*
)并且它可以找到一个文件
*.c
(其中
*
*.o
中的相同),那么它可以使用以下方法创建
*.o

$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
如果您查看错误消息列表的顶部,make将打印它运行的编译行,您将看到它不是您希望它运行的编译行

所以,你有很多方法来解决这个问题

一种选择是保留变量并修复规则:

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
,因为这是您的配方所期望的(它从a.c构建a.o,因此.c是先决条件)。然而,这确实是一个非常糟糕的makefile;这是“make的无用用法”,因为每次键入
make
时,它都会重建
avr.o
文件

更好的方法是修复makefile,使其使用标准的预定义变量设置而不是您自己的变量,并让make使用其内置规则生成对象文件:

CC = avr-gcc
CPPFLAGS = -I/usr/avr/include
CFLAGS = -mmcu=atmega2560 -Os

build: avr.o
这就是你要做的一切(你说“构建一个简单的AVR C程序”,但是你的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

生成文件中的这一行是问题的原因:

build: avr.o
这是什么意思?它告诉make,为了创建名为
build
的目标,它应该查找名为
avr.o
的目标,该目标可能已经存在,或者如果不存在,make应该构建它(如果它能够弄清楚如何做)

因此,在make-even尝试运行此规则的配方之前,它将首先尝试创建一个文件
avr.o

好吧,您还没有告诉它如何创建这样一个文件,但幸运的是(或不幸的是)make有一组内置规则,它可以使用这些规则创建它知道的某些类型的文件。其中一个内置规则说,如果make想要构建一个文件
*.o
(对于一些匹配
*
)并且它可以找到一个文件
*.c
(其中
*
*.o
中的相同),那么它可以使用以下方法创建
*.o

$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
如果您查看错误消息列表的顶部,make将打印它运行的编译行,您将看到它不是您希望它运行的编译行

所以,你有很多方法来解决这个问题

一种选择是保留变量并修复规则:

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
,因为这是您的配方所期望的(它从a.c构建a.o,因此.c是先决条件)。然而,这确实是一个非常糟糕的makefile;这是“make的无用用法”,因为每次键入
make
时,它都会重建
avr.o
文件

更好的方法是修复makefile,使其使用标准的预定义变量设置而不是您自己的变量,并让make使用其内置规则生成对象文件:

CC = avr-gcc
CPPFLAGS = -I/usr/avr/include
CFLAGS = -mmcu=atmega2560 -Os

build: avr.o
这就是你要做的一切(你说“构建一个简单的AVR C程序”,但是你的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

注意:ledblink.c和avr.c不一样(至少名称不同)。我不相信你的说法,当在Makefile中使用相同的命令时,它不会编译。在Makefile中使用相同的命令(no CC,INCLUDE,CCFLAGS)并告诉我们这是否有效。ledblink.c/avr.c是我的复制粘贴错误-修复了问题中的错误。第二点,是的,你是对的。问题不是CC,而是
build:avr.o
。我用
build:
替换了它,现在它可以编译了。我只是对错误消息感到困惑,在这种情况下,它似乎与我无关。谢谢你的帮助!注意:ledblink.c和avr.c不一样(至少名称不同)。我不相信