如何告诉Make搜索头文件

时间:2017-04-23 20:04:11

标签: makefile avr avr-gcc

如果我想编译一个简单的AVR C程序,我只想去:

avr-gcc -mmcu=atmega2560 -Os avr.c -o avr.o

代码编译时没有错误。但是,只要我将上述命令放在Makefile中,我就会收到编译错误,指出DDRCPC2PORTC未声明(请参阅底部的错误块) 。由于这些常量是在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

我发现了一个类似的问题here,但我没有幸运应用该解决方案。我认为问题出在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;
} 

1 个答案:

答案 0 :(得分:4)

makefile中的这一行是导致问题的原因:

build: avr.o

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

因此,在尝试运行此规则的配方之前,它将 FIRST 尝试创建文件avr.o

好吧,你还没有告诉它如何创建这样的文件,但幸运的是(或者不幸的是)make有一组内置的规则可以用来创建它知道的某些类型的文件。其中一条内置规则说如果make想要构建一个文件*.o(对于某些字符串匹配*),它可以找到一个文件*.c(其中**.o)中的相同,然后它可以使用此配方创建*.o

$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<

这是如何扩展的?好吧,您已将CC设置为avr-cc,因此它将使用该编译器。您尚未设置CFLAGSCXXFLAGSTARGET_ARCH,因此它将使用这些变量的默认值,这不是什么。因此,它将运行此编译行:

avr-cc -c -o avr.o avr.c

如果你查看错误消息列表的顶部,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,因为这是您的食谱所期望的(它从.c构建.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
相关问题