c项目makefile多重定义错误

发布于 2025-01-20 04:23:34 字数 11850 浏览 4 评论 0原文

这个问题是对应于这个 问题。

在我的嵌入式 C 项目中,我有两个独立的板,我想为每个板创建两个 .c 文件(master.c 和 Slave.c),其中包含自己特定的 main() 函数。

我使用 stm32cumbemx 生成带有 main.c、makefile 以及其他源和标头的项目(我想手动用 master.c 和 Slave.c 替换 main.c)。 这是项目的文件夹结构(为了简单起见,我删除了slave.c):

.
├── Inc
│   └── main.h
├── Makefile
├── Src
│   ├── main.c
│   └── master.c
└── STM32F103RBTx_FLASH.ld

main.h:

#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

main.c:

#include "main.h"
int variable = 1;
void function(void);
int main() {
    variable += 1;
    while(1){}
}

void function(void) {
    int something = 0;
    something++;
}

master.c:

#include "main.h"
int variable = 1;
int variable2;
void function(void);
void function2(void);
int main() {
    variable += 1;
    while(1){
        function2();
    }
}

void function(void) {
    int something = 0;
    something++;
}

void function2(void) {
    variable2++;
}

STM32F103RBTx_FlASH.ld:

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20005000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH


  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM



  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

和makefile(我添加到预生成文件中的部分位于 #edit begin#edit end 注释:

TARGET = myproject
#edit begin
MASTER = master
SLAVE = slave
#edit end


DEBUG = 1
# optimization
OPT = -Og


BUILD_DIR = build

# C sources
C_SOURCES =  \
Src/main.c

#edint begin
SLAVE_SOURCES = \
Src/slave.c

MASTER_SOURCES = \
Src/master.c \
#edit end

PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

CPU = -mcpu=cortex-m3

# fpu
# NONE for Cortex-M0/M0+/M3

# float-abi


# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS =

# C defines
C_DEFS =  \
-DUSE_HAL_DRIVER \
-DSTM32F103xB


# AS includes
AS_INCLUDES =

# C includes
C_INCLUDES =  \
-IInc \


# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif


# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"


# link script
LDSCRIPT = STM32F103RBTx_FLASH.ld

# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

#edit begin
master: $(BUILD_DIR)/$(MASTER).elf $(BUILD_DIR)/$(MASTER).hex $(BUILD_DIR)/$(MASTER).bin
slave: $(BUILD_DIR)/$(SLAVE).elf $(BUILD_DIR)/$(SLAVE).hex $(BUILD_DIR)/$(SLAVE).bin
#edit end

#######################################
# build the application
#######################################
# list of objects
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)))
$(info OBJECTS is $(OBJECTS))

#edit begin
MASTER_OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(MASTER_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(MASTER_SOURCES)))
$(info MASTER_OBJ is $(MASTER_OBJ))

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

$(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) $@

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

$(BUILD_DIR)/$(SLAVE).elf: $(SLAVE_OBJ) Makefile
    $(CC) $(SLAVE_OBJ) $(LDFLAGS) -o $@
    $(SZ) $@
#edit end

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

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

$(BUILD_DIR):
    mkdir $@

clean:
    -rm -fR $(BUILD_DIR)

-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

终端中 sudo make 的结果:

OBJECTS is build/main.o 
MASTER_OBJ is build/master.o
mkdir build
arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc  -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/main.d" -Wa,-a,-ad,-alms=build/main.lst Src/main.c -o build/main.o
arm-none-eabi-gcc build/main.o  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys -Wl,-Map=build/myproject.map,--cref -Wl,--gc-sections -o build/myproject.elf
arm-none-eabi-size build/myproject.elf
   text    data     bss     dec     hex filename
     88       8    1568    1664     680 build/myproject.elf
arm-none-eabi-objcopy -O ihex build/myproject.elf build/myproject.hex
arm-none-eabi-objcopy -O binary -S build/myproject.elf build/myproject.bin

如您所见,代码编译没有错误。 和 sudo make master 的结果(运行 sudo make clean 后):

MASTER_OBJ is build/master.o
mkdir build
arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/master.d" -Wa,-a,-ad,-alms=build/master.lst Src/master.c -o build/master.o
arm-none-eabi-gcc build/master.o  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/dual-interface.map,--cref -Wl,--gc-sections -o build/master.elf
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol Reset_Handler; defaulting to 08000000
arm-none-eabi-size build/master.elf
   text    data     bss     dec     hex filename
     88       8    1568    1664     680 build/master.elf
arm-none-eabi-objcopy -O ihex build/master.elf build/master.hex
arm-none-eabi-objcopy -O binary -S build/master.elf build/master.bin
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"master"  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/dual-interface.map,--cref -Wl,--gc-sections  Src/master.c build/master.elf build/master.hex build/master.bin   -o master
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: build/master.elf: in function `_init':
(.text+0x40): multiple definition of `_init'; c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp/crti.o:(.init+0x0): first defined here
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: build/master.elf: in function `_fini':
(.text+0x4c): multiple definition of `_fini'; c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp/crti.o:(.fini+0x0): first defined here
build/master.bin: file not recognized: file format not recognized
collect2.exe: error: ld returned 1 exit status
make: *** [master] Error 1

我该如何解决这个问题?

您可以使用“gnu make”和“arm-none-eabi-gcc”作为编译器在Windows中重新创建错误。在 Linux 中,如果出现 stdint.h 错误,您还需要安装此处提到的软件包之一。

This question is a repex created corresponding to this problem.

In my embedded C project I have two separate boards and I want to create two .c files (master.c and slave.c) for each board containing their own specific main() function.

I've used stm32cumbemx to generate the project with main.c, makefile and other sources and headers (I want to replace main.c with master.c and slave.c manually).
this is the folder structure of the project (I deleted slave.c for simplicity):

.
├── Inc
│   └── main.h
├── Makefile
├── Src
│   ├── main.c
│   └── master.c
└── STM32F103RBTx_FLASH.ld

main.h:

#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

main.c:

#include "main.h"
int variable = 1;
void function(void);
int main() {
    variable += 1;
    while(1){}
}

void function(void) {
    int something = 0;
    something++;
}

master.c:

#include "main.h"
int variable = 1;
int variable2;
void function(void);
void function2(void);
int main() {
    variable += 1;
    while(1){
        function2();
    }
}

void function(void) {
    int something = 0;
    something++;
}

void function2(void) {
    variable2++;
}

STM32F103RBTx_FlASH.ld:

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20005000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH


  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM



  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

and makefile (the parts I added to pre-generated file are between #edit begin and #edit end comments:

TARGET = myproject
#edit begin
MASTER = master
SLAVE = slave
#edit end


DEBUG = 1
# optimization
OPT = -Og


BUILD_DIR = build

# C sources
C_SOURCES =  \
Src/main.c

#edint begin
SLAVE_SOURCES = \
Src/slave.c

MASTER_SOURCES = \
Src/master.c \
#edit end

PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

CPU = -mcpu=cortex-m3

# fpu
# NONE for Cortex-M0/M0+/M3

# float-abi


# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS =

# C defines
C_DEFS =  \
-DUSE_HAL_DRIVER \
-DSTM32F103xB


# AS includes
AS_INCLUDES =

# C includes
C_INCLUDES =  \
-IInc \


# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif


# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"


# link script
LDSCRIPT = STM32F103RBTx_FLASH.ld

# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

#edit begin
master: $(BUILD_DIR)/$(MASTER).elf $(BUILD_DIR)/$(MASTER).hex $(BUILD_DIR)/$(MASTER).bin
slave: $(BUILD_DIR)/$(SLAVE).elf $(BUILD_DIR)/$(SLAVE).hex $(BUILD_DIR)/$(SLAVE).bin
#edit end

#######################################
# build the application
#######################################
# list of objects
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)))
$(info OBJECTS is $(OBJECTS))

#edit begin
MASTER_OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(MASTER_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(MASTER_SOURCES)))
$(info MASTER_OBJ is $(MASTER_OBJ))

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

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

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

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

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

$(BUILD_DIR)/$(SLAVE).elf: $(SLAVE_OBJ) Makefile
    $(CC) $(SLAVE_OBJ) $(LDFLAGS) -o $@
    $(SZ) $@
#edit end

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
    $(HEX) 
lt; $@

$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
    $(BIN) 
lt; $@

$(BUILD_DIR):
    mkdir $@

clean:
    -rm -fR $(BUILD_DIR)

-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

resutlt of sudo make in terminal:

OBJECTS is build/main.o 
MASTER_OBJ is build/master.o
mkdir build
arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc  -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/main.d" -Wa,-a,-ad,-alms=build/main.lst Src/main.c -o build/main.o
arm-none-eabi-gcc build/main.o  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys -Wl,-Map=build/myproject.map,--cref -Wl,--gc-sections -o build/myproject.elf
arm-none-eabi-size build/myproject.elf
   text    data     bss     dec     hex filename
     88       8    1568    1664     680 build/myproject.elf
arm-none-eabi-objcopy -O ihex build/myproject.elf build/myproject.hex
arm-none-eabi-objcopy -O binary -S build/myproject.elf build/myproject.bin

as you see the code compiles with no errors.
and result of sudo make master (after running sudo make clean):

MASTER_OBJ is build/master.o
mkdir build
arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/master.d" -Wa,-a,-ad,-alms=build/master.lst Src/master.c -o build/master.o
arm-none-eabi-gcc build/master.o  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/dual-interface.map,--cref -Wl,--gc-sections -o build/master.elf
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol Reset_Handler; defaulting to 08000000
arm-none-eabi-size build/master.elf
   text    data     bss     dec     hex filename
     88       8    1568    1664     680 build/master.elf
arm-none-eabi-objcopy -O ihex build/master.elf build/master.hex
arm-none-eabi-objcopy -O binary -S build/master.elf build/master.bin
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"master"  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/dual-interface.map,--cref -Wl,--gc-sections  Src/master.c build/master.elf build/master.hex build/master.bin   -o master
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: build/master.elf: in function `_init':
(.text+0x40): multiple definition of `_init'; c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp/crti.o:(.init+0x0): first defined here
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: build/master.elf: in function `_fini':
(.text+0x4c): multiple definition of `_fini'; c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp/crti.o:(.fini+0x0): first defined here
build/master.bin: file not recognized: file format not recognized
collect2.exe: error: ld returned 1 exit status
make: *** [master] Error 1

How can I solve this?

you can recreate the error in windows with "gnu make" and "arm-none-eabi-gcc" as compiler. in linux and in case of stdint.h error, you also need to install one of the packages mentioned here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

王权女流氓 2025-01-27 04:23:34

最后的GCC运行...

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -DUSE_HAL_DRIVER -DSTM32F103xB -IInc -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP - MF“ Master” -MCPU = Cortex -M3 -Mthumb -Specs = Nano.specs -TSTM32F103RBTX_FLASH.LC-LC -LM -LM -LNOSYS -LNOSYS -LNOSYS -WL,-MAP = build/myproject.mmap.map = build/myproject.map, - src/master.c build/master.elf build/master.hex -o主人
 

...生成错误本身是错误的。它来自哪里?

注意-o Master最后:Makefile中没有规则,其配方会产生这样的汇编,但它正在构建具有相同名称的文件,Master作为目标目标。 这是行使内置隐式规则的结果,用于从相应的命名C源文件中构建可执行文件。

有几种情况有助于这一点。

  1. 提出了构建目标<代码> Master 的请求。在这种情况下,这是目标目标,但也足以使其成为另一个目标的先决条件,make想要构建。

  2. Makefile不提供任何构建Master的配方。

  3. 有一个名为master.c的源文件。尽管它在子目录src中,但是有一个%vpath指令,告诉make在该目录中处理文件,就好像它们出现在项目中一样根目录。

此外,

  1. 内置规则显然包括目标Master的声明的先决条件(build> build/master.elf and build> build/master.hex)在汇编命令中。对于我已检查的make版本的版本没有记录或标准,这是多个定义错误的原因:GCC正在构建可执行文件,因此它提供了标准_init 和_fini函数,但是已包含在链接中的已构建的可执行文件build> master.felf也有这些。

由于您实际上不需要构建的名为Master构建的文件,因此一个好的解决方案是声明该目标假冒:

.PHONY: master

这有几个有用的效果,但出于您的目的而言,它会导致隐式规则搜索为了跳过该目标。

The last gcc run ...

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc  -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"master"  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys -Wl,-Map=build/myproject.map,--cref -Wl,--gc-sections  Src/master.c build/master.elf build/master.hex   -o master

... that generates the errors, is itself erroneous. Where does it come from?

Note the -o master at the end: there is no rule presented in the makefile whose recipe would produce such a compilation, but it is building a file with the same name, master, as the goal target. This is the result of the exercise of a built-in implicit rule for building an executable from a correspondingly-named C source file.

Several circumstances contribute to this.

  1. A request is made to build target master. It is the goal target in this case, but it would also suffice for it to be a prerequisite of another target that make wants to build.

  2. The makefile does not provide any recipe for building master.

  3. There is a source file named master.c. Although it is in subdirectory Src, there is a %vpath directive that tells make to treat files in that directory as if they appeared in the project root directory.

Additionally,

  1. The built-in rule is apparently including the declared prerequisites of target master (build/master.elf and build/master.hex) in the compilation command. This is not documented or standard for versions of make I've checked, and it is the reason for the multiple-definition errors: gcc is building an executable, so it provides standard _init and _fini functions, but the already-built executable build/master.elf that is included in the link also has these.

Since you don't actually want a file named master built, a good solution would be to declare that target phony:

.PHONY: master

That has several useful effects, but key for your purposes is that it causes the implicit rule search for that target to be skipped.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文