为什么使用-l时gcc动态链接?

时间:2018-09-11 18:59:42

标签: gcc linker shared-libraries static-libraries

我使用 pthread 库执行了“ Hello World”程序。 我用以下简单方式进行编译:

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      :address => "smtp.mandrillapp.com",
      :port => 587,
      :domain => 'www.xyz.com',
      :user_name => 'xyz',
      :password => 'xxx',
      :authentication => :plain,
      :enable_starttls_auto => true 
  } 

根据gcc文档(“链接选项”部分):

  

-l <​​em>库 [...]链接程序在标准目录列表中搜索该库,该库实际上是一个名为lib library .a的文件。链接器   然后使用该文件,就好像它是通过名称精确指定的一样。   [...]

所以,我的理解是:gcc正在寻找 libpthread.a 。给定.a结尾,这应该是一个静态库。

但是,这是动态链接的:

import Foundation
import CoreLocation

class LocationOperation: Operation, CLLocationManagerDelegate {

  // MARK: Properties
  private var manager: CLLocationManager?
  private let handler: (CLLocation) -> Void

  // MARK: Initialization
  init(locationHandler: @escaping (CLLocation) -> Void) {
    self.handler = locationHandler
    super.init()
  }

  // MARK: Main
  override func main() {
    DispatchQueue.main.async {
      let manager = CLLocationManager()
      manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
      manager.delegate = self
      manager.startUpdatingLocation()
    }
  }

  override func cancel() {
    DispatchQueue.main.async {
      self.stopLocationUpdates()
      super.cancel()
    }
  }

  private func stopLocationUpdates() {
    manager?.stopUpdatingLocation()
    manager = nil
  }

  // MARK: CLLocationManagerDelegate
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last,
      location.horizontalAccuracy <= manager.desiredAccuracy else {
        return
    }
    stopLocationUpdates()
    handler(location)
  }

  func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    stopLocationUpdates()
    print("Failure to find location") // handle this eventually
    self.cancel()
  }
}

我想念什么?

1 个答案:

答案 0 :(得分:0)

GCC手册中-l|--library选项的记载具有误导性, 因为它没有指定选项在支持的系统上的行为 共享库,或警告我们不这样做。

-l选项将传递给链接器,通常是GNU ld(或替代插件)。 ld manual中该选项的文档 更为出色,并表明共享库将满足-l选项 优先于静态库。

  

-l namespec

     

-library = namespec

     

将namespec指定的归档文件或目标文件添加到要链接的文件列表中。   此选项可以使用多次。如果namespec的格式为:filename,   ld将在库路径中搜索名为filename的文件,否则它将搜索>   名为libnamespec.a的文件的库路径。

     

在支持共享库的系统上,ld可能还会搜索libnamespec.a以外的文件。   具体地说,在ELF和SunOS系统上,ld将在目录中搜索名为libnamespec.so的库,然后再搜索名为libnamespec.a的库。。   (按照惯例,.so扩展名表示共享库。)   请注意,此行为不适用于:filename,它始终指定一个名为filename的文件。

     

链接器将在命令行中指定的位置仅搜索一次存档。   如果存档定义了在存档之前出现的某个对象中未定义的符号   在命令行上,链接器将包含存档中的相应文件。   但是,稍后出现在命令行中的对象中未定义的符号将   不会导致链接器再次搜索档案。

     

...

(我的重点)