Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-13787] Module compiled with Swift 5.1.3 cannot be imported by the Swift 5.3 compiler #56184

Open
swift-ci opened this issue Oct 28, 2020 · 12 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-13787
Radar rdar://problem/70770534
Original Reporter pratik7594 (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: deab1e926a55394ad859e46505d3835f

Issue Description:

We are creating a custom framework using CI Jenkins build which is having Xcode 12 and try to import in another project which is using Xcode 11.6 and that shows the above error.

We have tried "build_distribution_flag" - Yes in the custom framework but we having the same error. We are installing our custom framework by using pod into projects.

@typesanitizer
Copy link

Just to confirm I'm understanding the issue properly:

> We are creating a custom framework using CI Jenkins build which is having Xcode 12 and try to import in another project which is using Xcode 11.6 and that shows the above error.

Here, the module compiled with Xcode 12 is importing the module compiled with Xcode 11.6, correct?

Some potential things to check:

1. Are you setting the right build setting? It should be called "BUILD_LIBRARY_FOR_DISTRIBUTION". https://swift.org/blog/library-evolution/
2. Is there a .xcframework or .swiftinterface for being generated in the build artifacts? You can check this by looking at the build artifacts in ~/Library/Developer/Xcode/DerivedData.

Could you share more details about the error? Is there some mention of a swiftinterface or a swiftmodule?

This seems likely due to a misconfiguration where the setting is not turned on properly. This would lead to a binary swiftmodule being generated (which is not compatible across compiler versions) and no module

It would help to have a couple of sample projects which reproduce the issue.

@swift-ci create

@swift-ci
Copy link
Collaborator Author

Comment by Pratik Kankriya (JIRA)

Hi theindigamer (JIRA User),

We are setting the "BUILD_LIBRARY_FOR_DISTRIBUTION" to NO.

If we set "BUILD_LIBRARY_FOR_DISTRIBUTION" to YES. We get the following error arm64-apple-ios.swiftinterface::’SDKTest' is not a member type of

We are creating a framework and using the following script in Edit Scheme for archiving the framework

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-Universal

  1. Make sure the output directory exists

mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

  1. Next, work out if we're in SIMULATOR or REAL DEVICE

xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

  1. Step 2. Copy the framework structure (from iphoneos build) to the universal folder

cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

  1. Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory

BUILD_PRODUCTS="${SYMROOT}/../../../../Products"

cp -R "${BUILD_PRODUCTS}/Debug-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"

  1. Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory

lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_PRODUCTS}/Debug-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

  1. Step 5. Convenience step to copy the framework to the project's directory

cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

  1. Step 6. Convenience step to open the project's directory in Finder

open "${PROJECT_DIR}"

fi

@typesanitizer
Copy link

We are setting the "BUILD_LIBRARY_FOR_DISTRIBUTION" to NO. If we set "BUILD_LIBRARY_FOR_DISTRIBUTION" to YES. We get the following error arm64-apple-ios.swiftinterface::’SDKTest' is not a member type of

If you set BUILD_LIBRARY_FOR_DISTRIBUTION to NO (i.e. library evolution is turned off), then the rest of it isn't going to work. You need to either set it to YES and fix the compilation errors, or you need to use the same Xcode to build both frameworks instead of mixing Xcodes.

From the blog post: https://swift.org/blog/library-evolution/

Module stability currently requires library evolution support; typically you will enable both features when building a binary framework for distribution

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 2, 2020

Comment by Pratik Kankriya (JIRA)

Hi theindigamer (JIRA User),

I had set "BUILD_LIBRARY_FOR_DISTRIBUTION" to YES. Now I am getting the following error

"Module compiled with Swift 5.3 cannot be imported by the Swift 5.2.4 compiler: /Users/pratik/Desktop/IIIIII/Sample_ios/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftmodule",

In our custom framework, we are using Lottie pods for animation. My framework is created using Xcode 12.1 and I am using the framework in an app having Xcode 11.6. I want to know the above error is due to Lottie pods. Please let me know the steps to resolve this.

But I am using the same Xcode version for both the framework as well as app then we are not getting the above error.

@typesanitizer
Copy link

Do you see a matching swiftinterface file next to the swiftmodule shown in the error?

/Users/pratik/Desktop/IIIIII/Sample_ios/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftinterface

If you enabled library evolution for Lottie correctly, then there should be a matching swiftinterface. Otherwise, the setting has not been set properly. You can double-check this by looking at the compiler invocation for building Lottie in the build log. If the build setting has been enabled, then you should see a -enable-library-evolution flag in the invocation.

That said, this might not work: swiftinterfaces and swiftmodules are not guaranteed to be backwards compatible, i.e., a swiftinterface emitted by a newer compiler may not be readable by an older compiler. (Sorry, I misunderstood your post earlier.)

So the workflow of having an old compiler consume a library compiled with a newer compiler is not supported and may break in the future. It would be best if you were able to compile both with the same Xcode version, or have the app be compiled with a newer version of Xcode than the one used to compile the framework.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 2, 2020

Comment by Pratik Kankriya (JIRA)

Hi theindigamer (JIRA User),

I was facing this issue for Xcode 11 version but now the framework generated on Xcode 12 works on the application that is using Xcode 12.1.I think this may be Xcode 11 bug.

I had set the "BUILD_LIBRARY_FOR_DISTRIBUTION" to NO. But still, it is working on Xcode 12 & above versions but not on Xcode 11.

It will be really helpful if you get more info on this issue.

@typesanitizer
Copy link

It's possible that the compiler version in Xcode 12 and Xcode 12.1 is exactly the same, so the compiler in Xcode 12.1 is able to consume the swiftmodule generated by the compiler in Xcode 12. So I don't think that itself points to a bug in Xcode 11.

> It will be really helpful if you get more info on this issue.

Could you clarify what additional information you'd like? From what I can tell your issue is resolved with the Xcode update 11.6 -> 12. 🙂

@beccadax
Copy link
Contributor

beccadax commented Nov 2, 2020

pratik7594 (JIRA User): Above, you cite a diagnostic that appears to be cut off:

If we set "BUILD_LIBRARY_FOR_DISTRIBUTION" to YES. We get the following error arm64-apple-ios.swiftinterface::’SDKTest' is not a member type of

Could you provide a full version of this diagnostic? Also, can you tell me what kind of declaration "SDKTest" is, which module it is in, and whether there is a type by the same name as that module?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 3, 2020

Comment by Pratik Kankriya (JIRA)

Hi theindigamer (JIRA User),

-> Could you clarify what additional information you'd like? From what I can tell your issue is resolved with the Xcode update 11.6 -> 12.

I had not done any changes in my code for the module issue but after Xcode 12 it is working.

I had doubts here in Lottie pod which we are using in our framework. I cannot do any changes in the Lottie because I am using the framework directly. I want to know the issue is due to Lottie or any setting missing in my custom framework. I had already shared the script used for creating the framework.

Is there any setting is missing in my framework then please let me know. Exactly I am also not sure about how the issue resolved in Xcode 12

I am confused about why the XCode versions matter in creating the framework.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 3, 2020

Comment by Pratik Kankriya (JIRA)

Hi brentdax (JIRA User),

Could you provide a full version of this diagnostic? Also, can you tell me what kind of declaration "SDKTest" is, which module it is in and whether there is a type by the same name as that module?

DiagnosticsSDK is our framework name.SDKTest is the enum which we using on the framework and it is public enum.

I am confused about why the XCode versions matter in creating the framework.

@xymus
Copy link
Contributor

xymus commented Nov 5, 2020

There is a known bug in the swiftinterface files generation when a type has the same name as a module. If this is the case here there is a workaround that can be applied in the framework that produces the swiftinterface file. Please attach the full build log with the failure, it should give us more details on the underlying problem.

The Xcode version matters because it's associated to the Swift compiler version. When “BUILD_LIBRARY_FOR_DISTRIBUTION” is set to NO, the compiler generates only the swiftmodule files which can only be read by similar compiler versions. It is likely that a swiftmodule generated by Xcode 12 can be read by Xcode 12 and 12.1 but not 11 nor a future Xcode. When “BUILD_LIBRARY_FOR_DISTRIBUTION” is set to YES, the compiler generates the swiftinterface files in addition to the swiftmodule files. Similar compilers will still use the swiftmodules and skip the swiftinterfaces, only different compiler versions will read the swiftinterface files and report errors in it. This explains why using your framework from Xcode 12 works fine because the swiftmodule file is sound, while it fails in Xcode 11 as the swiftinterface is likely generated with issues in it.

@swift-ci
Copy link
Collaborator Author

Comment by Pratik Kankriya (JIRA)

Hi theindigamer (JIRA User) @xymus brentdax (JIRA User)

Now I had set the “BUILD_LIBRARY_FOR_DISTRIBUTION” to Yes. We are creating the framework file using Xcode 12.2. But when we are importing the framework in Xcode 12.2 and above we are getting the following error.

the compiler that produced it, 'Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1)', may have used features that aren't supported by this compiler, 'Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8)

I think it may be some setting issue while creating the framework. Please let me know the solution.

We are using the following script for creating the framework

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-Universal

  1. Make sure the output directory exists

mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

  1. Next, work out if we're in SIMULATOR or REAL DEVICE

xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

  1. Step 2. Copy the framework structure (from iphoneos build) to the universal folder

cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

  1. Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory

BUILD_PRODUCTS="${SYMROOT}/../../../../Products"

cp -R "${BUILD_PRODUCTS}/Debug-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"

  1. Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory

lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_PRODUCTS}/Debug-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

  1. Step 5. Convenience step to copy the framework to the project's directory

cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

  1. Step 6. Convenience step to open the project's directory in Finder

open "${PROJECT_DIR}"

fi

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

4 participants