I have a Swift package that has
- two targets with C++ code (
cpp
,cppbridge
), - one target with C code (
lz4
), - and a target with Swift code (
CompositorCore
).
Swift package file (redacted):
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "CompositorCore",
platforms: [.macOS(.v10_15)],
products: [
.library(
name: "CompositorCore",
type: .dynamic,
targets: ["CompositorCore"])
],
dependencies: [
...
],
targets: [
.target(
name: "cpp",
swiftSettings: [.interoperabilityMode(.Cxx)]
),
.target(
name: "cppbridge",
dependencies: ["cpp"],
swiftSettings: [.interoperabilityMode(.Cxx)]
),
.target(
name: "lz4"
),
.target(
name: "CompositorCore",
dependencies: ["cppbridge", "lz4"],
resources: [
...
],
swiftSettings: [.interoperabilityMode(.Cxx)]
),
.testTarget(
name: "CompositorCoreTests",
...
),
],
swiftLanguageModes: [.v5],
cxxLanguageStandard: .cxx17
)
Source tree layout:
Sources
βββ CompositorCore
...
βββ cpp
β βββ include
β βββ cpp.h
β βββ tex.hpp
βββ cppbridge
β βββ TeXBridge.cpp
β βββ TexTypes.cpp
β βββ include
β βββ TeXBridge.h
β βββ TeXErrors.h
β βββ TeXTypes.h
β βββ cppbridge.h
βββ lz4
βββ include
β βββ lz4.h
βββ lz4.c
The idea with the lz4
module is to bundle an LZ4 implementation, so that the package is self-contained and works for both macOS and Windows. I was previously using Apple's Compression framework from one of the C++ files.
In want to use the C/C++ modules in Swift like so:
import CxxStdlib
import Foundation
import cppbridge
import lz4
...
When compiling the package, I'm getting
karl@10 Core % swift build -Xswiftc -suppress-warnings
Building for debugging...
<module-includes>:1:9: note: in file included from <module-includes>:1:
1 | #import "/Users/karl/Documents/sandbox/apps/compositor/Sources/Core/Sources/lz4/include/lz4.h"
| `- note: in file included from <module-includes>:1:
2 |
/Users/karl/Documents/sandbox/apps/compositor/Sources/Core/Sources/lz4/include/lz4.h:661:1: error: import of C++ module 'std_stdint_h' appears within extern "C" language linkage specification
36 | */
37 | #if defined (__cplusplus)
38 | extern "C" {
| `- note: extern "C" language linkage specification begins here
39 | #endif
40 |
:
659 |
660 | #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
661 | # include <stdint.h>
| `- error: import of C++ module 'std_stdint_h' appears within extern "C" language linkage specification
662 | typedef int8_t LZ4_i8;
663 | typedef uint8_t LZ4_byte;
/Users/karl/Documents/sandbox/apps/compositor/Sources/Core/Sources/CompositorCore/TeX/EmbeddedTeX.swift:12:8: error: could not build Objective-C module 'lz4'
10 |
11 | import cppbridge
12 | import lz4
| `- error: could not build Objective-C module 'lz4'
13 |
14 | public typealias PageCompletion = (_ pageDviBytes: Data?, _ page: Int, _ textwidth: Int, _ stop: UnsafeMutablePointer<Bool>) -> Void
<module-includes>:1:9: note: in file included from <module-includes>:1:
1 | #import "/Users/karl/Documents/sandbox/apps/compositor/Sources/Core/Sources/lz4/include/lz4.h"
| `- note: in file included from <module-includes>:1:
2 |
...
Offending lines in lz4.h
:
660 | #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
661 | # include <stdint.h>
| `- error: import of C++ module 'std_stdint_h' appears within extern "C" language linkage specification
Commenting out the extern "C"
//#if defined (__cplusplus)
//extern "C" {
//#endif
makes the compiler happy, but then the linker complains (because I am messing with name mangling?):
karl@10 Core % swift build -Xswiftc -suppress-warnings
Building for debugging...
error: link command failed with exit code 1 (use -v to see invocation)
Undefined symbols for architecture arm64:
"LZ4_compressBound(int)", referenced from:
CompositorCore.EmbeddedTeX.(lookupPageDump in _C6A6B56F6A91CC1BF8BAAC0207457FAD)(Swift.Int) -> Foundation.Data? in EmbeddedTeX.swift.o
NOTE: found '_LZ4_compressBound' in lz4.c.o, declaration possibly missing 'extern "C"'
"LZ4_decompress_safe(char const*, char*, int, int)", referenced from:
closure #1 (Swift.UnsafeRawBufferPointer) -> Foundation.Data? in CompositorCore.EmbeddedTeX.(lookupPageDump in _C6A6B56F6A91CC1BF8BAAC0207457FAD)(Swift.Int) -> Foundation.Data? in EmbeddedTeX.swift.o
NOTE: found '_LZ4_decompress_safe' in lz4.c.o, declaration possibly missing 'extern "C"'
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[244/245] Linking libCompositorCore.dylib
How can I get this working?
Thanks