Gcc Makefile vpath%.o找不到obj文件

Gcc Makefile vpath%.o找不到obj文件,gcc,makefile,Gcc,Makefile,我正在使用以下vpath尝试查找$(OBJ)文件: 我的目标是这样设置: # Link target link: @echo "\nLinking files" $(CC) $(LINK_FLAGS) -o main.elf $(OBJS) 查看输出时,我得到(对于所有*.o文件): 我的项目结构如下所示: . ├── Makefile ├── inc │   └── main.h ├── lib │   ├── inc │   │   ├── cmsis │   │   │ 

我正在使用以下vpath尝试查找$(OBJ)文件:

我的目标是这样设置:

# Link target
link:
    @echo "\nLinking files"
    $(CC) $(LINK_FLAGS) -o main.elf $(OBJS)
查看输出时,我得到(对于所有*.o文件):

我的项目结构如下所示:

.
├── Makefile
├── inc
│   └── main.h
├── lib
│   ├── inc
│   │   ├── cmsis
│   │   │   ├── arm_common_tables.h
│   │   │   ├── ...
│   │   ├── peripherals
│   │   │   ├── misc.h
│   │   │   ├── ...
│   │   └── stm32f4xx
│   │       ├── stm32f4xx.h
│   │       ├── ...
│   ├── obj
│   │   ├── misc.o
│   ├── src
│   │   ├── peripherals
│   │   │   ├── misc.c
│   │   │   ├── ...
│   │   └── system_stm32f4xx.c
│   └── startup_stm32f4xx.s
├── src
│   └── main.c
└── stm32f4.ld
为什么找不到我的.o文件

完整输出供参考:

arm none eabi gcc-T“stm32f3.ld”-nostartfiles-Wl,-Map,“main.Map” -mcpu=cortex-m4-mthumb-g3-gdwarf-2-L.“/”-o main.elf misc.o stm32f4xx_adc.o stm32f4xx_can.o stm32f4xx_crc.o stm32f4xx_cryp.o stm32f4xx_cryp.o stm32f4xx_cryp_aes.o stm32f4xx_cryp_des.o stm32f4xx_cryp_tdes.o stm32f4xx_dac.o stm32f4xx_dbgmcu.o stm32f4xx_dcmi.o stm32f4xx_dma.o stm32f4xx_exti.o stm32f4xx_flash.o stm32f4xx_fsmc.o stm32f4xx_gpio.o stm32f4xx_hash.o stm32f4xx_hash_md5.o stm32f4xx_hash_sha1.o stm32f4xx_i2c.o stm32f4xx_iwdg.o stm32f4xx_pwr.o stm32f4xx_rcc.o stm32f4xx_rng.o stm32f4xx_rtc.o stm32f4xx_sdio.o stm32f4xx_spi.o stm32f4xx_syscfg.o stm32f4xx_tim.o stm32f4xx_usart.o stm32f4xx_wwdg.o 系统_stm32f4xx.o

$(OBJS)
只是一个变量,可以作为文本展开。当它出现在
链接
规则中的命令文本中时,它将简单地展开为文本

vpath
搜索应用于先决条件,因此您必须安排将
$(OBJS)
作为链接规则的先决条件显示,并安排规则的命令(通过自动变量,而不是直接使用
$(OBJS)

所以你的规则需要看起来更像

# Link target
link: main.elf

main.elf: $(OBJS)
    @echo "\nLinking files"
    $(CC) $(LINK_FLAGS) -o $@ $+

(我还冒昧地写出了生成的文件(main.elf)作为中间规则的非虚假目标。将这些内容明确化通常是一个好主意。)

vpath
只告诉Make在哪里找到文件,而不是编译器/链接器。您必须让make告诉编译器/链接器它在哪里找到它们。最简单的方法是使它们具有适当的依赖关系(以便在链接之前重建它们),然后使用
$^

# Link target
link: $(OBJS)
        @echo "\nLinking files"
        $(CC) $(LINK_FLAGS) -o main.elf $^

我已将以下内容添加到我的Makefile中:

OBJS = $(LIB_SRC:.c=.o)
OBJ_FILES = $(addprefix lib/out/,$(notdir $(LIB_SRC:.c=.o)))
并更新了目标:

link:
    @echo "\nLinking files"
    $(CC) $(LINK_FLAGS) -o main.elf $(OBJ_FILES)

链接器现在正在正确地查找.o文件。

尽管其他答案在细节上是正确的,但这里有一个更重要的问题:无法可靠地使用VPATH/VPATH查找派生文件,例如从makefile生成的.o文件。VPATH/VPATH仅用于查找源文件,例如.c文件


您应该阅读

我仍然获得与我的问题相同的输出,它不会解析例如misc.o到./lib/out/misc.oI。我仍然获得与我的问题相同的输出,它不会解析例如misc.o到./lib/out/misc.oI。o@josef:您可能忽略了更改
$(CC).
行以使用自动变量(
$+
$^
)包含已解析的先决条件名称。如中所述,这是至关重要的。是的,这将是手工操作的繁琐方式。正如Chris指出的,您希望使对象文件成为链接规则的正确依赖项(以便在必要时重新生成它们;这是使用make的主要目的!)。此时,您还可以通过
vpath
/
$+
正确地执行此操作,并利用您现有的先决条件。
OBJS = $(LIB_SRC:.c=.o)
OBJ_FILES = $(addprefix lib/out/,$(notdir $(LIB_SRC:.c=.o)))
link:
    @echo "\nLinking files"
    $(CC) $(LINK_FLAGS) -o main.elf $(OBJ_FILES)