链接报错‘Multiple definitions of main’,如何指定使用CPP文件的main?
这个问题我在项目里碰到过好多次,本质是链接器检测到了两个同名的强符号main——你自己代码里的和静态库library.a里的,所以抛出了多重定义错误。下面给你几个实用的解决办法,按稳妥程度排序:
方法1:重命名库中的main符号(最稳妥)
直接修改静态库内部的main符号名,让它和你的自定义main不再冲突。用objcopy工具就能搞定,命令如下:
objcopy --redefine-sym main=library_internal_main library.a
这个命令会把library.a里所有名为main的符号重命名为library_internal_main,之后再正常编译链接你的代码就不会有冲突了,完全不影响库的其他功能。
方法2:调整链接顺序+利用静态库的符号解析规则
静态库的链接器只会把当前未定义的符号对应的目标文件从库中拉出来。如果把你的源文件放在链接命令的最前面,链接器先解析到你的main函数,之后处理library.a时,发现main已经被定义了,就不会再把库中的main对应的目标文件拉进来。
比如你的源文件是my_main.cpp,编译链接命令可以写成:
g++ my_main.cpp library.a -o my_program
注意:这个方法的前提是库中的main所在的目标文件没有被其他必须的符号依赖——如果库中其他代码依赖了那个main,链接器还是会把它拉进来,这时候就会回到冲突问题,所以这个方法有一定局限性。
方法3:用链接器选项强制忽略多重定义(慎用)
如果上面两种方法都不适用,可以用链接器的--allow-multiple-definition选项,让它忽略重复符号的错误,默认使用先遇到的那个符号(也就是你的main,前提是你的源文件放在库前面)。
命令示例:
g++ my_main.cpp library.a -Wl,--allow-multiple-definition -o my_program
⚠️ 注意:这个选项会忽略所有重复符号的错误,不是只针对main,如果你的代码和库还有其他重名符号,可能会导致隐蔽的bug,所以非必要不推荐用。
内容的提问来源于stack exchange,提问作者KudmiSubba

