C 将一个程序与两个静态库链接,每个库包含依赖于另一个库中函数的函数?

C 将一个程序与两个静态库链接,每个库包含依赖于另一个库中函数的函数?,c,static-libraries,C,Static Libraries,实际上,我正试图从另一个函数b(存储在libb.a中)调用一个函数a(存储在liba.a中),但我有一个链接错误 这是我的文件: a、 c main.c void b(); int main(int argc, char const* argv[]) { b(); return (0); } 我是如何编译的 gcc -c a.c gcc -c b.c ar rc liba.a a.o ar rc libb.a b.o ranlib liba.a ranlib libb.a gcc ma

实际上,我正试图从另一个函数
b
(存储在libb.a中)调用一个函数
a
(存储在liba.a中),但我有一个链接错误

这是我的文件:

a、 c

main.c

void b();
int main(int argc, char const* argv[])
{
  b();
  return (0);
}
我是如何编译的

gcc -c a.c
gcc -c b.c
ar rc liba.a a.o
ar rc libb.a b.o
ranlib liba.a
ranlib libb.a
gcc main.c liba.a libb.a
(确切的消息错误)

有没有办法做我想做的事? 谢谢你的时间

编辑: 看来命令行中的库顺序很重要。
但是在我真正的问题中,libA依赖于libB,libB依赖于libA(MCVE代码没有演示)。

在您已经拥有的
a.c
b.c
main.c
目录中创建以下
Makefile

#!/usr/bin/make

ar:
        gcc -o a.o -c a.c
        gcc -o b.o -c b.c
        gcc -o m.o -c main.c
        ar rc liba.a a.o
        ar rc libb.a b.o
        ar rc libm.a m.o
        ranlib liba.a
        ranlib libb.a
        ranlib libm.a
        gcc -o main m.o a.o b.o

install:
        gcc -o a.o -c a.c
        gcc -o b.o -c b.c
        gcc -o m.o -c main.c
        gcc -o main m.o a.o b.o

clean:
        rm -f *.o
        rm -f *.a
        rm -f main
基本上,您的问题是C中多文件开发的一个示例

  • 如果发出
    makeinstall
    命令,则
    Makefile
    将使用标准gcc编译过程编译程序
  • 如果您发出
    make ar
    ,编译将是
    ar
    包装合规性
  • 如果发出
    makeclean
    ,则
    Makefile
    将清除您以前的生成
编辑:命令行中的库顺序似乎很重要。但在我真正的问题中,libA依赖于libB,libB依赖于libA(MCVE代码没有演示)

那么,你真正的问题是你把自己画在角落里了。正确的做法是安排两个库,使其中一个库完全独立于另一个库,并将它们依次放入link命令中

如果不进行更改,您可能会两次提到第一个库

gcc main.c liba.a libb.a liba.a
当涉及到名称解析时,链接器非常简单。它从一个未解析名称列表开始,遍历库列表,在找到名称时解析名称。它不会注意到你给它liba.a两次;它将解析
b
提供的
a
名称,然后解析
a
提供的
b
名称


但这种伎俩有一天可能会咬到你(如果它真的管用的话)。正如我所说的,最好的办法是理清你的依赖关系,为你自己和跟随你的人简化事情

如果你交换订单,有什么变化吗
gcc main.c libb.a liba.a
命令行上库的顺序很重要。如果B库依赖于库A,那么B必须在命令行之前出现在A上。在一个无关的注释中,不同于C++声明没有任何显式参数的函数(如声明“代码> < < /COD>和<代码> B<代码>”),并不意味着函数没有参数。如果函数不带参数,则必须指定
void
作为参数(如
void a(void);
)。当然,您只有一组空括号,就像您在显示的代码中所做的那样,在C语言中,这意味着函数接受数量不确定的不确定类型的参数。确切的参数是在首次调用函数时确定的(如果在不同的转换单元中有不同的调用,则可能会导致问题)。一对静态库之间的相互依赖是一种特殊形式的炼狱。如果您无法更改某些内容,使得只有一个库调用另一个库中的函数(最简单的解决方案),那么您最好将两个库合并为一个库,因为这两个库都不再是独立的单元。您可以切换到共享库,这将隐藏问题。其他选项包括多次重新扫描这对静态库(每个库扫描两次是否足够?),以及创建用于确保加载正确内容的符号(这既困难又不可靠,需要避免)。如果要将a.o和b.o对象与main一起链接,首先制作库有什么意义?在
gcc-c a.c
中,不使用gcc的object开关,gcc将自动为您创建一个.o对象。在回答这个问题时,我使用
gcc-oa.o-ca.c
将对象名传递给gcc。基本上,这两个命令将产生相同的输出。
b.c:(.text+0xa): undefined reference to `a'
#!/usr/bin/make

ar:
        gcc -o a.o -c a.c
        gcc -o b.o -c b.c
        gcc -o m.o -c main.c
        ar rc liba.a a.o
        ar rc libb.a b.o
        ar rc libm.a m.o
        ranlib liba.a
        ranlib libb.a
        ranlib libm.a
        gcc -o main m.o a.o b.o

install:
        gcc -o a.o -c a.c
        gcc -o b.o -c b.c
        gcc -o m.o -c main.c
        gcc -o main m.o a.o b.o

clean:
        rm -f *.o
        rm -f *.a
        rm -f main
gcc main.c liba.a libb.a liba.a