/usr/bin/C++ 不能用共享库编译为 gcc
Posted
技术标签:
【中文标题】/usr/bin/C++ 不能用共享库编译为 gcc【英文标题】:/usr/bin/C++ not compile as gcc with Shared library 【发布时间】:2016-12-14 07:15:59 【问题描述】:我尝试在共享库上工作。
详细来说,我关注这个链接: http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html.
这个命令一切正常:
$ gcc -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
$ ./test
但是当我从 gcc 更改为 /usr/bin/c++ 时,将命令更改为:
$ /usr/bin/c++ -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test2 main.c -lfoo
/tmp/ccpEHbNV.o: In function `main':
main.c:(.text+0x16): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
在我的 libfoo.so 中找不到方法 foo。
我也尝试用另一种方式使用 -rdynamic,它也适用于 gcc:
gcc -rdynamic ./libfoo.so -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
但是 /usr/bin/c++ 也有同样的错误。
请告诉我如何使它与 /usr/bin/c++ 一起工作。
非常感谢。
【问题讨论】:
除了g++之外,你有没有其他c++编译器? 不要混合和匹配编译器,名称修改将不匹配。使用gcc
或g++
编译lib 和main.c
,而不是两者。如果您确实需要在 C 和 C++ 中使用 lib,也可以使用 extern "C"
和适当的编译器保护来包装声明。
/usr/bin/c++
是 C++ 编译器的标准名称。它可以是您系统上的任何编译器。例如,在我的系统上它与g++
相同。您可以使用ls -l /usr/bin/g,c++
进行检查。在某些系统上,c++
是指向g++
的符号链接。在我的系统上,它只是 g++ 的一个副本(使用 md5sum /usr/bin/g,c++
检查)。所以除非你告诉我们哪个编译器伪装在/usr/bin/c++
下,否则无法回答。顺便说一句,这些命令适用于g++
,因此您的c++
不太可能是g++
。
C 和 C++ 是不同的语言。如果您使用 C 编译器编译库并使用 C++ 编译器编译代码,则需要确保使用 C++ 中的 C 链接声明库的函数。
我不明白。 /usr/bin/c++ 是 C++ 正确的编译器。如果我将任何内容从 C 更改为 Cpp。我也遇到了同样的问题。
【参考方案1】:
正如其他人所说,这是因为 C 和 C++ 编译库之间的符号命名不同,由于 C++ 具有重载函数,因此每个符号的命名应包括符号名称中的参数类型或标识实际函数或类方法的内容它的论点。 与 C++ 不同,C 没有这个问题,因为没有函数重载和它的标准 ABI。如果你想混合 C/C++ 文件,你必须用 g++ 编译所有 C 和 C++ 代码,并在 C 代码的定义中添加 extern C 关键字
#ifdef __cplusplus
extern "C"
#endif
// your C definitions (only function definitions) goes here
#ifdef __cplusplus
#endif
【讨论】:
【参考方案2】:问题的出现可能是因为 C++ 的名称错误。 /usr/bin/c++ 以 /usr/bin/g++ 结束。 gcc 是 C 编译器,而 g++ 是 C++ 编译器。您需要使用 g++ 编译您的库 libfoo.so,然后尝试链接。它应该可以工作。
【讨论】:
“gcc 是 C 编译器,而 g++ 是 C++ 编译器” - GCC 是 C 和 C++ 编译器。从手册页中阅读 NAME 部分。 我知道 gcc 的意思是 GNU 编译器集合。从历史上看,gcc 是 C 语言的命令。【参考方案3】:你使用的gcc和c++是什么版本的?
理想情况下,在 same 编译器工具链系列中应该没有错误。
事实上,我编写了代码,编译并执行了相同的示例,没有任何问题。
请注意我使用的 gcc/c++ 版本。
gcc (GCC) 6.2.1 20160830
g++ (GCC) 6.2.1 20160830
我写了一个shell脚本文件来执行命令
strace c++ -c -Wall -Werror -fpic foo.c
strace c++ -shared -o libfoo.so foo.o
strace c++ -L. -Wall -o test main.c -lfoo
并收集编译和链接的 strace 输出。请看下面的链接 http://pastebin.com/nJpQuCfS
希望这会有所帮助。
【讨论】:
以上是关于/usr/bin/C++ 不能用共享库编译为 gcc的主要内容,如果未能解决你的问题,请参考以下文章