swiftlang / swift-package-manager

The Package Manager for the Swift Programming Language
Apache License 2.0
9.75k stars 1.34k forks source link

Add Swift setting to add include paths for a target that are inherited by targets depending on this one #8077

Open DougGregor opened 2 weeks ago

DougGregor commented 2 weeks ago

Description

In the swift-java project, we have a fairly involved operation to figure out the include path for the JNI headers. The only mechanism we have to making this include path available to the Swift source files in that target is via unsafeFlags, e.g.,

    .target(
      name: "JavaRuntime",
      swiftSettings: [
        .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
      ]
    ),

Now, every target that depends JavaRuntime also has to include the same unsafe flags, or importing that module will fail. For example:

    .target(
      name: "JavaCelsiusConverterGUI",
      dependencies: [ "JavaRuntime" ],
      swiftSettings: [
        // I would rather not need this...
        .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
      ],

Could we have some direct way of specifying C include paths for a SwiftPM target that will affect the C and Swift compiles for that target and any target depending on it? The headerSearchPath C setting is almost the right idea, but it requires a relative path, and configuration-derived paths like these need to be absolute (because they are pointing at headers installed by someone else).

Expected behavior

Expected behavior described above.

Actual behavior

Actual behavior is "we can't express this".

Steps to reproduce

No response

Swift Package Manager version/commit hash

No response

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

No response

rauhul commented 2 weeks ago

~+1 this could be similar to the includes field of cc_library in bazel: https://bazel.build/reference/be/c-cpp#cc_library.includes~ nvm I think the existing headerSearchPath matches bazel include behavior

dschaefer2 commented 1 week ago

I am also seeing this when building SwiftPM on Windows. The C defines aren't getting copied over to the Swift modules resulting in symbols from CYaml being exported from consuming modules.

rauhul commented 6 days ago

I haven't concretely seen an issue with this, but im worried a bit about Xcc settings with many C modules because theres no way to indicate to the swift compiler that a particular Xcc should only be used when parsing Foo module's headers.

With the current model all Xcc flags are used for every -I which might introduce bug & inconsistent module interfaces.

dschaefer2 commented 5 days ago

Agreed. Ideally we would do like CMake does and mark settings as public or private. Then you'd only inherit the public ones.