Gcc 如何编写包含多个目录的Makefile
我有以下设置。在主文件夹中有两个名为/driverlib和/inc的文件夹,在同一文件夹中,我有一个链接器文件和两个c文件,startup_gcc和blink.cGcc 如何编写包含多个目录的Makefile,gcc,makefile,arm,Gcc,Makefile,Arm,我有以下设置。在主文件夹中有两个名为/driverlib和/inc的文件夹,在同一文件夹中,我有一个链接器文件和两个c文件,startup_gcc和blink.c #include <stdbool.h> #include <stdint.h> #include "inc/hw_can.h" #include "inc/hw_ints.h" #include "inc/hw_nvic.h" #include "inc/hw_memmap.h" #include "inc/
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
我遵循了我在网上找到的STM32F4模板。我修改了它,并试图在我的文件夹中包含这两个目录。但是,我得到以下错误:
C:\Users\D\Documents\ARM-Tiva\blinky3>make
driverlib/adc.c:49:24: fatal error: inc/hw_adc.h: No such file or directory
compilation terminated.
make: *** [driverlib/adc.o] Error 1
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
有人能给我解释一下如何包括这两个目录,以便/inc文件夹对/driverlib文件夹可见
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
以下是生成文件:
OBJCOPY = $(TC)-objcopy
OBJDUMP = $(TC)-objdump
SIZE = $(TC)-size
###################################################
# Set Include Paths
INCLUDES = -I /inc
INCLUDES = -I /driverlib
# Set Sources
LIB_SRCS = $(wildcard driverlib/*.c)
USER_SRCS = $(wildcard src/*.c)
# Set Objects
LIB_OBJS = $(LIB_SRCS:.c=.o)
USER_OBJS = $(USER_SRCS:.c=.o) startup_gcc.o
# Set Libraries
LIBS = -lm -lc
###################################################
# Set Board
MCU = -mthumb -mcpu=cortex-m4
DEFINES = -DPART_LM4F120H5QR -DTARGET_IS_BLIZZARD_RA1
# Set Compilation and Linking Flags
CFLAGS = $(MCU) $(FPU) $(DEFINES) $(INCLUDES) \
-g -Wall -std=gnu90 -O0 -ffunction-sections -fdata-sections
ASFLAGS = $(MCU) $(FPU) -g -Wa,--warn -x assembler-with-cpp
LDFLAGS = $(MCU) $(FPU) -g -gdwarf-2 \
-Ttivalinker.ld \
-Xlinker --gc-sections -Wl,-Map=$(PROJ_NAME).map \
$(LIBS) \
-o $(PROJ_NAME).elf
###################################################
# Default Target
all: $(PROJ_NAME).bin info
# elf Target
$(PROJ_NAME).elf: $(LIB_OBJS) $(USER_OBJS)
@$(CC) $(LIB_OBJS) $(USER_OBJS) $(LDFLAGS)
@echo $@
# bin Target
$(PROJ_NAME).bin: $(PROJ_NAME).elf
@$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
@echo $@
#$(PROJ_NAME).hex: $(PROJ_NAME).elf
# @$(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex
# @echo $@
#$(PROJ_NAME).lst: $(PROJ_NAME).elf
# @$(OBJDUMP) -h -S $(PROJ_NAME).elf > $(PROJ_NAME).lst
# @echo $@
# Display Memory Usage Info
info: $(PROJ_NAME).elf
@$(SIZE) --format=berkeley $(PROJ_NAME).elf
# Rule for .c files
.c.o:
@$(CC) $(CFLAGS) -c -o $@ $<
@echo $@
# Rule for .s files
.s.o:
@$(CC) $(ASFLAGS) -c -o $@ $<
@echo $@
# Clean Target
clean:
$(RM) $(LIB_OBJS)
$(RM) $(USER_OBJS)
$(RM) $(PROJ_NAME).elf
$(RM) $(PROJ_NAME).bin
$(RM) $(PROJ_NAME).map
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
我无法理解为什么driverlib不包含inc目录文件
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
编辑
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
我想澄清我的设置以供将来参考:在名为blinky的主文件夹中,我有三个文件夹:driverlib,inc和src。driverlib和inc文件夹取自TivaWARE文件夹,而src文件夹包含blinky.c和startup_gcc.c文件。如果使用以下选项,则可以获得以下内容:
C:\Users\D\Documents\ARM-Tiva\blinky>make
driverlib/adc.c:49:24: fatal error: inc/hw_adc.h: No such file or directory
compilation terminated.
make: *** [driverlib/adc.o] Error 1
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
这表明driverlib文件夹中的文件adc.c不能包含中的文件hw_adc.h
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
我按照以下建议修改了Makefile:
# Set Sources
LIB_SRCS = $(wildcard driverlib/*.c)
USER_SRCS = $(wildcard src/*.c)
# Set Objects
LIB_OBJS = $(LIB_SRCS:.c=.o)
USER_OBJS = $(USER_SRCS:.c=.o) src/startup_gcc.o
# Set Include Paths
INCLUDES = -Idriverlib/ \
-Iinc \
-Isrc/
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
Betas解决方案很有帮助,唯一的问题是我不想编辑driverlib文件夹中的所有文件。目录的命名约定不是我的决定。如果您可以查看driverlib文件夹中的所有文件,您会发现每个驱动程序文件(例如can驱动程序或ADC)都遵循以下约定:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#包括
#包括
#包括“inc/hw_can.h”
#包括“inc/hw_ints.h”
#包括“inc/hw_nvic.h”
#包括“inc/hw_memmap.h”
#包括“inc/hw_sysctl.h”
#包括“inc/hw_types.h”
#包括“driverlib/can.h”
#包括“driverlib/debug.h”
#包括“driverlib/interrupt.h”
所以现在我知道问题出在哪里了,但我缺乏编辑Makefile的理解。
通常,如果文件can.c和can.h位于driverlib文件夹中,那么使用#include“can.h”就足够了,因此我不明白如果所有的.h和.c文件都位于同一driverlib文件夹中,那么使用#include“driverlib/can.h”有什么意义。如果我编辑所有inc/头,那么我可以得到一个工作的二进制文件。但是,目的不是修改从TI获得的默认库存驱动程序文件和文件夹,而是使用Makefile
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
因此,为了澄清您是否遵循Betas解决方案并编辑所有文件,或者如果您将所有文件放在一个大目录中,那么您可以得到一个工作的二进制文件。另外,为了将来参考,我发现我可以使用Energia来完成我的工作,因为它使用相同的编译器,TIVA包括在ROM上烧掉的完整外围库。我不知道错误的确切原因,但这是不正确的:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
INCLUDES = -I /inc
# Now INCLUDES is "-I /inc"
INCLUDES = -I /driverlib
# Now INCLUDES is "-I /driverlib", and inc has been forgotten.
我想你的意思是:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
INCLUDES = -I /inc
INCLUDES += -I /driverlib
编辑:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
在#include指令中详细说明路径通常是个坏主意。在adc.c中,更改以下内容:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "inc/hw_adc.h"
为此:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "hw_adc.h"
并在makefile中删除前面的斜杠(因为您并不总是在根目录中):
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
最有用的是,如果您在问题中提供了一个未找到的头文件的实际完整路径,以及make在错误消息之外运行的示例编译行。考虑到这些信息,很难看出哪里出了问题
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
看来有一些沟通失误发生了。在主文件夹上写两个名为/driverlib和/inc的文件夹。根据定义,以/
开头的文件夹名位于目录结构的根目录中,而不在任何其他文件夹中。我不知道你说的主文件夹是什么意思
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
我要说的第一件事是您正在使用Windows(从命令行提示符可以看到),因此您需要确保您正在使用的make版本将正确地将Windows路径名转换为UNIX路径名。例如,如果您使用的是Cygwin版本的GNU make,那么我认为您使用的路径是不正确的
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
其次,我注意到您使用的是-I/inc
;也就是说,inc
目录位于文件系统的根目录。这是你的本意吗?Beta的答案将其更改为-I inc
,这意味着目录inc
作为当前工作目录的子目录,可能会有很大不同
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
第三,如果标题的路径名是/inc/hw_adc.h
,并且您的命令行上有-I/inc
,并且#包括“inc/hw_adc.h”
,我相信您可以看到这绝对不起作用。编译器将查找名为/inc/inc/hw_adc.h
的头文件。如果要在#include
行中保留相对路径名inc/hw_adc.h
,并且头文件的路径是/inc/hw_adc.h
,则应在编译命令行上使用-I/
(根目录)
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
最后,我要说,我实际上不同意Beta的建议,即在包含行中拼写路径是个坏主意。这是很常见的:如果您使用的库包含很多头文件,那么头文件通常收集在一个子目录中(考虑Boost或X11等),在源代码的#include
行中使用子目录的名称是一种良好的做法
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
另一方面,尽管如此,我同意Beta的说法,像
inc
这样的目录名是完全无用的。该目录应该有一个名称,该名称在某种程度上能让人联想到目录中可以找到的各种标题,而不是像“inc”这样无用的通用名称。可能是一个重复的问题:我已经尝试过了。我仍然会犯同样的错误。我也试着阅读Make手册,但没有太多成功。“inc/hw_adc.h”不在“/inc”或“/driverlib”中。如果您已经在include路径中添加了“inc/”,那么您可以将“inc/hw_adc.h”替换为“hw_adc.h”
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/can.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"