94

I'm running Xcode 11 Beta 4. I'm using CocoaPods, and wanted to use one of my dependencies with Swift Package Manager as a static library instead of as a framework. On a fresh project created with Xcode 11, the dependency can be imported successfully, but on my existing CocoaPods workspace, it does not.

I think it's likely related, but I'm also getting this link warning in Xcode:

directory not found for option '-L/Users/username/Library/Developer/Xcode/DerivedData/App-axanznliwntexmdfdskitsxlfypz/Build/Products/Release-iphoneos

I went to see if the directory exists after the warning is emitted, and it does. I could not find any meaningful difference between the newly-created project and my old one, other than the existence of CocoaPods.

Would appreciate any pointers.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
Adar Hefer
  • 1,514
  • 1
  • 12
  • 18

13 Answers13

192

After adding a library (FASwiftUI in my case) through Swift Package Manager I had to add it to

Project Settings -> My Target -> General -> Frameworks, Libraries, and Embedded Content

to be visible in the import statement.

I did not add any scripts for it to work.

enter image description here

Slipp D. Thompson
  • 33,165
  • 3
  • 43
  • 43
Jerzy Kiler
  • 2,795
  • 4
  • 18
  • 12
  • 12
    Thank you. Really helped me to save some time – inexcitus Oct 02 '20 at 15:11
  • 1
    I solved it by adding "FASwiftUI" to the dependencies array in my Swift Package's package file. See my answer below for more info. – Lucas C. Feijo Jul 15 '21 at 17:26
  • I have a project I started a few years ago with an older Xcode and I have only a section "Embedded content" which is empty and doesn't allow to add any existing packages. It allows to clone though. but when I clone it nothing new happens, the section remains empty and I cannot import the module. anything I miss? what could be the problem? – ramzesenok Dec 21 '21 at 21:26
  • 1
    Always funny when something really slows you down, you find the solution on SO but can't upvote it anymore because you already did. I'd love to give you a second upvote right now. – RyuX51 Feb 06 '23 at 12:10
37

Solution

let package = Package(
    name: "PackageName",
    dependencies: [
       // YOU MUST ADD THE DEPENDENCY BOTH HERE [1] AND BELOW [2]
      .package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
    ],
    targets: [
        .target(
            name: "PackageName",
            /*[2]*/ dependencies: ["FASwiftUI"], // [2] <<<--------- Added here as well
    ]
)

Explanation

I'm developing a Swift package that must provide FontAwesome Icons to whoever imports it.

I was getting "No such module 'FASwiftUI'" in my SwiftUI preview canvas.

I solved it by adding "FASwiftUI" to BOTH the dependencies array of the package AS WELL AS to the dependencies array in the target itself.

Full Package.swift File

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "PackageName",
    platforms: [
        .macOS(.v11),
        .iOS(.v14)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "PackageName",
            targets: ["PackageName"])
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/nalexn/ViewInspector", from: "0.8.1"),
        .package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "PackageName",
            dependencies: ["FASwiftUI"], // <<<--------- Added this here
            resources: [
                .process("Assets")
            ]
        ),
        .testTarget(
            name: "PackageNameTests",
            dependencies: ["PackageName", "ViewInspector"])
    ]
)
technoplato
  • 3,293
  • 21
  • 33
Lucas C. Feijo
  • 1,002
  • 3
  • 13
  • 29
  • Cheers, that was my issue when googling for this! – hesselbom Jan 13 '22 at 09:22
  • I can't add anything to the Package.swift file -- it seems to be read-only. – benwiggy Dec 25 '22 at 11:42
  • This means you're trying to edit the repo Xcode has checked out for you as a dependency, it's supposed to be read only. If you don't have access to the repo of the lib you're trying to change, you can fork it. – Lucas C. Feijo Dec 28 '22 at 15:49
  • Took far too much Googling to find this. I'm sure it's documented somewhere, but I don't recall seeing it anywhere else. Thank you for posting. – Josh Hudnall Jan 13 '23 at 21:50
  • 2
    You may have to add it as: `.product(name: "FASwiftUI", package: "-whatever-the-package-is-called")` In the .target dependencies and not just as "FASwiftUI" – P. Ent Feb 11 '23 at 20:53
33

Based on @AlexandreMorgado answer it seems like it is better to run this script in Build phases before Compile Sources. Then it works when archiving.

enter image description here

if [ -d "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" ] && [ "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" != "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/" ] 
then
  cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"
fi
sliwinski.lukas
  • 1,412
  • 1
  • 18
  • 28
32

It turned out that Swift Package Manager implicitly depends on the project's Configuration names. I had them at live/qa instead of Release/Debug, and changing them back resolved the issue. Very odd, but I hope it saves you some trouble dear reader.

Adar Hefer
  • 1,514
  • 1
  • 12
  • 18
12

After a whole week fighting this issue, I developed a workaround using schemes and pre-actions.

I have a configuration called "Beta", so Xcode can't compile SPM dependencies. I realised Xcode compile SPM dependencies as Swift modules and add the files in Build/Products/Release-iphoneos folder in DeriverData.

So I created a scheme in Xcode and added this run script on build pre-actions:

enter image description here

cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"

This script run before the build process, copying files and modules generated by Xcode on default Release-iphoneos folder to configuration folder, Beta-iphoneos, in my case.

After coping the content from Release-iphoneos to your $configuration$-iphoneos folder Xcode should correctly compile, build and run your project.

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
alemorgado
  • 191
  • 2
  • 9
  • I create a new environment such as staging and have above issue. Have you any solution for this? bro – logan.Nguyen Oct 09 '19 at 04:20
  • @logan.Nguyen, have you tried build again? Sometimes this workaround fails on first time, because the compilation process can execute before the files be copied, but when you run again it works. – alemorgado Oct 09 '19 at 11:07
  • This worked for me. Thanks! However when creating an archive it didn't. Also when adding the pre-action to the Archive phase. Do you maybe have an idea of how to solve this as well? – Menno Oct 09 '19 at 12:14
  • @Menno, I didn't test archiving with this method. But sliwinski.lukas just posted an alternative to fix this. – alemorgado Oct 09 '19 at 16:03
  • 1
    Keep in mind that this is confirmed to be an Xcode bug, as can be seen in a comment to my original answer. So I'd keep that in mind and keep an eye out for the fix in order to remove any workarounds. – Adar Hefer Oct 10 '19 at 13:12
5

I just ran into a similar problem and discovered that my schemes referenced old configurations, configurations that no longer existed. Once I updated them to the correct configurations the build succeeded.

(I'm leaving this comment more than a year after the original post. It's possible that what I ran into is completely different from what was originally reported. Still, it took me quite a while to track the problem down, so I wanted to leave a note that might save others time.)

2

Clearing the derived data solved the issue in my case. I have Microsoft Azure Devops CI Pipeline, to clear the derived data I have to edit the Xcode build task and in the "Actions" field add this command: clean.

mokagio
  • 16,391
  • 3
  • 51
  • 58
JAHelia
  • 6,934
  • 17
  • 74
  • 134
2

What worked for me: I removed my import WebMIDIKit line and added it again.

radu122
  • 2,865
  • 24
  • 24
2

Based on @sliwinski.lukas's answer, in my case the ${CONFIGURATION} was outputting "Release", so it was just copying the Release folder itself which was no good. I simply hardcoded my configuration name, and flipped Release and MyConfiguration, and it worked. I put the following code right before "Compile Sources" in the "Build Phases" tab:

cp -f -R "${SYMROOT}/MyConfiguration${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" || true

Also importantly, I had to add this in the project that used the SPM and not in the main app.

Genki
  • 3,055
  • 2
  • 29
  • 42
1

I just ran into a similar problem when running xcodebuild from the command line. I was passing CONFIGURATION_BUILD_DIR=build but found that it needs to be an absolute path: CONFIGURATION_BUILD_DIR=$(pwd)/build solved the problem.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
0

Might I shed a bit more light on your plight...

I'm working on a fairly large iOS app (6680 files) whose result is composed of many frameworks and a mixed bag of podfiles, swift packages, legacy ObjC code (that still outnumbers newer Swift stuff).

Whenever we deal with swift packages, we need to wrap them in frameworks because it simplifies podfile & dependency resolutions when we have our remote (Jenkins) build system eat everything up to spew binaries for internal QA & ultimately, Enterprise & AppStore publishing.

Earlier today, I was dealing with one such swift package wrapped in a framework and all the issues listed above hit me square in the face.

After stashing, pushing usable code and then reapplying my stashed framework wrapper to the swift package, I used a different route than opening our project's workspace where a bunch of projects and targets are collected.

Opening the lone framework wrapper seems to have kicked XCode (13.3.1) into submission and at that point, the target settings "Frameworks, Libraries and Embeddable" section was actually able to display the swift package's "Foo" binary. Added it, and then everything was playing nice.

So, if you're still having problems, try simplifying the problem by opening smaller morsles if you can. Or start making these wrapper frameworks (if it's at all possible) so that you can actually manage smaller bites before integrating them on XC's platter.

-1

For me, I go to Xcode -> File (The one on mac top bar) -> Packages -> Update to Latest Package Versions. This solved my problem.

Mike
  • 817
  • 1
  • 8
  • 15
-2

In order to keep incremental builds working I had to specify the output files of "Fix SPM" build phase like so: enter image description here

Tylerc230
  • 2,883
  • 1
  • 27
  • 31