Convert XCodeProj to Package.swift - swift

I have recently inherited a swift project and would prefer to do my development on a Linux VM, rather then the under powered Mac I have. I have found lots of tutorials on how to got from a Package.swift to a xcodeproj. But I haven't found anything to go the other direction (xcodeproj to Package.swift). It seems that I need the Package.swift to be able to use the swift cli (swift build).
Is there a way to build without the Package.swift file?
Is there a way to do this that I haven't found?
Is there a technical reason that we can't go from a xcodeproj to a Package.swift?

1./2.
A Package.swift file is internally translated to a set of swiftc commands.
If you run swift build -v (verbose) on a fully working Swift package, you can see the commands that are being run. Using these commands, you may be able to figure out how to compile any collection of Swift sources without a Package.swift.
For a framework, one command could look something like this:
swiftc -module-name TestPackage -emit-dependencies -emit-module -c Path/to/Sources/*.swift -Onone -g -enable-testing -j8 -DSWIFT_PACKAGE -DDEBUG -Xfrontend -color-diagnostics
When compiling an executable, there may be additional commands to link the standard library, etc.
3.
The feature set of Xcode far exceeds the capabilities of Swift packages (e.g. .app bundles, Storyboards, Metal source files, ObjC, C, C++, etc.)
However, you can convert your command line project to a Swift package by running swift package init --type library|executable to create a Package.swift file. You can then specify a path parameter for the target in the Package.swift file:
.target(name: "YourTarget", path: "Path/To/Your/Swift/Files")

Related

Is it possible to produce an XCFramework from a Swift Package with dependencies?

I want to be able to take an internal SPM package, which depends on several other internal (and one external) SPM packages, and compile it into an XCFramework, using a series of xcodebuild like you would for a framework project. For example, I have PackageB, which references PackageA, and I'm trying to build PackageB.xcframework. The first step would be:
xcodebuild -scheme PackageB -destination "generic/platform=iOS" -configuration Release ARCHS="arm64" BUILD_DIR="./Build
The tool's output indicates that the dependency packages are being resolved, but they are then not recognized by the compiler (i.e. code in PackageB which references PackageA will not compile because PackageA is unknown at that point).
Thanks for any pointers.
You can create xcframework from swift package by using swift-create-xcframework command line tool, there is also GitHub action available for this.
If you don't want to use this tool, you can generate Xcode project by using swift package generate-xcodeproj command:
OVERVIEW: Generates an Xcode project. This command will be deprecated soon.
USAGE: swift package generate-xcodeproj
OPTIONS:
--xcconfig-overrides
Path to xcconfig file
--output Path where the Xcode project should be generated
--legacy-scheme-generator
Use the legacy scheme generator
--watch Watch for changes to the Package manifest to
regenerate the Xcode project
--skip-extra-files Do not add file references for extra files to the
generated Xcode project
--version Show the version.
-h, -help, --help Show help information.
and then create xcframework with the generated Xcode project.

How to use CoreML Model in a Swift Package Manager macOS Command Line App?

I'm trying to create a command line app that runs on macOS and uses CoreML. I am using Swift Package Manager. Here are some steps to reproduce the problem:
Run
swift package init --type executable
Move a CoreML model into the Sources folder, for example, CNNEmotions.mlmodel
In main.swift, write
print(CNNEmotions()) // CNNEmotions is the name of the generated model type
I know that CoreML only runs on macOS and iOS., so in Package.swift, I added a platform parameter:
let package = Package.init(
name: "MyProject",
platforms: [
.macOS(.v10_13), // this is the minimum macOS version that supports CoreML
],
...
Run
swift build
And there will be an error saying that CNNEmotions is an unresolved identifier.
If I do swift package generate-xcodeproj and open up the project in Xcode, I can see that the .mlmodel file is not added to the project at all!
This person on Apple Forums seems to also be in the same situation as me, but there are no answers to their question...
How can I make SPM work with mlmodels?
Just when I thought it's the end of the world, I found that if I add the .mlmodel file into the project in Xcode, the program can compile and run successfully. But the problem with building it in Xcode is that it's quite inconvenient. It doesn't produce an executable in a convenient location (I have to go all the way to the DerivedData folder to find it). To be honest, I would just like a convenient command to build & run it, like swift build. This is my ultimate goal.

swift-package does not exist on my toolchain

I am following some tutorials, basically trying to start an echo server in swift, without xcode, just command line and plain text editors, so I can get a grasp of the ecosystem
but I found this error for which there seems to be no solution already online
swift package init --type executable
error: unable to invoke subcommand: /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.14.xctoolchain/usr/bin/swift-package (No such file or directory)
It looks like I was pointing to the Swift compiler in the OS toolchain (which doesn't have swiftpm)
So after running
export TOOLCHAINS=default swift package init --type executable
The command worked successfully

`swift package generate-xcodeproj` fails with "Swift does not support the SDK"

I'm having trouble running swift package generate-xcodeproj. I created my package like this:
$ /Applications/Xcode9.4.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift package init --type executable
(as I have many Xcode versions installed I explicitly targeted a swift binary when running the command so that I don't need to xcode-select all the time)
This created a Package.swift with the version header // swift-tools-version:4.0.
Now, when I run swift package generate-xcodeproj I get a fatal error:
$ /Applications/Xcode9.4.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift package generate-xcodeproj
/Users/max.chuquimia/Desktop/xcode/MyPackage: error: manifest parse error(s):
<unknown>:0: error: Swift does not support the SDK 'MacOSX10.12.sdk'
No .xcodeproj is generated. Why is this occurring?
It seems the problem is the $DEVELOPER_DIR environment variable is wrong - it should also be made to point to the Xcode version that the swift binary resides in.
$ DEVELOPER_DIR=/Applications/Xcode9.4.1.app/Contents/Developer /Applications/Xcode9.4.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift package generate-xcodeproj

Can not import TensorFlow for Swift in Xcode Playground

I'm trying to use Swift for TensorFlow and have followed the directions found here: https://github.com/tensorflow/swift/blob/master/Installation.md
When I go ahead and import TensorFlow as such within a Swift Playground file:
import TensorFlow
I get this error: "The active toolchain is not compatible with playgrounds. libswiftCore.dylib could not be loaded"
I was able to use Swift for TensorFlow within the REPL so I know it should work. Anyone have any ideas as to how to fix this issue? It clearly works as shown in this demonstration: https://www.youtube.com/watch?time_continue=819&v=Yze693W4MaU
Get the latest stable toolchain (e.g. v 0.6), install it, then go to Xcode > File > New > Project > Macos - Command Line Tools (instead of Playground). Additionally, the December 23, 2019 development toolchain—and beyond—should not require switching to the Legacy Build System. More information in this discussion here.
Was running into this as well. Answered in the Google Group - turns out you need to make sure you are creating a macOS playground and not an iOS playground.
I had the same issue and it turns out is the playground type.
From the Google Group reply:
As a synthesis of answers above and my own experience now with the latest May 8, 2020 builds and comments from the Google Group, I find:
SUCCESS
Xcode Project Command-line (as #8bitmp3 answered above)
Command-line swiftc (using the -O argument. Note this is the compiler)
FAILURE
Xcode Playground macOS (as #ian-do originally asked)
Command-line swift (and confirmed by Google Group. Note this is the interpreter)
For those interested in the command-line success (macOS 10.15.4), install the toolchain from here, create the source code file inference.swift per this page, and execute the following:
# Test this command. Expected outcome is your existing Xcode app as show below
$ xcrun -f swift
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift
# Switch to the new TensorFlow toolchain you installed
# Mine was located at /Library/Developer/Toolchains/swift-tensorflow-RELEASE-0.9.xctoolchain/
# Open the Info.plist file, locate CFBundleIdentifier, and copy the string value
# Mine was com.google.swift.20200507
$ export TOOLCHAINS=com.google.swift.20200507
# Test the switch to your TensorFlow toolchain. Note the different result
$ xcrun -f swift
/Library/Developer/Toolchains/swift-tensorflow-RELEASE-0.9.xctoolchain/usr/bin/swift
# Compile your Swift for TensorFlow source code
$ cd <directory with .swift file>
$ swiftc -O -sdk `xcrun --show-sdk-path` inference.swift
# Run the program
$ ./inference
[[0.68070436]]