SPM vs Xcode Folders

One of the things that I am having difficulty with is, it seems that SPM and Xcode have different rules for folder hierarchies.

This is how SPM wants it.

MyProject
├── Package.resolved
├── Package.swift
├── README.md
├── Sources
│   └── MyProject
│       ├── AppDelegate.swift
│       ├── Base.lproj
│       │   ├── LaunchScreen.storyboard
│       │   └── Main.storyboard
│       ├── CollectionViewAdaptor.swift
│       ├── Info.plist
│       ├── Query.swift
│       ├── SearchAdaptor.swift
└── Tests
    └── MyProjectTests
        └── MyProjectTests.swift

Xcode has a different layout:

MyProject
├── MyProject
│   ├── AppDelegate.swift
│   ├── Base.lproj
│   │   ├── LaunchScreen.storyboard
│   │   └── Main.storyboard
│   ├── Info.plist
│   └── ViewController.swift
├── MyProject.xcodeproj
├── MyProjectTests
│   ├── MyProjectTests.swift
│   └── Info.plist
├── MyProjectUITests
│   ├── MyProjectUITests.swift
│   └── Info.plist
├── Frameworks
├── README.md
└── Tests
    └──MyProjectTests

Note that SPM want Sources and Tests while Xcode has repeated Project name and Project name Tests folders. Is the SPM layout the new layout? I am trying to adopt SPM but these path issues seem to confuse things. Xcode is expecting things in its layout. When I run this on the terminal I get the usual UIKit missing errors but it finds things:

swift xcode build

If I run it in Xcode the SPM build phase is looking in its expected folder layout:

Showing All Messages
PhaseScriptExecution Build\ Swift\ Package\ Manager\ Dependencies /Users/possen/Library/Developer/Xcode/DerivedData/MyProject-arxseroadahccwabgqjxvtlzbomp/Build/Intermediates.noindex/MyProject.build/Debug-iphonesimulator/MyProject.build/Script-D5976F2B210E2CCF0053A61B.sh (in target: MyProject)
cd /Users/possen/Projects/MyProject
/bin/sh -c /Users/possen/Library/Developer/Xcode/DerivedData/MyProject-arxseroadahccwabgqjxvtlzbomp/Build/Intermediates.noindex/MyProject.build/Debug-iphonesimulator/MyProject.build/Script-D5976F2B210E2CCF0053A61B.sh

/usr/local/bin/swift-xcode-build: line 120: /Users/possen/Projects/MyProject/MyProject/Package.swift: No such file or directory
Warning: Missing 'Sources' dir in: /Users/possen/Projects/MyProject/MyProject
Building dependencies (debug) ... (0s)
Compile Swift Module 'PromiseKit' (14 sources)
Compile Swift Module 'PMKFoundation' (5 sources)
Compile Swift Module 'AwaitKit' (4 sources)
Compile Swift Module 'QNetwork' (1 sources)
Compile Swift Module 'MyProject' (8 sources)
2018-07-29 11:48:29.783 swift-progress[49179:10327528] app will terminate: 0
mv: rename .build/ to /Users/possen/Projects/MyProject/MyProject/.buildzz/.build/x86_64-apple-ios12.0/debug: Invalid argument
Done building package (for dependencies). (8s)
swift package resolve failed.
Command PhaseScriptExecution failed with a nonzero exit code

you can see this /Users/possen/Projects/MyProject/MyProject/.buildzz/.build/x86_64-apple-ios12.0/debug:

Where it looks in MyProject/MyProject rather than the Source and Test layout preferred by SPM. Are we going to the SPM layout or keeping the Xcode layout? Any recommendations on what I should do for this? Create an alias maybe?

By the way, this is running on Xcode 10beta4
Thanks,
Paul

If you want to use the SPM, you're going to probably want to use its expected layout. You can always use swift package generate-xcodeproj or just configure your Xcode project around it.

Thanks. It seems like it might be a bug in Xcode line 120 of the script /usr/local/bin/swift-xcode-build has this comment about the grep path.

if [[ "x${BUILD_IN_XCODE}" = "xyes" ]]; then
  # this is a little tricky, we should be more flexible here:
  #   grep  path: "."
  if [[ $(grep -c 'path: "."' < "${SPM_CONFIG}") -eq 0 ]]; then
    # TODO: this is Swift 4 specific, Swift 3 doesn't require the subdir
    SPM_PKG_DUMMY_DIR="${SPM_PACKAGE_DIR}/Sources/${PRODUCT_NAME}"
    if [[ ! -d "${SPM_PACKAGE_SOURCE_DIR}/Sources/${PRODUCT_NAME}" ]]; then
      echo "Warning: Missing 'Sources' dir in: ${SPM_PACKAGE_SOURCE_DIR}"
    fi
    mkdir -p "${SPM_PKG_DUMMY_DIR}"
  else
    SPM_PKG_DUMMY_DIR="${SPM_PACKAGE_DIR}"
  fi
  
  # create a dummy
  # TODO: differentiate between Executable and Library Package?
  echo "fileprivate let swiftXcodeDummy = true;" > "${SPM_PKG_DUMMY_DIR}/dummy.swift"
  
  if [[ "x$verbose" = "xyes" ]]; then
    echo "Dummy dir ${SPM_PKG_DUMMY_DIR}"
  fi
fi

My workaround was to create an alias back to the root of my project cd MyProject; ln -s . MyProject This seems to work at least for now.