【问题标题】:Is it not allowed create a static library without a .c file in it?不允许创建一个没有 .c 文件的静态库吗?
【发布时间】:2012-07-28 22:56:03
【问题描述】:

我有两个文件 -> /home/snyp1/new 文件夹中的 fact.hmain.cmain.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 文件,就不能创建库吗?

【问题讨论】:

    标签: gcc static-libraries unix-ar


    【解决方案1】:

    我使用 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.,这比提供绝对路径更容易。

    【讨论】:

    • 感谢您的解释。我在头文件中有函数体,如果我做 $gcc main.c -o main ,它工作得很好,我不知道头文件被转换成预编译的头文件。
    • 确实,一个精心设计的头文件只包含接口,不包含实现,所以如果你把它编译成.o它就会是空的。
    【解决方案2】:

    我不确定ar 是否支持除第一个选项之外的任何内容。试试

    ar -rs libfact.a fact.o
    

    或者只是

    ar rs libfact.a fact.o
    

    请注意,我不知道为什么运行 ranlib 不起作用。

    【讨论】:

    • 正确,官方用法是:ar [-]p[mod] archive [member...],其中破折号是可选的,p 是要执行的操作(在这种情况下是r),mod 是零个或多个修饰符(在这种情况下s) 所以它应该是ar rsar -rs
    • ar -r -s 是合法的 POSIX 语法,因为 Utility Syntax Guidelines 正在慢慢侵蚀传统的 unix 语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2021-01-05
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    相关资源
    最近更新 更多