Library include not detecting header in include path

两盒软妹~` 提交于 2019-12-11 13:01:13

问题


I am trying to set up a makefile project using the mbed library for use in a larger project I am wanting to do later on. I have the project directory set up like this...

.
|-- Doxyfile
|-- NUCLEO_F446RE.mk
|-- Nucleo_blink.map
|-- asm
|-- attach.gdb
|-- debug
|-- gdb-pipe.cfg
|-- lib
|   `-- mbed
|       |-- AnalogIn.h
|       |-- ...
|       |-- TARGET_NUCLEO_F446RE
|       |   |-- TARGET_STM
|       |   |   `-- TARGET_STM32F4
|       |   |       |-- PeripheralPins.h
|       |   |       |-- TARGET_NUCLEO_F446RE
|       |   |       |   |-- PeripheralNames.h
|       |   |       |   |-- PinNames.h
|       |   |       |   |-- PortNames.h
|       |   |       |   |-- device.h
|       |   |       |   `-- objects.h
|       |   |       `-- gpio_object.h
|       |   |-- TOOLCHAIN_GCC_ARM
|       |   |   |-- STM32F446XE.ld
|       |   |   |-- board.o
|       |   |   |-- ...
|       |   |   `-- system_stm32f4xx.o
|       |   |-- arm_common_tables.h
|       |   |-- ...
|       |   `-- system_stm32f4xx.h
|       |-- Ticker.h
|       |-- ...
|       `-- wait_api.h
|-- makefile
|-- obj
|-- release
`-- src
    `-- main.cc

Specifically, my error is in lib/mbed/platform.h, which tries to include device.h. I have a makefile that should add it to the include path, but g++ still seems to be unable to find it. Here is the exact error...

arm-none-eabi-g++    -c -o main.o source/main.cc
In file included from source/../lib/mbed/mbed.h:21:0,
                from source/main.cc:1:
source/../lib/mbed/platform.h:21:20: fatal error: device.h: No such file or directory
#include "device.h"
                    ^
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1

Line 1 of main.cc is #include "../lib/mbed/mbed.h"

NUCLEO_F446RE.mk defines the device-specific include path I am using, and I hope to be able to be able to choose the .mk file to use based on a variable I pass to the makefile, so that I can easily use a different mbed board if I want. Here are the contents of NUCLEO_F446RE.mk...

HARDFP = 1

LIBRARY_PATHS = -L./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM 

CPU = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=$(FLOAT_ABI)

LINKER_SCRIPT = ./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/STM32F446XE.ld

CC_SYMBOLS = -DTARGET_M4 -DMBED_BUILD_TIMESTAMP=1453683815.81 -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -DTARGET_RTOS_M4_M7 -DTARGET_FF_MORPHO -DTARGET_CORTEX_M -D__FPU_PRESENT=1 -DTARGET_FF_ARDUINO -DTARGET_STM32F446RE -DTARGET_NUCLEO_F446RE -D__MBED__=1 -DTARGET_STM -DTARGET_STM32F4 -D__CORTEX_M4 -DARM_MATH_CM4

INCLUDE_PATHS = -I./lib/ -I./lib/mbed/ \
-I./lib/mbed/TARGET_NUCLEO_F446RE/ \
-I./lib/mbed/TARGET_NUCLEO_F44\6RE/TARGET_STM/ \
-I./lib/mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4/ \
-I./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/ \
-I./lib/mbed/TARGET_NUCLEO_F446RE/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F446RE/ #<--device.h is here

SYS_OBJECTS = ./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash_ramfunc.o \
./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/board.o \
...

For good measure, here is my makefile. I have been trying to keep everything as neat as possible.

#Project parameters
PROJECT = Nucleo_blink
OBJECTS = main.o
DEST    = debug
VPATH   = src lib $DEST
TARGET  = NUCLEO_F446RE

#Compilation options
DEBUG = 1

#Tools
AS      = $(GCC_BIN)arm-none-eabi-as
CC      = $(GCC_BIN)arm-none-eabi-gcc
CXX     = $(GCC_BIN)arm-none-eabi-g++
LD      = $(GCC_BIN)arm-none-eabi-gcc
OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump
SIZE    = $(GCC_BIN)arm-none-eabi-size 

include $(TARGET).mk

CFLAGS = $(INCLUDE_PATHS) $(CC_SYMBOLS) $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -Wextra -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer -MMD -MP

ifeq ($(HARDFP),1)
        FLOAT_ABI = hard
else
        FLOAT_ABI = softfp
endif

ifeq ($(DEBUG), 1)
        CFLAGS += -DDEBUG -O0
else
        CFLAGS += -DNDEBUG -Os
endif

LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -Wl,--wrap,main -Wl,-Map=$(PROJECT).map,--cref
LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys

LIBRARIES = -lmbed 

.PHONY: all clean lst size

all: $(PROJECT).bin $(PROJECT).hex

clean:
        rm -f debug/* obj/* asm/* $(DEPS)

obj/%.o: %.c #<---Attempt to fix target error mentioned by @user657267
        $(CC)  $(CC_FLAGS) $(CC_SYMBOLS) -std=c99 $(INCLUDE_PATHS) -o obj/$@ $<

obj/%.o: %.cc
        $(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o obj/$@ $<

obj/%.o: %.cpp
        $(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o obj/$@ $<

obj/%.o: %.asm
        $(CC) $(CPU) -c -x assembler-with-cpp -o asm/$@ $<

$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
        $(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $(DEST)/$@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)

$(PROJECT).bin: $(PROJECT).elf
        $(OBJCOPY) -O binary $< $@

$(PROJECT).hex: $(PROJECT).elf
        @$(OBJCOPY) -O ihex $< $@

$(PROJECT).lst: $(PROJECT).elf
        @$(OBJDUMP) -Sdh $< > $@

lst: $(PROJECT).lst

size: $(PROJECT).elf
        $(SIZE) $(PROJECT).elf

DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
-include $(DEPS)

A lot of the code I have here is based on the output from the online mbed IDE after exporting a simple project to a makefile. However, the export had everything in a single directory, and that will be extremely messy as I start doing larger projects and possibly add more libraries. The strange part is that this project compiles without any errors when I use the single-directory exported version. What is going on here? Why is g++ not seeing device.h in my multi-directory version?

EDITS 2016-05-09: Minor tweaks to makefile, same error.


回答1:


%.o: %.cc %.cpp

This pattern rule is (probably) incorrect, you're telling make to apply this rule if and only if both the .cc and .cpp files exist (or can be made by other rules). As main.cpp presumably doesn't exist make will fall back to its built-in implicit rule, which obviously won't know about INCLUDE_PATHS or any other of the unconventional variables you're using for flags.

You can fix this by making the two rules separate

%.o: %.cc
    $(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o obj/$@ $<
%.o: %.cpp
    $(CXX) $(CC_FLAGS) $(CC_SYMBOLS) -std=c++98 -fno-rtti $(INCLUDE_PATHS) -o obj/$@ $<

These rules are still broken however, as when one of them matches something like ./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash_ramfunc.o you're going to place it into obj/./lib/mbed/TARGET_NUCLEO_F446RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash_ramfunc.o, which means make will always recompile the object because it won't be where you've said it should be (check out the informal Rules of Makefiles, specifically 2).



来源:https://stackoverflow.com/questions/37106184/library-include-not-detecting-header-in-include-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!