叮当链接器不识别-e选项,但GCC链接器识别

叮当链接器不识别-e选项,但GCC链接器识别,gcc,makefile,clang,ld,entry-point,Gcc,Makefile,Clang,Ld,Entry Point,我想使用一个Makefile来生成一个二进制文件,为我进行单元测试。它获取我的程序的所有对象文件,以及一个已编译的tester对象,并将其打包在一起。问题是,我想在测试仪文件中使用自定义入口点,而不是main 所以没问题,ld带有一个标志-e,我可以在这里指定所述入口点。所以在我的Makefile中,我写了: $(CC) $(ALL_CFLAGS) -Wl,-e$(TEST_ENTRY) $(OBJDIR)/$(TEST_SUITE:.c=.o) $(OBJECTS) -o $(BINDIR)/

我想使用一个Makefile来生成一个二进制文件,为我进行单元测试。它获取我的程序的所有对象文件,以及一个已编译的tester对象,并将其打包在一起。问题是,我想在测试仪文件中使用自定义入口点,而不是
main

所以没问题,
ld
带有一个标志
-e
,我可以在这里指定所述入口点。所以在我的Makefile中,我写了:

$(CC) $(ALL_CFLAGS) -Wl,-e$(TEST_ENTRY) $(OBJDIR)/$(TEST_SUITE:.c=.o) $(OBJECTS) -o $(BINDIR)/$(TARGET)-test
请注意,我正在使用
gcc
函数进行所有链接,因此我必须使用
-Wl
将命令传递给链接器。问题就从这里开始:

在Debian上使用
gcc
,该命令工作正常,我的程序按预期运行

在MacOS上使用
clang
,在编译时出现以下错误:

ld:未知选项:-etester
叮当声:错误:链接器命令失败,退出代码为1(使用-v查看调用)
make:**[测试]错误1

Makefile将入口点(名为
tester
)与参数放在一起,不带任何空格。据我所知,这应该是完全可以接受的?毕竟,
gcc
接受它

如果我添加一个空格,它将假定
$(TEST\u ENTRY)
是编译器的一个参数。我可以用引号来避免这个问题。因此,我也尝试了以下方法:

-Wl,"-e $(TEST_ENTRY)"
然而,我得到了同样的错误

ld:未知选项:-e测试仪

我想问一下,是否有人知道一种解决方案,它可以让clang在不破坏gcc中已经运行的事实的情况下正确运行?也许我在这里遗漏了什么。

(LLVM链接器)说指定入口点的标志是
--entry
。因此,在MacOS上,您必须使用像
-Wl,--entry=$(TEST\u entry)
这样的参数来代替 这似乎与clang的函数名混乱有关。为了避免用户定义的函数名与libc或Sysmte.A中的内在函数名重复,编译器会损坏用户定义的函数名。对于c语言,通常会添加一个‘‘’作为前缀

比如说,

int test(..)
损坏

\u在编译过程中测试

测试项目: 使用
clang helloworld.c-o helloworld
编译时,
执行结果:

╰─$ ./helloworld     
hello world
╰─$ ./helloworld     
hello test entry
使用
clang helloworld.c-o helloworld-e_test编译时,
执行结果:

╰─$ ./helloworld     
hello world
╰─$ ./helloworld     
hello test entry

有关更多详细信息,请参阅或回答问题。

恐怕是同一问题。编辑:等一下,我错过了
=
。是的,我仍然收到
ld:unknown选项:--entry=tester
我觉得
clang
没有正确地将参数传递到
lld
。谢谢你的回答,Simon,但是附加u>没有任何作用。我继续收到相同的错误:
ld:unknown选项:--entry=\u tester
@FinnRayment命令:
clang helloworld.c-o helloworld-e\u test
not.:
clang helloworld.c-o helloword--entry=\u test
。注意,
-e
\u test
之间不存在空白。请参阅
man clang
了解详细的clang命令用法,或回答询问。因此,我似乎可以完全绕过使用
-Wl
,直接将其传递给clang的
gcc
别名。这也适用于GNU
gcc
。我现在唯一的问题是,clang附加了这个额外的
,我可以检查一下。你能在回答中加上你的评论吗?我会把它标记为正确的?谢谢你的帮助。事实上,这是一件非常复杂的事情。这与ABI:应用程序二进制接口
有关。在编程历史中定义了几种不同的ABI标准,。ABI不仅关系到函数名的混乱方式,还关系到调用
调用
指令时函数参数如何传入,以及堆栈平衡方法和局部变量排序。不同的编译器(或编译器版本)可能使用不同的ABI标准,我在ubuntu(-Wl,-etest)上试过clang-6.0,在ubuntu(-etest)上试过clang-8.0,在mac(-e_测试)上试过clang-10.0。我在mac上也使用clang-10.0,如果clang-6.0和8.0需要不同的参数,那么这就是问题所在。无论如何,我正在迁移到
autoconf
,因此这将解决我所有的长期问题。