Undefined symbols for architecture x86_64 when trying to wrap a C library

I'm trying to create a Swift package for a wrapper around a C/C++ library, libtcod. I can link to the library directly in a MacOS command line project in Xcode. But when I try to use it in my Swift package, I get:

tom@Thomass-MBP SwiftyTCOD % swift test
ld: warning: Could not find or use auto-linked library '/usr/local/lib/libtcod.dylib'
Undefined symbols for architecture x86_64:
  "_TCOD_console_check_for_keypress", referenced from:
      _$s10SwiftyTCOD7ConsoleC16checkForKeypressSo0B6_key_tayF in Console.swift.o
  "_TCOD_console_flush", referenced from:
      _$s10SwiftyTCOD7ConsoleC5flushyyF in Console.swift.o
  "_TCOD_console_init_root", referenced from:
      _$s10SwiftyTCOD7ConsoleC5width6height5title12isFullScreen8rendererACSgSi_SiSSSbAA8RendererOtcfc in Console.swift.o
  "_TCOD_console_is_window_closed", referenced from:
      _$s10SwiftyTCOD7ConsoleC14isWindowClosedSbvgZ in Console.swift.o
  "_TCOD_console_put_char", referenced from:
      _$s10SwiftyTCOD7ConsoleC7putChar1x1y4char4flagySi_SiSJSo0b7_bkgnd_G2_tatF in Console.swift.o
  "_TCOD_console_set_custom_font", referenced from:
      _$s10SwiftyTCOD7ConsoleC13setCustomFont8fontFile5flags17numCharHorizontal0jK8VerticalySS_S3itFZ in Console.swift.o
  "_TCOD_console_set_default_background", referenced from:
      _$s10SwiftyTCOD7ConsoleC20setDefaultBackgroundyySo0B9_ColorRGBVF in Console.swift.o
  "_TCOD_console_set_default_foreground", referenced from:
      _$s10SwiftyTCOD7ConsoleC20setDefaultForegroundyySo0B9_ColorRGBVF in Console.swift.o
  "_TCOD_quit", referenced from:
      _$s10SwiftyTCOD7ConsoleCfd in Console.swift.o
ld: symbol(s) not found for architecture x86_64
[0/1] Linking SwiftyTCODPackageTests

My Package.swift:

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

import PackageDescription

let package = Package(
    name: "SwiftyTCOD",
    products: [
        .library(
            name: "SwiftyTCOD",
            targets: ["SwiftyTCOD"]),
    ],
    dependencies: [],
    targets: [
        .systemLibrary(name: "tcod"),
        .target(name: "SwiftyTCOD", dependencies: ["tcod"]),
        .testTarget(name: "SwiftyTCODTests", dependencies: ["SwiftyTCOD"]),
    ]
)

And my module.modulemap:

module tcod {
    umbrella header "swiftytcod_tcod.h"
    link "/usr/local/lib/libtcod.dylib"
}

Any help is much appreciated!

I think absolute paths aren't supported in a module's link declaration, though that's a reasonable feature request (for Apple, not for Swift). They get translated to -l options for the linker, so link "tcod" should do it for you. (Fortunately /usr/local/lib is a default search path already.)

Thanks for the response. link tcod is what I started with and only went to the full path when that didn't work. Sadly, they produce the same results.

tom@Thomass-MBP SwiftyTCOD % swift test
ld: warning: Could not find or use auto-linked library 'tcod'
Undefined symbols for architecture x86_64:
  "_TCOD_console_check_for_keypress", referenced from:
      _$s10SwiftyTCOD7ConsoleC16checkForKeypressSo0B6_key_tayF in Console.swift.o
  "_TCOD_console_flush", referenced from:
      _$s10SwiftyTCOD7ConsoleC5flushyyF in Console.swift.o
  "_TCOD_console_init_root", referenced from:
      _$s10SwiftyTCOD7ConsoleC5width6height5title12isFullScreen8rendererACSgSi_SiSSSbAA8RendererOtcfc in Console.swift.o
  "_TCOD_console_is_window_closed", referenced from:
      _$s10SwiftyTCOD7ConsoleC14isWindowClosedSbvgZ in Console.swift.o
  "_TCOD_console_put_char", referenced from:
      _$s10SwiftyTCOD7ConsoleC7putChar1x1y4char4flagySi_SiSJSo0b7_bkgnd_G2_tatF in Console.swift.o
  "_TCOD_console_set_custom_font", referenced from:
      _$s10SwiftyTCOD7ConsoleC13setCustomFont8fontFile5flags17numCharHorizontal0jK8VerticalySS_S3itFZ in Console.swift.o
  "_TCOD_console_set_default_background", referenced from:
      _$s10SwiftyTCOD7ConsoleC20setDefaultBackgroundyySo0B9_ColorRGBVF in Console.swift.o
  "_TCOD_console_set_default_foreground", referenced from:
      _$s10SwiftyTCOD7ConsoleC20setDefaultForegroundyySo0B9_ColorRGBVF in Console.swift.o
  "_TCOD_quit", referenced from:
      _$s10SwiftyTCOD7ConsoleCfd in Console.swift.o
ld: symbol(s) not found for architecture x86_64
[5/6] Linking SwiftyTCODPackageTests

Oops. I guess /usr/local/lib is not a default search path anymore despite the man page claiming it is. The supported way to solve this is by using pkg-config (see SE-0063), but pkg-config on Mac also seems to not search /usr/local/lib/pkgconfig by default, so you may still need to add that to your PKG_CONFIG_PATH environment variable.

The absence of /usr/local/lib on the search path is SR-12909.

2 Likes