简体   繁体   English

如何编写Makefile以包含多个目录

[英]How to write Makefile to include multi directories

I have the following setup. 我有以下设置。 Two folders named /driverlib and /inc on the main folder and on the same folder I have a linker file and two c files, startup_gcc and blink.c. 在主文件夹和同一文件夹上的两个名为/ driverlib和/ inc的文件夹中,我有一个链接器文件和两个c文件,startup_gcc和blink.c。

I followed a template I found online for STM32F4. 我遵循了我在网上找到的STM32F4模板。 I modified it and tried to include both directories on my folder. 我对其进行了修改,并尝试将这两个目录都包含在我的文件夹中。 However I am getting the following error: 但是我收到以下错误:

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

Can somebody explain to me how to include both directories so that the /inc folder is visible to the /driverlib folder. 有人可以向我解释如何同时包含两个目录,以便/ inclib文件夹对/ driverlib文件夹可见。

Here's the makefile: 这是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

The issue is obviously at this paragraph: 问题显然在此段:

###################################################
# 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

I cannot understand why driverlib does not include the inc directory files. 我不明白为什么driverlib不包含inc目录文件。

EDIT 编辑

I wanted to clarify my setup for future reference: On the main folder called blinky I have three folders : driverlib, inc and src. 我想澄清一下设置,以备将来参考:在名为blinky的主文件夹中,我有三个文件夹:driverlib,inc和src。 The driverlib and inc folders are taken from the TivaWARE folder while the src folder contains the blinky.c and startup_gcc.c file. driverlib和inc文件夹来自TivaWARE文件夹,而src文件夹包含blinky.c和startup_gcc.c文件。 Given the following if you use make you obtain the following : 如果使用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   

This shows that the file adc.c in the driverlib folder cannot include the file hw_adc.h in 这表明driverlib文件夹中的文件adc.c不能在其中包含文件hw_adc.h。

I modified the Makefile following the suggestions below: 我按照以下建议修改了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/

Betas solution was helpful , the only issue was that I did not want to edit all the files in the driverlib folder. Beta解决方案很有帮助,唯一的问题是我不想编辑driverlib文件夹中的所有文件。 The naming convention of the directories was not my decision. 目录的命名约定不是我的决定。 If you can see all the files in the driverlib folder you'll find out that each driver file , CAN driver for example or ADC) follows this convention : 如果您可以看到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" 

So right now I understand where the issue is but I lack the understanding to edit the Makefile. 所以现在我知道问题出在哪里,但我缺乏对Makefile进行编辑的理解。 Normally if files can.c and can.h are in folder driverlib using #include "can.h" would suffice so I do not understand what's the point of using #include "driverlib/can.h" if all .h and .c files are in the same driverlib folder . 通常,如果文件can.c和can.h使用#include“ can.h”存放在driverlib文件夹中就足够了,所以我不明白如果所有.h和.c都使用#include“ driverlib / can.h”有什么意义?文件位于同一driverlib文件夹中。 If I edit all the inc/ header then I can get a working binary file. 如果我编辑所有的inc /标头,那么我可以获得一个有效的二进制文件。 The aim however was not to modify the default stock driver files and folders obtained from TI but to use the Makefile. 但是,其目的不是修改从TI获得的默认库存驱动程序文件和文件夹,而是使用Makefile。

So to clarify if you follow Betas solution and edit all the files , or if you put all the files in one big directory then you can get a working binary file. 因此,澄清一下您是否遵循Beta测试解决方案并编辑所有文件,或者是否将所有文件放在一个大目录中,则可以获得一个可用的二进制文件。 Also for future reference I found I could use Energia for what I am doing since it uses the same compiler and TIVA includes the complete peripheral library burned on ROM. 另外,作为将来的参考,我发现我可以使用Energia做我的事,因为它使用相同的编译器,并且TIVA包括在ROM上刻录的完整外围设备库。

I don't know the cause of the error exactly, but this is not correct: 我不知道确切的错误原因,但这是不正确的:

INCLUDES    = -I /inc 

# Now INCLUDES is "-I /inc"

INCLUDES    = -I /driverlib

# Now INCLUDES is "-I /driverlib", and inc has been forgotten.

I think you mean this: 我想你的意思是:

INCLUDES    = -I /inc 
INCLUDES    += -I /driverlib

EDIT: 编辑:

It's generally a bad idea to spell out paths in the #include directives. 在#include指令中拼出路径通常是个坏主意。 In adc.c , change this: adc.c ,更改以下内容:

#include "inc/hw_adc.h"

to this: 对此:

#include "hw_adc.h"

and in the makefile remove the leading slashes (since you won't always be in the root directory): 并在makefile中删除前导斜杠(因为您将不会始终位于根目录中):

INCLUDES    = -I inc 
INCLUDES    += -I driverlib

The most helpful thing would have been if you had provided the actual complete path of one of the header files which is not being found, in your question, and an example compile line run by make in addition to the error message. 如果您提供了问题中没有找到的头文件之一的实际完整路径,并且提供了除错误消息外还由make运行的示例编译行,那将是最有帮助的事情。 Given that information it's trivial to see what's wrong. 鉴于这些信息,看看有什么问题很简单。

It looks like some miscommunication is happening. 看来有些沟通不畅。 You write two folders named /driverlib and /inc on the main folder . 在主文件夹上写了两个名为/ driverlib和/ inc的文件夹 A folder name that begins with a / is by definition at the root of the directory structure, not within any other folder. 按照定义,以/开头的文件夹名称位于目录结构的根目录中,而不位于任何其他文件夹中。 I don't know what you mean by on the main folder . 我不知道您在主文件夹中的意思

The first thing I'll say is that you're using Windows (as can be seen by your command line prompt), and so you need to be sure that the version of make you're using will do the right thing converting Windows pathnames to UNIX pathnames. 我要说的第一件事是您正在使用Windows(从命令行提示符可以看到),因此您需要确保使用的make版本能够正确转换Windows路径名UNIX路径名。 For example if you're using Cygwin version of GNU make, then I think the paths you're using are not correct. 例如,如果您正在使用Cygwin版本的GNU make,那么我认为您使用的路径不正确。

Second, I note that you are using -I /inc ; 其次,我注意到您正在使用-I /inc ; that is, the inc directory is at the root of your filesystem. 也就是说, inc目录位于文件系统的根目录。 Is that what you intended? 那是你想要的吗? Beta's answers have changed that to -I inc , which means the directory inc as a subdirectory of the current working directory, which could be quite different. Beta的答案已将其更改为-I inc ,这意味着目录inc作为当前工作目录的子目录,可能会大不相同。

Third, if the pathname to the headers is /inc/hw_adc.h and you have -I /inc on your command line and #include "inc/hw_adc.h" , I'm sure you can see how this will absolutely not work. 第三,如果标头的路径名是/inc/hw_adc.h并且命令行上有-I /inc ,并且#include "inc/hw_adc.h" ,我敢肯定,您可以看到它绝对不起作用。 The compiler will be looking for header files named /inc/inc/hw_adc.h . 编译器将查找名为/inc/inc/hw_adc.h头文件。 If you want to keep the relative pathname inc/hw_adc.h in your #include line, and the path to the header file is /inc/hw_adc.h , then you should use just -I / (the root directory) on the compile command line. 如果要将相对路径名inc/hw_adc.h#include行中,并且头文件的路径为/inc/hw_adc.h ,则应在编译时仅使用-I / (根目录)命令行。

Lastly, I'll say that I actually don't agree with Beta's suggestion that it's a bad idea to spell out paths in include lines. 最后,我要说的是我实际上不同意Beta的建议,即在包含行中拼写出路径是一个坏主意。 This is common: if you are using a library that contains a lot of header files then typically the header files are collected in a subdirectory (consider things like Boost, or X11, etc.) and it's, IMO, good practice to use the name of the subdirectory in your #include lines in the source code. 这很常见:如果您使用的库包含很多头文件,则通常将头文件收集在子目录中(考虑诸如Boost或X11等之类的东西),IMO,使用名称的习惯源代码中的#include行中的子目录。

On the other hand, though, I will agree with Beta that a directory name like inc is utterly lame and is of pretty much no use whatever. 但是,另一方面,我将同意Beta的观点,即像inc这样的目录名完全是me脚的,几乎毫无用处。 That directory should have a name which is somehow evocative of the kinds of headers that can be found inside it, not something uselessly generic like "inc". 该目录应具有某种名称,该名称以某种方式唤起了可以在其中找到的头的名称,而不是像“ inc”这样无用的通用名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM