簡體   English   中英

如何編寫Makefile以包含多個目錄

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM