/home/snyp1/new
文件夹中有两个文件->fact.h
和main.c
。main.c
具有调用fact.h
中的fact(int x)
函数的主函数。我正在使用ar命令->创建.a
存档
snyp1@Snyp:~/new$ ar -r -s libfact.a fact.o
ar: creating libfact.a
fact.h fact.o libfact.a main.c
snyp1@Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
snyp1@Snyp:~/new$ ranlib libfact.a
snyp1@Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
我在ubuntu 12.04。请告诉我出了什么问题。(此外,如果我不使用-L/.../new
,gcc会说它找不到"lfact",可能是因为它不在/usr/local/lib
中)
编辑:好的,我找到原因了。这是因为我使用fact.h
构建fact.o
,然后将其放入库中,所以它没有按预期工作。所以我现在把它改成了file.c
,现在工作得很好。对不起,我本应该提供这些信息的。虽然我不知道为什么会出现这种问题。难道库中没有至少一个.c
文件就不可能创建吗?
我用fact.h构建了fact.o,然后把它放在库中,结果并没有像预期的那样工作。
你的意思是你在编译fact.h
来产生fact.o
吗?
如果是这样的话,那就不是你所期望的。在头文件上调用gcc
时,它会生成预编译的头,而不是对象文件。因此,尽管您得到了一个名为foo.o
的文件,但它不是一个有效的对象文件。如果您刚刚运行gcc -c fact.h
,它会产生一个预编译的头fact.gch
,但可能您运行了gcc -c fact.h -o fact.o
,这会导致文件被称为fact.o
,即使它仍然是一个预编译器头。file fact.o
会显示:
$ file fact.o
fact.o: GCC precompiled header (version 013) for C
通过运行gcc -x c -c fact.h -o fact.o
(-x c
表示将输入视为C代码,而不是从文件扩展名推断类型),您可以强制GCC将文件视为C码,而不是标头,但只正确命名文件而不是试图编译标头可能更简单,也不那么令人困惑。
难道没有一个.c文件就不能创建库吗?
他们至少需要一个对象文件(即.o
文件),但您没有一个有效的对象,您有一个预先编译的头,错误地命名为.o
,但它实际上不是一个对象。
如果我不使用
-L/.../new
,gcc会说它找不到"lfact",可能是因为它不在/usr/local/lib
中
链接器不仅在/usr/local/lib
中查找,它还查找其他默认位置,但是的,这基本上就是问题所在。注意,如果库在当前目录中,也可以说-L.
,这比给出绝对路径更容易。
我不确定ar
是否支持第一个选项以外的任何内容上的短划线。尝试
ar -rs libfact.a fact.o
或者只是
ar rs libfact.a fact.o
请注意,我不知道为什么运行ranlib
不起作用。