swiftlang / swift-package-manager

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

Xcode reports a "module not found" error even though the module is one of the target dependencies #5951

Open crazytonyli opened 1 year ago

crazytonyli commented 1 year ago

Description

Mix.zip is an example Swift package.

There are three targets in this package:

Expected behavior

Mix scheme can be built successfully.

Actual behavior

Mix scheme can't be built.

Screen Shot 2022-12-07 at 11 25 48 AM

Steps to reproduce

  1. Open this project in Xcode.
  2. MixObjC scheme can be built successfully.
  3. Xcode reports an error when building Mix scheme: "module not found" error in MixObjc/ObjC.h.
Screen Shot 2022-12-07 at 11 25 48 AM

Swift Package Manager version/commit hash

Release 5.7

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

swift-driver version: 1.62.15 Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51) Target: arm64-apple-macosx12.0 Darwin A8C-MBP.local 21.6.0 Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000 arm64

neonichu commented 1 year ago

Looks like in Xcode, there's no -fmodule-map-path being passed to MixCore.modulemap when building the "Mix" target, but the package appears to build with swift build. cc @abertelrud

crazytonyli commented 1 year ago

BTW, I have reported this issue on Feedback Assistant, ID: FB12110253.

Kjuly commented 1 year ago

Just happened to be in the same situation, and found out why.

As "Importing Swift into Objective-C" said:

When declarations in an Objective-C header file refer to a Swift class or protocol that comes from the same target, importing the generated header creates a cyclical reference. To avoid this, use a forward declaration of the Swift class or protocol to reference it in an Objective-C interface.

Therefore, it's better to avoid importing MixObjC in the .h file:

#import <Foundation/Foundation.h>

@import MixCore; // HERE: Replace it with `@class MixCoreClass;`

@interface MixObjC: NSObject

@property (nonatomic, strong) MixCoreClass *core;
@property (nonatomic, assign) int value;

@end

This will solve your "module not found" error. However, you will get another error when you import the MixObjC into a Swift file to access the property core:

Value of type 'MixObjC' has no member 'core'

This issue occurs in a situation of such package dependencies:

Mix (Swift) -- MixObjC (Objective-C) ---- MixCore (Swift)

Which was mentioned in this thread: "[SR-1549] Swift member of Objective-C class not exposed to Swift".