Swift包装管理器在包装后丢失库

时间:2018-12-24 17:46:16

标签: swift-package-manager

我正在尝试为Swift的C库生成包装器,但是当我将其导入到Xcode项目中时,出现了一个错误

  

缺少必需的模块“ Clibsodium”

我不确定它试图从哪里获得这个名字。我的包装器中有Package.swift

// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Sodium",
    pkgConfig: "libsodium",
    providers: [
        .brew(["libsodium"]),
        .apt(["libsodium-dev"])
    ]
)

然后我的module.modulemap看起来像这样:

module Sodium [system] {
  header "shim.h"
  link "sodium"
  export *
}

和shim.h仅包含适当的标头:

#ifndef CLIB_SWIFT_SODIUM
#define CLIB_SWIFT_SODIUM

#ifdef __APPLE__
    #include "/usr/local/include/sodium.h"
#else
    #include "/usr/include/sodium.h"
#endif

#endif

在我的Mac上,如果我运行pkg-config --libs libsodium,则会显示以下信息:

  

-L / usr / local / Cellar / libsodium / 1.0.16 / lib -lsodium

1 个答案:

答案 0 :(得分:0)

我修复了将 Clibsodium 库定义为显式模块的问题。这样做,您可以通过 import Sodium.Clibsodium 之类的Sodium框架导入它,并修复缺少的 Missing required module'Clibsodium'

我在以下方面启发了我的解决方案:

  

为了将C库导入Swift,首先需要   声明为模块。声明采用模块图的形式-   描述要导入的标头和要链接的静态库的文件。   生成的模块可以(自然地)导入Swift和   Objective-C(使用@import关键字)。

     

这种嵌入C库的方式   在大多数情况下,将其整合到一个框架中(了解有关   这种方法在这里和那里)。只要你是合法的   开发一些内部框架或简单地模块化您的   将应用程序划分为多个部分。但是,当   您需要通过迦太基将图书馆运送给外部用户,   Cocoapods或二进制。主要原因是   框架不能在计算机之间移植。当经历   编译后,您生成的框架将绑定到当前位置   您计算机上模块映射中的头文件和库。您可以使用   立即在您的项目中,但是您应该尝试将其发送到   其他人将无法将其链接到项目,因为   模块映射引用的文件不再可访问。

this的文章中,您可以逐步找到如何利用这种方法的优点和缺点来实现它。

基本上,您需要做的是:

  • 创建 Sodium.modulemap 文件并将其添加到项目的根目录
  • Sodium.modulemap 中,您可以将Clibsodium库定义为一个显式模块,例如:

    framework module Sodium {
        umbrella header "Sodium.h"
    
        explicit module Clibsodium {
            private header "version.h"
            private header "crypto_pwhash_argon2id.h"
            private header "export.h"
            private header "core.h"
            private header "crypto_aead_aes256gcm.h"
            private header "crypto_aead_chacha20poly1305.h"
            private header "crypto_aead_xchacha20poly1305.h"
            private header "crypto_auth.h"
            private header "crypto_auth_hmacsha256.h"
            private header "crypto_auth_hmacsha512.h"
            private header "crypto_auth_hmacsha512256.h"
            private header "crypto_box.h"
            private header "crypto_box_curve25519xsalsa20poly1305.h"
            private header "crypto_core_hsalsa20.h"
            private header "crypto_core_hchacha20.h"
            private header "crypto_core_salsa20.h"
            private header "crypto_core_salsa2012.h"
            private header "crypto_core_salsa208.h"
            private header "crypto_generichash.h"
            private header "crypto_generichash_blake2b.h"
            private header "crypto_hash.h"
            private header "crypto_hash_sha256.h"
            private header "crypto_hash_sha512.h"
            private header "crypto_kdf.h"
            private header "crypto_kdf_blake2b.h"
            private header "crypto_kx.h"
            private header "crypto_onetimeauth.h"
            private header "crypto_onetimeauth_poly1305.h"
            private header "crypto_pwhash.h"
            private header "crypto_pwhash_argon2i.h"
            private header "crypto_scalarmult.h"
            private header "crypto_scalarmult_curve25519.h"
            private header "crypto_secretbox.h"
            private header "crypto_secretbox_xsalsa20poly1305.h"
            private header "crypto_secretstream_xchacha20poly1305.h"
            private header "crypto_shorthash.h"
            private header "crypto_shorthash_siphash24.h"
            private header "crypto_sign.h"
            private header "crypto_sign_ed25519.h"
            private header "crypto_stream.h"
            private header "crypto_stream_chacha20.h"
            private header "crypto_stream_salsa20.h"
            private header "crypto_stream_xsalsa20.h"
            private header "crypto_verify_16.h"
            private header "crypto_verify_32.h"
            private header "crypto_verify_64.h"
            private header "randombytes.h"
            private header "randombytes_internal_random.h"
            private header "randombytes_sysrandom.h"
            private header "runtime.h"
            private header "utils.h"
         }
    
      export *
      module * { export * }
    }
    
  • Sodium.modulemap不应添加到任何目标,而必须在内部设置-打包-模块图(MODULEMAP_FILE)= $ SRCROOT / GifSwift / GifSwift.modulemap

    中指定>
  • 必须将Clibsodium文件作为专用标题和链接的静态库(libsodium-x.a)添加到框架目标
  • import Clibsodium 语句替换为 Sodium.Clibsodium

现在您可以在任何项目中使用Sodium框架而不会丢失模块错误,因为Sodium会在.framework容器中查找库