我有一个项目,在 2 个位置有源代码。当项目链接时,它会抱怨函数是双重定义的(它不是):
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src src/Meter.c -o build/x86_64-linux-gnu/obj/Meter.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src src/PaymentHandler.c -o build/x86_64-linux-gnu/obj/PaymentHandler.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src src/PaymentHandlerDaemon.c -o build/x86_64-linux-gnu/obj/PaymentHandlerDaemon.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src src/PrintSocketReceiver.c -o build/x86_64-linux-gnu/obj/PrintSocketReceiver.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src src/SerialPrinter.c -o build/x86_64-linux-gnu/obj/SerialPrinter.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src ../../Bla/trunk/src/CheckSum.c -o build/x86_64-linux-gnu/obj/Bla/CheckSum.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src ../../Bla/trunk/src/CheckSum.c -o build/x86_64-linux-gnu/obj/Bla/Config.o
cc build/x86_64-linux-gnu/obj/Meter.o build/x86_64-linux-gnu/obj/PaymentHandler.o build/x86_64-linux-gnu/obj/PaymentHandlerDaemon.o build/x86_64-linux-gnu/obj/PrintSocketReceiver.o build/x86_64-linux-gnu/obj/SerialPrinter.o build/x86_64-linux-gnu/obj/Bla/CheckSum.o build/x86_64-linux-gnu/obj/Bla/Config.o -o build/x86_64-linux-gnu/obj/../PaymentHandlerDaemon -lrt -lpthread -lconfig -lm -L../../libSOS/trunk/build/x86_64-linux-gnu -lSOS -L../lib/ABCUtilLib/build/x86_64-linux-gnu -lABCUtil -L../lib/ABCUtilSO/build/x86_64-linux-gnu -lABCMain
build/x86_64-linux-gnu/obj/Bla/Config.o: In function `CheckSum_Buffer':
/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:34: multiple definition of `CheckSum_Buffer'
build/x86_64-linux-gnu/obj/Bla/CheckSum.o:/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:34: first defined here
build/x86_64-linux-gnu/obj/Bla/Config.o: In function `CheckSum_Stream':
/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:54: multiple definition of `CheckSum_Stream'
build/x86_64-linux-gnu/obj/Bla/CheckSum.o:/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:54: first defined here
build/x86_64-linux-gnu/obj/Bla/Config.o: In function `pppfcs16':
/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:125: multiple definition of `pppfcs16'
build/x86_64-linux-gnu/obj/Bla/CheckSum.o:/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/../../Bla/trunk/src/CheckSum.c:125: first defined here
build/x86_64-linux-gnu/obj/Meter.o: In function `Meter_MessagePumpProc':
/home/builder/projects/Applications/PaymentHandlerDaemon/trunk/src/Meter.c:365: undefined reference to `Config_GetHardwareInfo'
collect2: error: ld returned 1 exit status
make: *** [build/x86_64-linux-gnu/obj/../PaymentHandlerDaemon] Error 1
我认为这是因为 makefile 为每个目录编译了 2 个不同的配方,并且它们不共享预编译定义。
有没有更好的方法来制作一个有 2 个源目录的项目?我应该只将不同目录中的几个源添加到迷你库中,然后添加它吗?
制作文件:
CC ?= gcc
ARCH = $(shell $(CC) -dumpmachine)
# compile and link flags
CC_FLAGS ?= -c -w -fPIC -g3 -Og -D__EMULATE_SOS__
CC_INCLUDE = -I../../libSOS/trunk/include
CC_INCLUDE += -I. -I../../include
CC_INCLUDE += -I../lib/ABCUtilSO/src
CC_INCLUDE += -I../../Bla/trunk/src
# Libraries
LIBS := -lrt -lpthread -lconfig -lm
LIBS += -L../../libSOS/trunk/build/$(ARCH) -lSOS
LIBS += -L../lib/ABCUtilLib/build/$(ARCH) -lABCUtil
LIBS += -L../lib/ABCUtilSO/build/$(ARCH) -lABCMain
OUT1_DIR = build/$(ARCH)/obj
OUT2_DIR = build/$(ARCH)/obj/Bla
# result
EXEC = ${OUT1_DIR}/../PaymentHandlerDaemon
#-------------------------------------------------------------
# main sources (1)
SRC1_DIR = src
#all the sources in the srec directory will be included
SOURCES1 = $(wildcard ${SRC1_DIR}/*.c)
# deduce the object list from the source list
_OBJECTS1 = $(patsubst %.c,%.o,$(SOURCES1) )
# the replace the source directory wioth the output directory
OBJECTS1 = $(patsubst ${SRC1_DIR}%,${OUT1_DIR}%,$(_OBJECTS1) )
#-------------------------------------------------------------
# extra sources (2)
SRC2_DIR = ../../Bla/trunk/src
#SRC2_LIST = Meter.c
SRC2_LIST = CheckSum.c Config.c
#all the sources in the srec directory will be included
#SOURCES2 = $(pathsubs %,$(SRC2_DIR)/%,$(SRC2_LIST))
SOURCES2 = $(patsubst %.c,${SRC2_DIR}/%.c,$(SRC2_LIST))
# deduce the object list from the source list
_OBJECTS2 = $(patsubst %.c,%.o,$(SOURCES2) )
# the replace the source directory wioth the output directory
OBJECTS2 = $(patsubst ${SRC2_DIR}%,${OUT2_DIR}%,$(_OBJECTS2) )
#-------------------------------------------------------------
# build receipes
all: $(EXEC)
# Main target
$(EXEC): $(OBJECTS1) $(OBJECTS2)
$(CC) $(OBJECTS1) $(OBJECTS2) -o $@ $(LIBS)
# To obtain object files
${OUT1_DIR}%.o:${SRC1_DIR}%.c
@mkdir -p $(OUT1_DIR)
$(CC) -c $(CC_FLAGS) $(CC_INCLUDE) $< -o $@
# # To obtain object files
${OUT2_DIR}%.o:${SOURCES2}
@mkdir -p $(OUT2_DIR)
$(CC) -c $(CC_FLAGS) $(CC_INCLUDE) $< -o $@
# To remove generated files
clean:
rm -fr build/$(ARCH)
# debug.. for example use as make -print-SRC_DIR
print-% : ; @echo $* = $($*)
人们总是从多个目录构建项目。每种情况都需要不同的方法。
您发布的内容应该有效。多重定义很可能不是因为Makefile
。我会更仔细地研究这个错误。toolchain
告诉你它在哪里找到这两个定义。
制作文件:
CC ?= gcc
# compile and link flags
CC_FLAGS ?= -c -w -fPIC -g3 -Og
CC_INCLUDE += -I../../AnotherProject/src
# Libraries
LIBS := -lrt -lpthread -lconfig -lm
OUT1_DIR = build/obj
OUT2_DIR = build/obj/extra2
# result
EXEC = build/MyProgram
#-------------------------------------------------------------
# main sources (1) (everything in src directory)
SRC1_DIR = src
SOURCES1 = $(wildcard ${SRC1_DIR}/*.c)
# deduce the object list from the source list
_OBJECTS1 = $(patsubst %.c,%.o,$(SOURCES1) )
# the replace the source directory wioth the output directory
OBJECTS1 = $(patsubst ${SRC1_DIR}%,${OUT1_DIR}%,$(_OBJECTS1) )
#-------------------------------------------------------------
# extra sources (just cherry pick what i need to reuse)
SRC2_DIR = ../../AnotherProject/src
SRC2_LIST = CheckSum.c Config.c
#all the sources in the srec directory will be included
SOURCES2 = $(patsubst %.c,${SRC2_DIR}/%.c,$(SRC2_LIST))
# deduce the object list from the source list
_OBJECTS2 = $(patsubst %.c,%.o,$(SOURCES2) )
# the replace the source directory wioth the output directory
OBJECTS2 = $(patsubst ${SRC2_DIR}%,${OUT2_DIR}%,$(_OBJECTS2) )
#-------------------------------------------------------------
# build receipes
all: debug $(EXEC)
debug: FORCE
echo "1====" $(OBJECTS1)
echo "2====" $(OBJECTS2)
FORCE:
# Main target
$(EXEC): $(OBJECTS1) $(OBJECTS2)
$(CC) $(OBJECTS1) $(OBJECTS2) -o $@ $(LIBS)
# To obtain object files
${OUT1_DIR}/%.o:${SRC1_DIR}/%.c
@mkdir -p $(OUT1_DIR)
$(CC) -c $(CC_FLAGS) $(CC_INCLUDE) $< -o $@
# To obtain the extra object files
${OUT2_DIR}/%.o:${SRC2_DIR}/%.c
@mkdir -p $(OUT2_DIR)
$(CC) -c $(CC_FLAGS) $(CC_INCLUDE) $< -o $@
编辑
这是你的问题。
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src ../../Bla/trunk/src/CheckSum.c -o build/x86_64-linux-gnu/obj/Bla/CheckSum.o
cc -c -c -w -fPIC -g3 -Og -D__EMULATE_SOS__ -I../../libSOS/trunk/include -I. -I../../include -I../lib/ABCUtilSO/src -I../../Bla/trunk/src ../../Bla/trunk/src/CheckSum.c -o build/x86_64-linux-gnu/obj/Bla/Config.o
您会看到它正在从同一个源文件CheckSum.c
构建CheckSum.o
和Config.o
。因此,链接时有多个定义。这是您拥有的不良模式规则的结果。
${OUT2_DIR}%.o:${SOURCES2}