rules_swift_package_manager icon indicating copy to clipboard operation
rules_swift_package_manager copied to clipboard

SWIFT_PACKAGE copt not correctly applied when importing Objective-C library

Open luispadron opened this issue 1 year ago • 0 comments

When a Swift target depends on an Objective-C target that uses #if SWIFT_PACKAGE we are currently only adding the -DSWIFT_PACKAGE to copts but we should also be adding -Xcc -DSWIFT_PACKAGE for the clang compilation step.


The following build file reproduces an issue, it shows a minimal Package.swift BUILD files after rules_swift_package_manager generates it:

load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library", "swift_library_group", "swift_binary")
load("@rules_swift_package_manager//swiftpkg/internal:generate_modulemap.bzl", "generate_modulemap")

swift_library_group(
  name = "Foo",
  visibility = ["//visibility:public"],
  deps = ["@swiftpkg_ios_svgkit//:SVGKit.rspm", "@swiftpkg_ios_svgkit//:SVGKit.rspm_modulemap"],
)

objc_library(
  name = "Foo.rspm",
  srcs = ["Foo.m"],
  enable_modules = True,
  module_name = "Foo",
  hdrs = ["Foo.h"],
  copts = [
    "-fblocks",
    "-fobjc-arc",
    "-fPIC",
    "-fmodule-name=Foo",
    "-DSWIFT_PACKAGE=1",
  ],
)

generate_modulemap(
  name = "Foo.rspm_modulemap",
  deps = [],
  hdrs = ["Foo.h"],
  module_name = "Foo",
  noop = False,
)

swift_library_group(
  name = "FooSwift",
  visibility = ["//visibility:public"],
  deps = [":FooSwift.rspm"],
)

swift_library(
  name = "FooSwift.rspm",
  tags = ["manual"],
  deps = [
    ":Foo.rspm",
    ":Foo.rspm_modulemap"
  ],
  copts = ["-DSWIFT_PACKAGE"],
  module_name = "FooSwift",
  srcs = ["Foo.swift"],
  always_include_developer_search_paths = True,
)

# Consumer example

swift_binary(
    name = "swift_package_copt_example",
    srcs = ["main.swift"],
    deps = [":FooSwift"],
)

With the following Foo.h

#if SWIFT_PACKAGE
int foo(int x);
#else
int bar(int x); // should not be hit when building as a Swift package
#endif

When running:

bazel run swift_package_copt_example

The following error is shown:

Foo.swift:5:12: error: cannot find 'foo' in scope
    return foo(x)
           ^~~

This is because the #if SWIFT_PACKAGE case is not being hit. Fixing this requires updating the copts attribute of the swift_library to be: copts = ["-DSWIFT_PACKAGE", "-Xcc", "-DSWIFT_PACKAGE"].

Both are required because the first one is for the Swift compile and the second for the clang compile step.

luispadron avatar Sep 25 '24 19:09 luispadron