rizsotto / Bear

Bear is a tool that generates a compilation database for clang tooling.
GNU General Public License v3.0
4.79k stars 314 forks source link

arm-none-eabi-gcc: stdlib.h reported by clangd as missing when missing "/" in arguments of compile_commands.json #379

Closed bleonars closed 3 years ago

bleonars commented 3 years ago

Issue The bear generated compile_commands.json causes coc.clangd in vim to report

'stdlib.h' file not found 
[clang: pp_file_not_found] 

whenever arm-none-eabi-gcc path argument is missing "/" symbol. the project compiles fine with arm-none-eabi-gcc and generates correct outputs. only clangd is having issues with the bear generated compile_commands.json causing my intellisense from coc.clangd to highlight stdlib.h as missing

Reproduce Makefile used:


##############################################################
#                      SETUP SOURCES                         #
##############################################################

STM_DIR = Drivers
STM_SRC = $(STM_DIR)/STM32F4xx_HAL_Driver/Src

vpath %.c $(STM_SRC)

SRCS = src/main.c
SRCS += src/system_stm32f4xx.c
SRCS += stm32f4xx_ll_rcc.c
SRCS += stm32f4xx_ll_utils.c
SRCS += stm32f4xx_ll_pwr.c
SRCS += stm32f4xx_ll_exti.c
SRCS += stm32f4xx_ll_gpio.c
SRCS += stm32f4xx_ll_adc.c
SRCS += stm32f4xx_ll_crc.c
SRCS += stm32f4xx_ll_dac.c
SRCS += stm32f4xx_ll_dma.c
SRCS += stm32f4xx_ll_dma2d.c
SRCS += stm32f4xx_ll_i2c.c
SRCS += stm32f4xx_ll_rtc.c
SRCS += stm32f4xx_ll_spi.c
SRCS += stm32f4xx_ll_tim.c
SRCS += stm32f4xx_ll_usart.c
SRCS += stm32f4xx_ll_rng.c
SRCS += stm32f4xx_ll_lptim.c
SRCS += src/startup_stm32f407xx.s

INC_DIR = $(STM_DIR)/CMSIS/Include
INC_DIR += $(STM_DIR)/CMSIS/Device/ST/STM32F4xx/Include
INC_DIR += $(STM_DIR)/STM32F4xx_HAL_Driver/Inc
INC_DIR += include

INCLUDE = $(addprefix -I, $(INC_DIR))

##############################################################
#                       SETUP TOOLS                          #
##############################################################

CC      = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
GDB     = arm-none-eabi-gdb

DEF = -DSTM32F407xx -DUSE_FULL_LL_DRIVER

CFLAGS = -g
CFLAGS += -O0
CFLAGS += --specs=nosys.specs
CFLAGS += -Wall -Wextra
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4#-mthumb-interwork
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16

LFLAGS = -Tstm32f407vgtx_flash.ld

##############################################################
#                      SETUP TARGETS                         #
##############################################################

.PHONY: $(PROJ_NAME)
$(PROJ_NAME): $(PROJ_NAME).elf

$(PROJ_NAME).elf: $(SRCS)
    $(CC) $(INCLUDE) $(DEF) $(CFLAGS) $(LFLAGS) $^ -o $@
    $(OBJCOPY) -O ihex   $(PROJ_NAME).elf $(PROJ_NAME).hex
    $(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin

clean:
    rm -f *.o $(PROJ_NAME).elf $(PROJ_NAME).hex $(PROJ_NAME).bin 

flash:
    st-flash write $(PROJ_NAME).bin 0x8000000

.PHONY: debug
debug:
    $(GDB) $(PROJ_NAME).elf

make clean; bear -- make

Generated compile_commands.json

    "arguments": [
      "/usr/bin/arm-none-eabi-gcc",
      "-c",
      "-IDrivers/CMSIS/Include",
      "-IDrivers/CMSIS/Device/ST/STM32F4xx/Include",
      "-IDrivers/STM32F4xx_HAL_Driver/Inc",
      "-Iinclude",
      "-DSTM32F407xx",
      "-DUSE_FULL_LL_DRIVER",
      "-g",
      "-O0",
      "--specs=nosys.specs",
      "-Wall",
      "-Wextra",
      "-mlittle-endian",
      "-mthumb",
      "-mcpu=cortex-m4",
      "-mfloat-abi=hard",
      "-mfpu=fpv4-sp-d16",
      "-Tstm32f407vgtx_flash.ld",
      "-o",
      "stm32f407_lcd.elf",
      "src/main.c"
    ],
    "directory": "/home/boss/Development/stm32f407_lcd",
    "file": "/home/boss/Development/stm32f407_lcd/src/main.c",
    "output": "/home/boss/Development/stm32f407_lcd/stm32f407_lcd.elf"
  }
...

Expected behavior Whenever the compiler flag contains ending "/" the error disappears and the standard library files are included correctly and there is no error. "/usr/bin/arm-none-eabi-gcc/"

ex.

    "arguments": [
      "/usr/bin/arm-none-eabi-gcc/",
      "-c",
      "-IDrivers/CMSIS/Include"

Environment:

rizsotto commented 3 years ago

Thanks @bleonars for the report. Do I understand it correctly, the problem is the difference between "good" and "bad" is the trailing / at the end of /usr/bin/arm-none-eabi-gcc? That surprises me a lot! :) Can you explain the slash relevance for the correct behavior? (Or can you show me the output of ls -l /usr/bin/arm-none-eabi-gcc? Or what commands I need to run to re-create your arch dev env?)

bleonars commented 3 years ago

Do I understand it correctly, the problem is the difference between "good" and "bad" is the trailing / at the end of /usr/bin/arm-none-eabi-gcc? Can you explain the slash relevance for the correct behavior?

Yes, that is correct. I'm not sure what the relevance of the slash is myself either... However, when I add the slash clangd now detects the standard library and coc.clangd provides me the right suggestions without errors, where it does not if the slash is missing.

(Or can you show me the output of ls -l /usr/bin/arm-none-eabi-gcc? Or what commands I need to run to re-create your arch dev env?)

image

sudo pacman -Sy arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-new

bleonars commented 3 years ago

After further testing I've come to the conclusion that the whole arguments' location tag generated by bear for compile_commands.json is incorrect. Whenever I remove it, or change it to simply /usr/bin/gcc the issue of the missing stdlib.h disappears. It seems that the issue is with the inability of clangd to find the stdlib.h containing directory when the argument for the compiler location is listed as /usr/bin/arm-none-eabi-gcc. This makes no sense as the arm-none-eabi-gcc compilation works perfectly fine.

bleonars commented 3 years ago

I've done some digging around and found this site https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clangd/Configuration.html#id2. I've followed what it says and replaced the /usr/bin/arm-none-eabi-gcc argument flag with -query-driver=/usr/bin/arm-none-eabi-gcc. This now works as intended. Therefore, my question becomes: is there any way to change the bear config to generate a -query-driver argument versus just the default arm-none-eabi-gcc binpath?

rizsotto commented 3 years ago

Thanks for digging into it! The trailing / is something that I can't understand, and happy to hear that it is not necessarily a problem we need to solve. :smile:

To add extra flags could be already supported by Bear. You just need to specify those in the configuration file. Look for compilers_to_recognize section, where you can specify extra arguments for each compiler. (Not sure if this is well tested, but that suppose to work.)

bleonars commented 3 years ago

Thanks for the information. This seems to fix it. Issue can be closed.