swiftlang/swift-package-manager

Support Multiple Public Header Paths

Opened this issue · 1 comments

Description

Some C++ libraries require multiple directories within the library to be set as include search paths.

However, in SwiftPM’s C++ targets, only one publicHeadersPath can be specified.
As a result, making existing C++ libraries buildable with SwiftPM often requires modifying the include directives in the codebase.

It is worth mentioning that include search paths can be added using the headerSearchPath option in cxxSettings.
This allows the C++ target itself to be built successfully.

However, this approach causes issues when building targets that depend on that target.
It would require every dependent target (including indirect dependencies) to configure those search paths as well.
Moreover, if the dependent target is in a different package, there is no safe way to reference those file paths, making this workaround impractical.

Rewriting include directives in the codebase introduces review overhead for the maintainers of the C++ library, making it a significant hurdle.

If SwiftPM allowed multiple directories to be set as search paths through the target configuration, it would be very helpful in such cases.

In fact, I encountered this issue in the following situation, and I would greatly appreciate the addition of such a feature:
troldal/OpenXLSX#298

Expected behavior

I propose introducing a new API:

publicHeadersPaths: [String]

Actual behavior

Currently, only one public header path can be specified.

Steps to reproduce

No response

Swift Package Manager version/commit hash

Swift Package Manager - Swift 6.0.3-dev

Swift & OS version (output of swift --version && uname -a)

swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.4 clang-1600.0.30)
Target: arm64-apple-macosx15.0

This is definitely an area I want to study more and look for solutions. To leverage the C/C++ ecosystem better, we'll need to be more flexible about things like this.

It's not just being able to specify it in the package manifest, we'll also need to make sure we generate as usable module map in this configuration.