3

我正在使用以下 vpath 来尝试定位我的 $(OBJ) 文件:

vpath %.o ./lib/obj

我的目标是这样设置的:

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

查看输出时,我得到(对于所有 *.o 文件):

...error: misc.o: No such file or directory

我的项目结构如下:

.
├── 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_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 system_stm32f4xx.o

4

4 回答 4

5

$(OBJS)只是一个变量,并被扩展为文本。当它出现在link规则中的命令文本中时,它会简单地扩展为文本。

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

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

# Link target
link: main.elf

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

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

于 2013-02-26T21:27:11.347 回答
5

尽管其他答案在他们所说的细节上是正确的,但这里有一个更大的观点:不可能可靠地使用 VPATH/vpath 来查找派生文件,例如从 makefile 构建的 .o 文件。VPATH/vpath仅对查找文件有用,例如 .c 文件。

你应该阅读http://make.mad-scientist.net/vpath.html

于 2013-02-27T12:21:25.893 回答
3

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

# Link target
link: $(OBJS)
        @echo "\nLinking files"
        $(CC) $(LINK_FLAGS) -o main.elf $^
于 2013-02-26T21:27:27.523 回答
1

我已将以下内容添加到我的 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 文件。

于 2013-02-27T08:36:08.593 回答