cgrindel / rules_swift_package_manager

Collection of utilities and Bazel rules to aid in the development and maintenance of Swift repositories using Bazel.
Apache License 2.0
74 stars 29 forks source link

Allow a client to specify how a `binaryTarget` is linked #559

Closed cgrindel closed 1 year ago

cgrindel commented 1 year ago

When support for binaryTarget targets was added to this repository, they were modeled as apple_dynamic_xcframework_import Bazel targets. However, with #498, the implementation was changed to model binaryTarget as apple_static_xcframework_import. Ideally, clients could select how these targets should be exposed.

The following is the code that was used to expose the binary targets as a dynamic xcframework.

# Code from swikftpkg_build_files.bzl

def _apple_dynamic_xcframework_import_build_file(target):
    load_stmts = [apple_dynamic_xcframework_import_load_stmt]
    glob = scg.new_fn_call(
        "glob",
        ["{tpath}/*.xcframework/**".format(tpath = target.path)],
    )
    decls = [
        build_decls.new(
            kind = apple_kinds.dynamic_xcframework_import,
            name = pkginfo_targets.bazel_label_name(target),
            attrs = {
                "visibility": ["//visibility:public"],
                "xcframework_imports": glob,
            },
        ),
    ]
    return build_files.new(
        load_stmts = load_stmts,
        decls = decls,
    )

Related to #498. Related Slack thread.

jpsim commented 1 year ago

Starting with #546 I'm getting dlopen failures when running my unit tests if some SPM binaryTarget is in the dependency graph. For example:

.package(
    url: "https://github.com/airbnb/lottie-spm.git",
    from: "4.1.2"
),

I get the following errors when running tests:

2023-09-08 09:38:11.162 xctest[44944:1241469] The bundle "MyModuleTests" couldn't be loaded. Try reinstalling the bundle.
2023-09-08 09:38:11.163 xctest[44944:1241469] (dlopen(/var/folders/y5/g_w8jzsn4637nw1fkc2whgfw0000gn/T/test_runner_work_dir.W6aOQ9/MyModuleTests/MyModuleTests.xctest/MyModuleTests, 0x0109): Library not loaded: @rpath/Lottie.framework/Lottie
  Referenced from: <5F0052B1-6F77-3F11-AF5B-909E096716DD> /private/var/folders/y5/g_w8jzsn4637nw1fkc2whgfw0000gn/T/test_runner_work_dir.W6aOQ9/MyModuleTests/MyModuleTests.xctest/MyModuleTests
  Reason: tried: '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/Lottie.framework/Lottie' (no such file), '/usr/lib/swift/Lottie.framework/Lottie' (no such file, not in dyld cache), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Agents/Frameworks/Lottie.framework/Lottie' (no such file), '/private/var/folders/y5/g_w8jzsn4637nw1fkc2whgfw0000gn/T/test_runner_work_dir.W6aOQ9/MyModuleTests/MyModuleTests.xctest/Frameworks/Lottie.framework/Lottie' (no such file), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/Lottie.framework/Lottie' (no such file), '/usr/lib/swift/Lottie.framework/Lottie' (no such file, not in dyld cache), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Agents/Frameworks/Lottie.framework/Lottie' (no such file), '/private/var/folders/y5/g_w8jzsn4637nw1fkc2whgfw0000gn/T/test_runner_work_dir.W6aOQ9/MyModuleTests/MyModuleTests.xctest/Frameworks/Lottie.framework/Lottie' (no such file), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/Lottie.framework/Lottie' (no such file), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/Lottie.framework/Lottie' (no such file), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib/Lottie.framework/Lottie' (no such file), '/Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Lottie.framework/Lottie' (no such file))

Tests run fine with 0.8.0 but not with 0.9.0, and although I haven't fully confirmed it's #546, it's the most likely suspect.

I'll try to come up with a minimal repro case.

cgrindel commented 1 year ago

@jpsim Did you have any validation issues when the framework was loaded dynamically (i.e., as of 0.8.0)?

jpsim commented 1 year ago

Not that I know of. Tests were passing, but maybe there were some validation logs that were hidden somehow? None that I saw.

cgrindel commented 1 year ago

I am going to try and implement a check as @AttilaTheFun described here.

cgrindel commented 1 year ago

Copied @AttilaTheFun comment from Slack for better visibility.

alternately you could try to sniff the format with the posix file command

cmd.Exec("/usr/bin/file", pathToFile)

static frameworks will look like:

$ file /Users/logan/Downloads/BrazeKit
/Users/logan/Downloads/BrazeKit: current ar archive random library

dynamic frameworks look like:

$ file /Users/logan/Downloads/SpotifyiOS 
/Users/logan/Downloads/SpotifyiOS: Mach-O 64-bit dynamically linked shared library arm64