Using modulemaps

As a way to learn more about modulemaps, I'm trying to call GTK from Swift. I'm using swift-package-manager/Usage.md at main · apple/swift-package-manager · GitHub as documentation.

I tried the libgit2 example and got that working (albeit with a different manifest than in the documentation). However, GTK is a bit more difficult.

What I have so far:

Manifest for CGTK:

let package = Package(
    name: "CGTK",
    products: [
        .library(name: "CGTK", targets: ["CGTK"])
    ],
    targets: [
        .systemLibrary(name: "CGTK", pkgConfig: "gtk+-3.0")
    ]
)

And the following modulemap:

module CGTK [system] {
  header "/usr/local/include/gtk-3.0/gtk/gtk.h"
  link "gtk-3.0"
  export *
}

Manifest for my Demo app:

let package = Package(
    name: "Demo",
    dependencies: [
        .package(url: "../CGTK", from: "0.0.1")
    ],
    targets: [
        .target(name: "Demo", dependencies: ["CGTK"])
    ]
)

Unfortunately, I'm unable to build this Demo app because GTK requires GDK and it cannot find the gdk/gdk.h header (which is /usr/local/include/gtk-3.0/gdk/gdk.h)

How should I proceed?

  • Should I add build flags (for a C example, those are pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0)?
  • Should I create additional modules for GDK, Glib and other dependencies?
  • Something else?

Thanks!

I have a working example at https://github.com/Longhanks/gtk-test, which uses this modulemap: https://github.com/Longhanks/gtk-modulemap-linux

You can test it with the included make.sh script, but I have to admit, the code could be vastly improved.

Thanks @Longhanks. I will definitely take a look at your repo.

W.r.t. my issue: Turns out I was just confused by the outdated documentation at swift-package-manager/Usage.md at main · apple/swift-package-manager · GitHub

After digging a bit deeper (following the warnings eventually led me to a solution), the solution is very simple. It only requires a single package:

let package = Package(
    name: "Demo",
    targets: [
        .systemLibrary(name: "CGTK", pkgConfig: "gtk+-3.0"),
        .target(name: "Demo", dependencies: ["CGTK"])
    ]
)

With the following manifest in Sources/CGTK:

module CGTK [system] {
  header "/usr/local/include/gtk-3.0/gtk/gtk.h"
  export *
}

So far this seems to work! I can build and run with just the normal swift build and swift run commands, and everything works fine in Xcode as well.

I'll report my issues via the bug reporter and ask for an update to the docs.