[英]How to write Makefile to include multi directories
我有以下設置。 在主文件夾和同一文件夾上的兩個名為/ driverlib和/ inc的文件夾中,我有一個鏈接器文件和兩個c文件,startup_gcc和blink.c。
我遵循了我在網上找到的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
有人可以向我解釋如何同時包含兩個目錄,以便/ inclib文件夾對/ driverlib文件夾可見。
這是makefile:
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
問題顯然在此段:
###################################################
# 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
我不明白為什么driverlib不包含inc目錄文件。
編輯
我想澄清一下設置,以備將來參考:在名為blinky的主文件夾中,我有三個文件夾:driverlib,inc和src。 driverlib和inc文件夾來自TivaWARE文件夾,而src文件夾包含blinky.c和startup_gcc.c文件。 如果使用make給出以下信息,則將獲得以下信息:
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
這表明driverlib文件夾中的文件adc.c不能在其中包含文件hw_adc.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/
Beta解決方案很有幫助,唯一的問題是我不想編輯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"
所以現在我知道問題出在哪里,但我缺乏對Makefile進行編輯的理解。 通常,如果文件can.c和can.h使用#include“ can.h”存放在driverlib文件夾中就足夠了,所以我不明白如果所有.h和.c都使用#include“ driverlib / can.h”有什么意義?文件位於同一driverlib文件夾中。 如果我編輯所有的inc /標頭,那么我可以獲得一個有效的二進制文件。 但是,其目的不是修改從TI獲得的默認庫存驅動程序文件和文件夾,而是使用Makefile。
因此,澄清一下您是否遵循Beta測試解決方案並編輯所有文件,或者是否將所有文件放在一個大目錄中,則可以獲得一個可用的二進制文件。 另外,作為將來的參考,我發現我可以使用Energia做我的事,因為它使用相同的編譯器,並且TIVA包括在ROM上刻錄的完整外圍設備庫。
我不知道確切的錯誤原因,但這是不正確的:
INCLUDES = -I /inc
# Now INCLUDES is "-I /inc"
INCLUDES = -I /driverlib
# Now INCLUDES is "-I /driverlib", and inc has been forgotten.
我想你的意思是:
INCLUDES = -I /inc
INCLUDES += -I /driverlib
編輯:
在#include指令中拼出路徑通常是個壞主意。 在adc.c
,更改以下內容:
#include "inc/hw_adc.h"
對此:
#include "hw_adc.h"
並在makefile中刪除前導斜杠(因為您將不會始終位於根目錄中):
INCLUDES = -I inc
INCLUDES += -I driverlib
如果您提供了問題中沒有找到的頭文件之一的實際完整路徑,並且提供了除錯誤消息外還由make運行的示例編譯行,那將是最有幫助的事情。 鑒於這些信息,看看有什么問題很簡單。
看來有些溝通不暢。 您在主文件夾上寫了兩個名為/ driverlib和/ inc的文件夾 。 按照定義,以/
開頭的文件夾名稱位於目錄結構的根目錄中,而不位於任何其他文件夾中。 我不知道您在主文件夾中的意思 。
我要說的第一件事是您正在使用Windows(從命令行提示符可以看到),因此您需要確保使用的make版本能夠正確轉換Windows路徑名UNIX路徑名。 例如,如果您正在使用Cygwin版本的GNU make,那么我認為您使用的路徑不正確。
其次,我注意到您正在使用-I /inc
; 也就是說, inc
目錄位於文件系統的根目錄。 那是你想要的嗎? Beta的答案已將其更改為-I inc
,這意味着目錄inc
作為當前工作目錄的子目錄,可能會大不相同。
第三,如果標頭的路徑名是/inc/hw_adc.h
並且命令行上有-I /inc
,並且#include "inc/hw_adc.h"
,我敢肯定,您可以看到它絕對不起作用。 編譯器將查找名為/inc/inc/hw_adc.h
頭文件。 如果要將相對路徑名inc/hw_adc.h
在#include
行中,並且頭文件的路徑為/inc/hw_adc.h
,則應在編譯時僅使用-I /
(根目錄)命令行。
最后,我要說的是我實際上不同意Beta的建議,即在包含行中拼寫出路徑是一個壞主意。 這很常見:如果您使用的庫包含很多頭文件,則通常將頭文件收集在子目錄中(考慮諸如Boost或X11等之類的東西),IMO,使用名稱的好習慣源代碼中的#include
行中的子目錄。
但是,另一方面,我將同意Beta的觀點,即像inc
這樣的目錄名完全是me腳的,幾乎毫無用處。 該目錄應具有某種名稱,該名稱以某種方式喚起了可以在其中找到的頭的名稱,而不是像“ inc”這樣無用的通用名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.