Sources/PackageManagerDocs/Documentation.docc/Dependencies/ExampleSystemLibraryPkgConfig.md
Create an Command-line executable package that uses libgit2 as a system library dependency.
The following example walks through creating a binary executable that depends on libgit2.
Create a directory called example, and initialize it as a package that builds an executable:
$ mkdir example
$ cd example
example$ swift package init --type executable
Edit the Sources/example/main.swift so it consists of this code:
import Clibgit
let options = git_repository_init_options()
print(options)
Add a systemLibrary target to Package.swift that uses the pkgConfig parameter to look up the location of the library.
// swift-tools-version:6.1
import PackageDescription
let package = Package(
name: "example",
targets: [
.systemLibrary(
name: "Clibgit",
pkgConfig: "libgit2",
providers: [
.brew(["libgit2"]),
.apt(["libgit2-dev"])
]
)
]
)
The above example specifies two providers that Swift Package Manager can use to install the dependency, if needed.
Note: For Windows-only packages
pkgConfigshould be omitted aspkg-configis not expected to be available. If you can't or don't want to use thepkgConfigparameter, pass the path of a directory containing the library using the-Lflag in the command line when building your package instead.bash% swift build -Xlinker -L/usr/local/lib/
This example follows the convention of prefixing modules with C and using camelcase for the rest of the library, following Swift module name conventions.
This allows you to create and use another module more directly named after the library that provides idiomatic Swift wrappers around the underlying C functions.
Create a directory Sources/Clibgit in your example project, and add a module.modulemap in the directory:
module Clibgit [system] {
header "git2.h"
link "git2"
export *
}
In the same directory, create the header file, git2.h, that the above module map references:
// git2.h
#pragma once
#include <git2.h>
Tip: Try to avoid specifying an absolute system path in the module map to the
git2.hheader provided by the library. Doing so will break compatibility of your project between machines that use a different file system layout or install libraries to different paths.
The example directory structure should look like this now:
.
├── Package.swift
└── Sources
├── Clibgit
│ ├── git2.h
│ └── module.modulemap
└── main.swift
With the system library target fully defined, you can now use it as a dependency in other targets.
For example, in Package.swift:
// swift-tools-version:6.1
import PackageDescription
let package = Package(
name: "example",
targets: [
.executableTarget(
name: "example",
dependencies: ["Clibgit"],
path: "Sources"
),
.systemLibrary(
name: "Clibgit",
pkgConfig: "libgit2",
providers: [
.brew(["libgit2"]),
.apt(["libgit2-dev"])
]
)
]
)
Now run the command swift run in the example directory to create and run the executable:
% example swift run
Building for debugging...
[1/1] Write swift-version-3E695E30EE234B31.txt
Build of product 'example' complete! (0.10s)
git_repository_init_options(version: 0, flags: 0, mode: 0, workdir_path: nil, description: nil, template_path: nil, initial_head: nil, origin_url: nil)