【问题标题】:Adding functionality to Makefile gives error :- "multiple definitoon here ..."向 Makefile 添加功能会产生错误:-“这里有多个定义...”
【发布时间】:2013-01-22 11:18:55
【问题描述】:

我已经获得了一个已经在工作的 Makefile,它实际上工作正常。

Makefile 的内容可以在这篇文章中找到……

Questions about Makefile - what is "$+" & where are .c files/dependencies called here ?

我将这个问题与我上面提到的上一篇文章分开提出,因为它涉及不同的问题,并且将其添加到该问题会不必要地增加其长度。

现在我又添加了一个在很多地方都非常频繁使用的功能,所以我认为创建一个单独的文件是个好主意,所以我创建了linklayer.c 并将linklayer.o 添加到$LIBOBJS

我添加了这个...

 LIBOBJS= linklayer.o csum.o compact.o protoname.o headers.o 
 parseargs.o cryptomod.o crc32.o

还有这个

 linklayer.o:    linklayer.c
    $(CC) -o $@ -c -I. $(CFLAGS) $+

我在sendip_module.h 中声明了函数,该函数已在项目中的每个模块中声明和访问。

但是现在这个多重定义错误来了......我做错了什么或误解了什么?

注意:“ipv6_opts”在 ipv6.h 中定义

$ make all
for subdir in mec ; do \
    cd $subdir ;\
    make  ;\
    cd ..  ;\
    done
make[1]: Entering directory `/home/udit/Desktop/sendip-2.5-mec-2/mec'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/udit/Desktop/sendip-2.5-mec-2/mec'
  gcc-4.4 -o ipv6.so -fPIC -fsigned-char -pipe -Wall -Wpointer-arith 
 -Wwrite-strings -Wstrict-prototypes -Wnested-externs -Winline -Werror
 -g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\" -shared ipv6.c
  libsendipaux.a libsendipaux.a

 libsendipaux.a(linklayer.o):(.data.rel.local+0x0)
                              : multiple definition of `ipv6_opts'
 /tmp/ccxa4tMX.o:(.data.rel.local+0x0): first defined here
 collect2: ld returned 1 exit status
 make: *** [ipv6.so] Error 1

为什么这libsendipaux.a libsendipaux.a 两次? Makefile 本身是否有问题。

是否需要先手动编译,然后添加到 libsendipaux.a 中?

我是这个 Makefile 东西的新手,所以请帮助我了解这一切是如何运作的?

谢谢。

编辑:

重新制作调试输出 -

 remake -x

Reading makefiles...
Updating goal targets....
/home/udit/Desktop/sendip-2.5-mec-2/Makefile:33 File `all' does not exist.
/home/udit/Desktop/sendip-2.5-mec-2/Makefile:48 File `subdirs' does not exist.
/home/udit/Desktop/sendip-2.5-mec-2/Makefile:48 Must remake target `subdirs'.
for subdir in mec ; do \
    cd $subdir ;\
    make  ;\
    cd ..  ;\
    done
make[1]: Entering directory `/home/udit/Desktop/sendip-2.5-mec-2/mec'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/udit/Desktop/sendip-2.5-mec-2/mec'
/home/udit/Desktop/sendip-2.5-mec-2/Makefile:48 Successfully remade target file    
`subdirs'.
File `ipv6.so' does not exist.
Must remake target `ipv6.so'.
gcc-4.4 -o ipv6.so -fPIC -fsigned-char -pipe -Wall -Wpointer-arith 
-Wwrite-strings -Wstrict-prototypes -Wnested-externs -Winline -Werror 
-g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\" -shared ipv6.c 
 libsendipaux.a libsendipaux.a
 libsendipaux.a(linklayer.o):(.data.rel.local+0x0)
                                  : multiple definition of `ipv6_opts'
 /tmp/ccb0oaXR.o:(.data.rel.local+0x0): first defined here
 collect2: ld returned 1 exit status
 remake: *** [ipv6.so] Error 1

 #0  ipv6.so at ??
 #1  all at /home/udit/Desktop/sendip-2.5-mec-2/Makefile:33

33rd line -> all: $(LIBS) subdirs sendip $(PROTOS) sendip.1 sendip.spec

我想这对我没有帮助....实际问题在于我对场景本身的理解。请帮我摆脱混乱。

【问题讨论】:

  • 建议:安装remake并使用remake -x调试你的Makefile;也可以运行make -p 来找出默认规则。
  • 谢谢...我现在就做,如果发现什么就更新。
  • 你了解声明函数和定义函数的区别吗?您可以发布代码的最小完整示例吗? (这看起来像是代码问题,而不是 Make 问题。)

标签: gcc makefile static-libraries static-linking


【解决方案1】:

您面临的问题是,您将多个对象链接在一起,其中至少两个对象定义了函数ipv6_opts。 由于该函数有两种实现,因此您的链接器无法决定使用哪一种并引发错误。

问题很可能来自您将libsendipaux.a 两次链接到最终二进制文件的事实。

发生这种情况的原因在这里:

 %.so: %.c $(LIBS)
        $(CC) -o $@ $(CFLAGS) $(LIBCFLAGS) $+ $(LIBS)

在此目标中,$+ 将扩展为您目标的所有依赖项(即:%.c $(LIBS),而这又将解析为 ipv4.c libsendipaux.a

对编译器的实际调用可以读取为$(CC) -o $@ $(CFLAGS) $(LIBCFLAGS) ipv4.c $(LIBS) $(LIBS),而$(LIBS) $(LIBS) 将扩展为libsendipaux.a libsendipaux.a,这将产生错误的双链接。

所以解决方案是从 .so 目标中删除无关的 $(LIBS):

 %.so: %.c $(LIBS)
        $(CC) -o $@ $(CFLAGS) $(LIBCFLAGS) $+

顺便说一句,您在remake 中遇到的关于不存在文件的错误是因为allsubdirs 确实没有文件,而是虚假目标(目标不生成在目标名称之后调用的文件) .

为防止出现这些警告,请在您的 makefile 中添加如下内容:

.PHONY: all subdirs

【讨论】:

    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    相关资源
    最近更新 更多