1 year ago

#386638

test-img

mehdi

makefile error in c project multiple definitions

For a minimal reproducible example of this problem, please go to this link.

I'm working on a stm32 project that is initialized using stm32cubemx(Makefile) and I'm using vscode as ide.

Until now I had a single main.c file with main() function in it and everything was ok.

I have two separate boards in my project and I decided to create two source files (master.c and slave.c) with specific main() functions in them and deleted the main.c file. Also I added two targets (master and slave) to my Makefile (which is created by cubemx) so that I can choose which files to compile and flash to each board. The C_SOURCES variable was defined by cumbemx:

# C sources
C_SOURCES =  \
Src/gpio.c \
Src/crc.c \
Src/i2c.c \
Src/usart.c \
Src/stm32f1xx_it.c \
Src/stm32f1xx_hal_msp.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \
Src/system_stm32f1xx.c \
Src/tim.c \
Src/fxos.c

I added MASTER_SOURCES variable and copied all the sources above plus master.c in it:

MASTER_SOURCES = \
Src/master.c \
Src/gpio.c \
Src/crc.c \
Src/i2c.c \
Src/usart.c \
Src/stm32f1xx_it.c \
Src/stm32f1xx_hal_msp.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \
Src/system_stm32f1xx.c \
Src/tim.c \
Src/fxos.c
TARGET = my-initial-target
MASTER = master
SLAVE = slave

and down below I defined the targets for each board as follows:

all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

master: $(BUILD_DIR)/$(MASTER).elf $(BUILD_DIR)/$(MASTER).hex $(BUILD_DIR)/$(MASTER).hex
slave: $(BUILD_DIR)/$(SLAVE).elf $(BUILD_DIR)/$(SLAVE).hex $(BUILD_DIR)/$(SLAVE).hex

and also defined MASTER_OBJ using auto-created OBJECTS variable as a sample:

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

MASTER_OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(MASTER_SOURCES:.c=.o))) 
vpath %.c $(sort $(dir $(MASTER_SOURCES)))

MASTER_OBJ += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))


$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
    $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
    $(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
    $(CC) $(OBJECTS) $(LDFLAGS) -o $@
    $(SZ) $@

$(BUILD_DIR)/$(MASTER).elf: $(MASTER_OBJ) Makefile
    $(CC) $(MASTER_OBJ) $(LDFLAGS) -o $@
    $(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
    $(HEX) $< $@
    
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
    $(BIN) $< $@    
    
$(BUILD_DIR):
    mkdir $@        

But after I run make master or in terminal, I get several multiple definition errors like this:

/usr/lib/gcc/arm-none-eabi/11.2.0/../../../../arm-none-eabi/bin/ld: build/master.elf: in function `_sbss':
/home/mehdi/coding/mag-dual-interface/Src/master.c:132: multiple definition of `drdyFlag'; /tmp/ccnS08MO.o:/home/mehdi/coding/mag-dual-interface/Src/master.c:132: first defined here

the drdyFlag variable is defined in the master.c file which has replaced the initial main.c. this error is repeated nearly for every function and variable declared and defined in master.c. If I add extern to function declarations (although I have not declared or defined them in any other source file), the above error for functions is resolved, but it has no effect in variables. All the header files have include guards and no .c files are included anywhere.

So can someone please tell me what am I doing wrong here?

c

makefile

stm32

gnu-make

0 Answers

Your Answer

Accepted video resources