Jar*_*ary 1 c c++ linker makefile
我有一个问题.我在C文件中定义了read-line.c,一个函数print,如下所示:
void history_print(void)
{
/* some stuff */
}
Run Code Online (Sandbox Code Playgroud)
在C++文件command.cc中,我有以下内容:
extern "C" void history_print(void);
Run Code Online (Sandbox Code Playgroud)
然后我只需调用history_print().
#Use GNU compiler
cc = gcc -g
CC = g++ -g
all: shell
tty-raw-mode.o: tty-raw-mode.c
gcc -c tty-raw-mode.c
read-line.o: read-line.c
gcc -c read-line.c
lex.yy.o: shell.l
lex shell.l
$(cc) -c lex.yy.c
y.tab.o: shell.y
yacc -d shell.y
$(CC) -c y.tab.c
command.o: command.cc
$(CC) -c command.cc
shell: y.tab.o lex.yy.o tty-raw-mode.o read-line.o command.o
$(CC) -o shell lex.yy.o y.tab.o tty-raw-mode.o read-line.o command.o -ll -lgen
Run Code Online (Sandbox Code Playgroud)
在我的Makefile中链接规则输出时遇到问题:
Undefined first referenced
symbol in file
history_print command.o
ld: fatal: Symbol referencing errors. No output written to shell
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `shell'
Run Code Online (Sandbox Code Playgroud)
输出-v选项标志为make:
yacc -d shell.y
g++ -g -v -c y.tab.c
Reading specs from /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/specs
Configured with: ../sources/gcc-3.4.6/configure --prefix=/opt/csw/gcc3 --with-local- prefix=/opt/csw --without-gnu-as --with-as=/usr/ccs/bin/as --without-gnu-ld --with-ld=/usr/ccs/bin/ld --enable-threads=posix --enable-shared --enable-multilib --enable-nls --with-included-gettext --with-libiconv-prefix=/opt/csw --with-x --enable- java-awt=xlib --enable-languages=all
Thread model: posix
gcc version 3.4.6
/opt/csw/gcc3/libexec/gcc/sparc-sun-solaris2.8/3.4.6/cc1plus -quiet -v y.tab.c -quiet -dumpbase y.tab.c -mcpu=v7 -auxbase y.tab -g -version -o /var/tmp//ccCi8vXj.s
ignoring nonexistent directory "/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../.. /../../sparc-sun-solaris2.8/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6/sparc- sun-solaris2.8
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6/backward
/opt/csw/include
/opt/csw/gcc3/include
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/include
/usr/include
End of search list.
GNU C++ version 3.4.6 (sparc-sun-solaris2.8)
compiled by GNU C version 3.4.6.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
/usr/ccs/bin/as -V -Qy -s -xarch=v8 -o y.tab.o /var/tmp//ccCi8vXj.s
/usr/ccs/bin/as: SunOS 5.10 118683-05 Patch 04/30/2010
lex shell.l
gcc -g -c lex.yy.c
gcc -c tty-raw-mode.c
gcc -c read-line.c
g++ -g -v -c command.cc
Reading specs from /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/specs
Configured with: ../sources/gcc-3.4.6/configure --prefix=/opt/csw/gcc3 --with-local- prefix=/opt/csw --without-gnu-as --with-as=/usr/ccs/bin/as --without-gnu-ld --with-ld=/usr/ccs/bin/ld --enable-threads=posix --enable-shared --enable-multilib --enable-nls --with-included-gettext --with-libiconv-prefix=/opt/csw --with-x --enable- java-awt=xlib --enable-languages=all
Thread model: posix
gcc version 3.4.6
/opt/csw/gcc3/libexec/gcc/sparc-sun-solaris2.8/3.4.6/cc1plus -quiet -v command.cc -quiet -dumpbase command.cc -mcpu=v7 -auxbase command -g -version -o /var/tmp//cckVWlC7.s
ignoring nonexistent directory "/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../sparc-sun-solaris2.8/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6/sparc-sun-solaris2.8
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../../../include/c++/3.4.6/backward
/opt/csw/include
/opt/csw/gcc3/include
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/include
/usr/include
End of search list.
GNU C++ version 3.4.6 (sparc-sun-solaris2.8)
compiled by GNU C version 3.4.6.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
/usr/ccs/bin/as -V -Qy -s -xarch=v8 -o command.o /var/tmp//cckVWlC7.s
/usr/ccs/bin/as: SunOS 5.10 118683-05 Patch 04/30/2010
g++ -g -v -o shell lex.yy.o y.tab.o tty-raw-mode.o read-line.o command.o -ll -lgen
Reading specs from /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/specs
Configured with: ../sources/gcc-3.4.6/configure --prefix=/opt/csw/gcc3 --with-local- prefix=/opt/csw --without-gnu-as --with-as=/usr/ccs/bin/as --without-gnu-ld --with-ld=/usr/ccs/bin/ld --enable-threads=posix --enable-shared --enable-multilib --enable-nls --with-included-gettext --with-libiconv-prefix=/opt/csw --with-x --enable- java-awt=xlib --enable-languages=all
Thread model: posix
gcc version 3.4.6
/opt/csw/gcc3/libexec/gcc/sparc-sun-solaris2.8/3.4.6/collect2 -V -R /opt/csw/lib -Y P,/opt/csw/lib:/usr/ccs/lib:/usr/lib -Qy -o shell /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crt1.o /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crti.o /usr/ccs/lib/values-Xa.o /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crtbegin.o -L/opt /csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6 -L/usr/ccs/bin -L/usr/ccs/lib -L/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../.. lex.yy.o y.tab.o tty-raw-mode.o read-line.o command.o -ll -lgen -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc -lc /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crtend.o /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crtn.o
ld: Software Generation Utilities - Solaris Link Editors: 5.10-1.497
Undefined first referenced
symbol in file
history_print command.o
ld: fatal: Symbol referencing errors. No output written to shell
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `shell'
Run Code Online (Sandbox Code Playgroud)
我想问题是由于链接,它与Makefile有关,但我不知道如何修复.有人可以帮帮我吗?
非常感谢,非常感谢你的帮助.
Jary
这是因为您正在重新编译该a.c文件,g++并且没有extern C围绕函数定义的包装器.因此,名称将进行C++重整会有不print中a.o的目标文件.
然而,b.cc会认为print是C的名字(因为它具有的extern C),所以它会去寻找未重整版本.
要么放入extern C定义a.c(这可能会使常规C编译器无法使用,所以请记住这一点)或更改您g++要使用的命令a.o(由于它是用C编译器完成的事实而具有未命名的名称)的a.c.
实际上,这不起作用,因为您没有在g++命令中调用链接器.我什至不知道为什么你要包括a.o到b.o.可能最好的时间是在链接时创建ab可执行文件,而不是编译时间,例如:
CC = g++ -g
a.o: a.c
gcc -o a.o -c a.c
b.o: b.cc
$(CC) -o b.o -c b.cc
ab: a.o b.o
$(CC) -o ab a.o b.o
Run Code Online (Sandbox Code Playgroud)
更新:将其分解为最简单的测试用例,以便您可以看到我的意思:
a.c:
#include <stdio.h>
void print(void) {
printf ("7\n");
}
b.cc:
extern "C" void print(void);
int main(void) {
print();
return 0;
}
Makefile:
output: a.o b.o Makefile
g++ -o output a.o b.o
a.o: a.c Makefile
gcc -o a.o -c a.c
b.o: b.cc Makefile
g++ -o b.o -c b.cc
Run Code Online (Sandbox Code Playgroud)
然后运行make和程序:
pax> make
gcc -o a.o -c a.c
g++ -o b.o -c b.cc
g++ -o output a.o b.o
pax> ./output
7
Run Code Online (Sandbox Code Playgroud)
如果您更改a.c要使用的编译,g++则会在原始错误中找不到print:
pax> make
g++ -o a.o -c a.c
g++ -o b.o -c b.cc
g++ -o output a.o b.o
b.o:b.cc:(.text+0x2b): undefined reference to `_print'
collect2: ld returned 1 exit status
make: *** [output] Error 1
Run Code Online (Sandbox Code Playgroud)
现在看来你的最终Makefile是正确的.它a.c使用C编译器进行编译,因此不会发生名称修改.我的建议是清理所有内容(删除所有*.o文件)并make再次运行,然后将输出发布在问题的底部.
可能有些文件是较旧的文件,这就是为什么你应该在运行之前删除所有目标文件的原因make.
| 归档时间: |
|
| 查看次数: |
2746 次 |
| 最近记录: |