1

I create a Firebird Swift client library for macOS and Linux, but I need to link the Firebird C library, depending of the system target.

Currently, my library bundle the Firebird Framework for macOS using a xcframework, but I'm unable to do it for Linux, since xcframework only support macOS

I have the following directories:

CFirebird
|- Package.swift
|- Headers
|  |- ibase.h
|  |- iberror.h
|
|- Libraries
|  |- macos
|  |  |- Firebird.xcframework
|  |- linux
|     |- libfbclient.so (and the others libs from firebird)
|
|- Sources
   |- CFirebird
      |- module.modulemap

I have a modulemap for exporting the library

module CFirebird {
    umbrella "../../Headers"
    export *
    link "fbclient"
}

And my Package.swift

let package = Package(
    name: "CFirebird",
    platforms: [
        .macOS(.v10_15),
    ],
    products: [
        .executable(
            name: "Firebird",
            targets: ["Firebird"])
    ],
    targets: [
        .binaryTarget(name: "CFirebird-macos", path: "Libraries/macos/Firebird.xcframework"),
        .systemLibrary(name: "CFirebird"),
        .target(
            name: "Firebird",
            dependencies: [
                "CFirebird",
                .target(name: "CFirebird-macos", condition: .when(platforms: [.macOS])),
            ],
            linkerSettings: [
                .linkedLibrary("fbclient", .when(platforms: [.linux])),
            ]),
    ]
)

The only way I founded to make it work on Linux is install the Firebird library on the system, but I want to bundle it with the framework.

Is that possible? Did I make some mistakes?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
ugocottin
  • 64
  • 8
  • According to my knowledge it is impossible unless you build your own version of Firebird client library. – user13964273 Mar 30 '21 at 17:13
  • Bundling your own fbclient doesn't sound like a good plan. That prevents people from using a newer (or older) Firebird client library, or you could run into compatibility issues when a client library is compiled with specific options; it would also make it hard to user Firebird 3 and higher Firebird Embedded. – Mark Rotteveel Mar 30 '21 at 17:25
  • So I shouldn’t bundle it with the package and letting the linker link it with the user’s firebird library on this system? In another worlds, rely on the user to link it. – ugocottin Apr 03 '21 at 16:08
  • 1
    Not "it" but "them". There are many CPU architectures of Linux. Even of most popular there would be Intel x86, AMD64, then ARM 32-bits and ARM 64-bits, and then there are MIPS, PowerPC and what not. You would have to bundle and install proper libraries (and libraries are not mere libfbclient.so but also ICU and some data files) for every distro-and-arch of Linux you support. – Arioch 'The Apr 08 '21 at 09:59

1 Answers1

0

Ok, the approach I took was to rely on the user to link the Firebird library, as "Arioch 'The" said. The correct way to do it (in my opinion) is to specify the pkg-config file used for swift. In my case, I would have been libfbclient.pc.

To make swift use pkg-config, replace the following in the package description target:

.systemLibrary(name: "CFirebird", pkgConfig: "libfbclient")

Swift will retrieve the flags from pkg-config to make compilation possible.

ugocottin
  • 64
  • 8