'generate-xcodeproj' is no longer needed and will be deprecated soon

Hello :wave:, When I use swift package generate-xcodeproj I get a warning:

warning: Xcode can open and build Swift Packages directly. 'generate-xcodeproj' is no longer needed and will be deprecated soon.

However, it is still needed. Without running the above command, Xcode is not smart enough to open it as an Xcode project, it looks like a normal package instead.

I don't understand this comment: Swift package generate-xcodeproj - #2 by lukasa

With Xcode 11 you can simply open a Swift package directly, without needing to generate an intermediary Xcode project. Navigate to your directory and type xed . .

Sure you can open with xed but that will get you the screenshot above, with no Xcode project tab e.g. (build settings, build phases, targets, etc.)

I'm afraid this functionality will be removed in the future, because I don't know what the error means. generate-xcodeproj seems useful to me.

Once I run swift package generate-xcodeproj, it's much better:

Could someone confirm my hunch? I have to pick the first screenshot (no Xcode project tab or .xcodeproj file at all) over the second?

Yup, I found The Xcode 11 and Swift Package Combo Platter quite useful :)

1 Like

Correct. generate-xcodeproj is deprecated. Since deprecation, it has ceased to be updated to support new package features. It will eventually be removed entirely.

The current way to work with packages is to open the Package.swift file in Xcode.

None of these were ever actually supported by the package. If you tinkered with them, they only affected the Xcode targets, and not the underlying package. Thus, such settings had no effect on clients, even if you checked the project into source control alongside the package.

You can create custom schemes to use during development (which are stored in .swiftpm/xcode if you want to check them in). They can be used to control development toggles such as test coverage, location spoofing, or the command line arguments to feed to an executable when you click “run”.

Xcode‐style build settings and phases are prohibited precisely because packages do not support them. If you need them for a top‐level application or tool, then you should create an Xcode project for it instead. If it naturally belongs right alongside a library that is vended as a package, then you can still check it into the same repository. Drag the repository root directory into the Xcode project to reference the package with a relative path. From there you can link against any of the products from the package.

3 Likes

Thanks Jeremy, that's very helpful :)

1 Like

For xcode only, this might be great.However, if the framework needs to be compiled in CI, this directive is required (my understanding is.)

Like this

# the first generate xcodeproj
swift package generate-xcodeproj

# then build framework
PACKAGE_NAME=mypkg
xcodebuild -quiet \
  -project ${PACKAGE_NAME}.xcodeproj \
  -scheme ${PACKAGE_NAME}-Package \
  -configuration Release \
  -sdk iphoneos \
  -derivedDataPath ./target/xcodebuild \
  ONLY_ACTIVE_ARCH=NO \
  CONFIGURATION_BUILD_DIR=./target \
  clean build

If there is no generate-xcodeproj, how should the xcodebuild command (-project argument) be used?

It depends on your purpose.

  • If you just want to make sure the build succeeds (because clients depend on it as a package), then just leave -project out. The rest of your options should be fine as just you have them. (Although packages with only one product may not have a an additional “build everything” mypkg-Package scheme. In that case, use xcodebuild -list to figure out what scheme name to specify instead.)

  • If your aim is to produce a compiled binary that you then vend manually, you can do one of two things:

    1. If its simplicity will suffice, you can specify an explicitly static or dynamic library product in the manifest and vend the resulting .a, .dylib, etc.

    2. If you need anything more complicated, then you will need an Xcode project to configure the bundling details. You do not need the entire package duplicated the way generate-xcodeproj once did. You can simply depend on the package locally the same way you would with an application. (See the end of my previous comment if you need instructions.)

I am running into the issue today that xcode building for release insists on building for all architectures, even if I create another xcodeproj and depend on the local package (as in 2.). My package does not support Intel, and never will, and I get build errors when Xcode tries to build for it. swift build -c release works fine, but building for Release in Xcode tries to build a universal binary, which I don't want, but can't seem to disable without accessing Build Settings.

I can kind of work around this by running xcodebuild ONLY_ACTIVE_ARCH=YES -destination 'generic/platform=macOS,arch=arm64,name=Any Mac'. That builds from the command line, but then I can't easily use Profiling in Xcode, which is the reason I wanted to use Xcode in the first place.

Any ideas of how to enable a smooth workflow for this? Basically, Xcode makes too many assumptions about my Package when I open it, but I don't have control over those assumptions any more either.

Hey @Geordie_J, have you found any solution for this? I have a Swift package that only compiles on x86 and I can build it normally using Xcode, but when I want to profile it (which is my only real Xcode use-case as well) then Xcode tries to build it for both architectures and fails.

I don't know how to get Xcode to profile my Swift package w/o building it for arm.

1 Like

No, I don’t think so, sorry. Just waiting for improvements in Xcode. I haven’t tried it with Xcode 15 beta yet - maybe you’ll have luck with that