C++ 生成文件 LD 错误
C++ Makefile LD Error
我正在使用 C++ 和 libopencm3 对 ARM 进行编程。但是我的 Makefile 包含错误。就像你现在看到的那样!
我有以下 Makefile:
Q = @
RM = @rm -f
MAKE = make
CC = arm-none-eabi-gcc
CPP = arm-none-eabi-g++
LD = arm-none-eabi-gcc
OBC = arm-none-eabi-objcopy
OBD = arm-none-eabi-objdump
SIZ = arm-none-eabi-size
STFLASH = st-flash
FIRMWARE = FIRMWARE
LIBNAME = opencm3_stm32f1
SRCS = main.cpp Robot.cpp
OBJS = $(SRCS:%.cpp=$(OBJ_DIR)/%.o)
OPENCM3_DIR = $(realpath libopencm3)
INCLUDE_DIR = $(OPENCM3_DIR)/include
LIB_DIR = $(OPENCM3_DIR)/lib
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
OBJ_DIR = ./build
LDSCRIPT = stm32f103c8t6.ld
CPPFLAGS = -g -Os -Wall
CPPFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++
CPPFLAGS += -fno-common -ffunction-sections -fdata-sections
CPPFLAGS += -MD -Wall -Wundef
CPPFLAGS += -I$(INCLUDE_DIR) -DSTM32F1
CPPFLAGS += -msoft-float -mfix-cortex-m3-ldrd
CPPFLAGS += -mthumb -mcpu=cortex-m3
LDFLAGS = --static -nostartfiles
LDFLAGS += -L$(LIB_DIR)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(FIRMWARE).MAP
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -msoft-float -mfix-cortex-m3-ldrd
LDFLAGS += -mthumb -mcpu=cortex-m3
LDLIBS = -l$(LIBNAME)
LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
all: bin elf hex
lib:
$(Q)if [ ! "`ls -A libopencm3`" ] ; then \
printf "######## ERROR ########\n"; \
printf "\tPlease run:\n"; \
printf "\tgit clone https://github.com/libopencm3/libopencm3.git\n"; \
printf "######## ERROR ########\n"; \
exit 1; \
fi
$(Q)$(MAKE) -C libopencm3
elf: $(OBJ_DIR)/$(FIRMWARE).ELF
bin: $(OBJ_DIR)/$(FIRMWARE).BIN
hex: $(OBJ_DIR)/$(FIRMWARE).HEX
dox:
$(Q)doxygen Doxyfile
$(OBJ_DIR)/$(FIRMWARE).BIN: $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)printf " OBJCOPY $(OBJ_DIR)/$(FIRMWARE).BIN\n"
$(Q)$(OBC) -Obinary $(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).BIN
$(OBJ_DIR)/$(FIRMWARE).HEX: $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)printf " OBJCOPY $(OBJ_DIR)/$(FIRMWARE).HEX\n"
$(Q)$(OBC) -Oihex $(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).HEX
$(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).MAP: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
$(Q)printf " LD $(OBJ_DIR)/$(FIRMWARE).ELF\n"
$(Q)$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)$(SIZ) $(OBJ_DIR)/$(FIRMWARE).ELF
$(OBJS): $(SRCS)
$(Q)printf " CPP $(*).cpp\n"
$(Q)$(CPP) $(CPPFLAGS) -o $@ -c $<
flash: $(OBJ_DIR)/$(FIRMWARE).BIN
$(Q)printf " FLASH $(OBJ_DIR)/$(FIRMWARE).BIN\n"
$(Q)$(STFLASH) write $(OBJ_DIR)/$(FIRMWARE).BIN 0x8000000
libclean:
$(Q)$(MAKE) -C libopencm3 clean
clean:
$(Q)printf " CLEAN\n"
$(Q)$(RM) $(OBJ_DIR)/*.o
$(Q)$(RM) $(OBJ_DIR)/*.d
deepclean: clean
$(Q)$(RM) $(OBJ_DIR)/$(FIRMWARE).*
但是链接(LD)不起作用。查看错误:
CPP build/main.cpp
main.cpp: In function 'int main()':
main.cpp:25:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(i = 0; i < 36000000UL; i++)
^
CPP build/Robot.cpp
main.cpp: In function 'int main()':
main.cpp:25:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(i = 0; i < 36000000UL; i++)
^
LD ./build/FIRMWARE.ELF
./build/Robot.o: In function `main':
/home/martin/Dropbox/workspace/electronics/arm/Procyon/main.cpp:15: multiple definition of `main'
./build/main.o:/home/martin/Dropbox/workspace/electronics/arm/Procyon/main.cpp:15: first defined here
collect2: error: ld returned 1 exit status
Makefile:73: recipe for target 'build/FIRMWARE.ELF' failed
make: *** [build/FIRMWARE.ELF] Error 1
哪里错了?
我不知道 LD 有什么问题,当我将这个 makefile 用于 C(不是 C++)时它工作正常!?
也许是因为我使用 gcc 而不是 g++ 进行 LD'ing?
谢谢,
马丁
您已使每个对象都依赖于所有 来源
$(OBJS): $(SRCS)
将其更改为
$(OBJS): $(OBJ_DIR)/%.o: %.cpp
或者干脆
$(OBJ_DIR)/%.o: %.cpp
我正在使用 C++ 和 libopencm3 对 ARM 进行编程。但是我的 Makefile 包含错误。就像你现在看到的那样!
我有以下 Makefile:
Q = @
RM = @rm -f
MAKE = make
CC = arm-none-eabi-gcc
CPP = arm-none-eabi-g++
LD = arm-none-eabi-gcc
OBC = arm-none-eabi-objcopy
OBD = arm-none-eabi-objdump
SIZ = arm-none-eabi-size
STFLASH = st-flash
FIRMWARE = FIRMWARE
LIBNAME = opencm3_stm32f1
SRCS = main.cpp Robot.cpp
OBJS = $(SRCS:%.cpp=$(OBJ_DIR)/%.o)
OPENCM3_DIR = $(realpath libopencm3)
INCLUDE_DIR = $(OPENCM3_DIR)/include
LIB_DIR = $(OPENCM3_DIR)/lib
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
OBJ_DIR = ./build
LDSCRIPT = stm32f103c8t6.ld
CPPFLAGS = -g -Os -Wall
CPPFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++
CPPFLAGS += -fno-common -ffunction-sections -fdata-sections
CPPFLAGS += -MD -Wall -Wundef
CPPFLAGS += -I$(INCLUDE_DIR) -DSTM32F1
CPPFLAGS += -msoft-float -mfix-cortex-m3-ldrd
CPPFLAGS += -mthumb -mcpu=cortex-m3
LDFLAGS = --static -nostartfiles
LDFLAGS += -L$(LIB_DIR)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(FIRMWARE).MAP
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -msoft-float -mfix-cortex-m3-ldrd
LDFLAGS += -mthumb -mcpu=cortex-m3
LDLIBS = -l$(LIBNAME)
LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
all: bin elf hex
lib:
$(Q)if [ ! "`ls -A libopencm3`" ] ; then \
printf "######## ERROR ########\n"; \
printf "\tPlease run:\n"; \
printf "\tgit clone https://github.com/libopencm3/libopencm3.git\n"; \
printf "######## ERROR ########\n"; \
exit 1; \
fi
$(Q)$(MAKE) -C libopencm3
elf: $(OBJ_DIR)/$(FIRMWARE).ELF
bin: $(OBJ_DIR)/$(FIRMWARE).BIN
hex: $(OBJ_DIR)/$(FIRMWARE).HEX
dox:
$(Q)doxygen Doxyfile
$(OBJ_DIR)/$(FIRMWARE).BIN: $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)printf " OBJCOPY $(OBJ_DIR)/$(FIRMWARE).BIN\n"
$(Q)$(OBC) -Obinary $(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).BIN
$(OBJ_DIR)/$(FIRMWARE).HEX: $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)printf " OBJCOPY $(OBJ_DIR)/$(FIRMWARE).HEX\n"
$(Q)$(OBC) -Oihex $(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).HEX
$(OBJ_DIR)/$(FIRMWARE).ELF $(OBJ_DIR)/$(FIRMWARE).MAP: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
$(Q)printf " LD $(OBJ_DIR)/$(FIRMWARE).ELF\n"
$(Q)$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(OBJ_DIR)/$(FIRMWARE).ELF
$(Q)$(SIZ) $(OBJ_DIR)/$(FIRMWARE).ELF
$(OBJS): $(SRCS)
$(Q)printf " CPP $(*).cpp\n"
$(Q)$(CPP) $(CPPFLAGS) -o $@ -c $<
flash: $(OBJ_DIR)/$(FIRMWARE).BIN
$(Q)printf " FLASH $(OBJ_DIR)/$(FIRMWARE).BIN\n"
$(Q)$(STFLASH) write $(OBJ_DIR)/$(FIRMWARE).BIN 0x8000000
libclean:
$(Q)$(MAKE) -C libopencm3 clean
clean:
$(Q)printf " CLEAN\n"
$(Q)$(RM) $(OBJ_DIR)/*.o
$(Q)$(RM) $(OBJ_DIR)/*.d
deepclean: clean
$(Q)$(RM) $(OBJ_DIR)/$(FIRMWARE).*
但是链接(LD)不起作用。查看错误:
CPP build/main.cpp
main.cpp: In function 'int main()':
main.cpp:25:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(i = 0; i < 36000000UL; i++)
^
CPP build/Robot.cpp
main.cpp: In function 'int main()':
main.cpp:25:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(i = 0; i < 36000000UL; i++)
^
LD ./build/FIRMWARE.ELF
./build/Robot.o: In function `main':
/home/martin/Dropbox/workspace/electronics/arm/Procyon/main.cpp:15: multiple definition of `main'
./build/main.o:/home/martin/Dropbox/workspace/electronics/arm/Procyon/main.cpp:15: first defined here
collect2: error: ld returned 1 exit status
Makefile:73: recipe for target 'build/FIRMWARE.ELF' failed
make: *** [build/FIRMWARE.ELF] Error 1
哪里错了? 我不知道 LD 有什么问题,当我将这个 makefile 用于 C(不是 C++)时它工作正常!?
也许是因为我使用 gcc 而不是 g++ 进行 LD'ing?
谢谢, 马丁
您已使每个对象都依赖于所有 来源
$(OBJS): $(SRCS)
将其更改为
$(OBJS): $(OBJ_DIR)/%.o: %.cpp
或者干脆
$(OBJ_DIR)/%.o: %.cpp