针对c/c++库进行链接

Linking against a c/c++ library

本文关键字:链接 c++ 针对      更新时间:2023-10-16

我有一些关于链接C/C++库的基本问题。我试图理解使用两种不同用法-L/usr/local/lib -lm用法和/usr/local/lib/libm.a用法的区别。例如,当我编译并链接[SUNDIALS]库中的一个示例时,以下两项工作都是

gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe -I/usr/local/include -L/usr/local/lib/ -lsundials_cvode -lsundials_nvecserial -lm

gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe /usr/local/lib/libsundials_cvode.a /usr/local/lib/libsundials_nvecserial.a

然而,要编译并链接库[libsbml]中的一个示例,以下操作

g++ -Wall readSBML.cpp -o readSBML.exe -I/usr/local/include -L/usr/local/lib -lsbml

但这不是

g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.a

如果需要,我可以发布我得到的完整错误消息,但消息的最后一行如下

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

我的问题如下:

  1. 在(第一示例的)第二种类型的链接中,没有关于在哪里找到include文件(头文件)的信息,编译器如何知道在第一示例的第一种类型中提供的-I/usr/local/include中提供的信息?

  2. 在第一个示例的第二个样式中没有/usr/local/lib/libm.a(如果我试图包含它,它实际上会给出一个错误消息,即找不到libm.a),那么为什么第一个样式中需要-lm

  3. 如何以第二种风格(即使用/usr/local/lib/libsbml.a)编译第二个示例?我确实看到/usr/local/lib文件夹中有文件libsbml.alibsbml-static.a,但它们都不起作用。

如果有帮助的话,我在OS X机器上。

如果有人能在这方面提供帮助,我将不胜感激。

只是更新-我试过

g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.5.dylib

而且编译和链接都很好。

谢谢SN

一般情况下

  • -L选项用于查找库本身的位置。每个库都是一个或多个目标代码(机器语言)文件的集合。无需查找包含文件
  • -I选项与链接器无关,它帮助编译器解析驱动程序中使用的头文件(例如Roberts_dns.c)。这发生在预处理阶段

在(第一个示例的)第二种链接样式中,没有关于在哪里找到包含文件(头文件)的信息,。。

如果编译按预期进行,可能是因为/usr/local/include位于gcc的默认包含路径中。要检查gcc的默认包含路径,请执行gcc -xc -E -v -

在第一个例子的第二种风格中没有/usr/local/lib/libm.a(它实际上给出了一条错误消息,即libm.a如果我试图将其包含在内,则无法找到),那么为什么在中需要-lm第一种风格?

在Linux中,一些库(如libc.a)默认情况下直接链接到您的可执行库,而libm.a则不是。不过,在Mac(您的环境)中,libm默认情况下直接链接到可执行文件。所以你不必显式地链接它。libm.a位于/usr/local/lib/中的可能性较小。所以你犯了一个错误。但为什么一开始就把它联系起来呢?