Request for help packaging an Xcode-based program

Hi all,

I opened PR 67226 to add a derivation for SwiftFormat, a Swift formatting and linting tool. The build step is very straightforward…

xcodebuild -project SwiftFormat.xcodeproj \
    -scheme "SwiftFormat (Command Line Tool)" \
    CODE_SIGN_IDENTITY= SYMROOT=build OBJROOT=build

…as long as you have access to the Xcode infrastructure, which currently seems to be a pain point in Nix.

For this package, I tried to copy the workaround that @lilyball came up with for the MacVim derivation:

let
  buildSymlinks = runCommand "swiftformat-build-symlinks" {} ''
    mkdir -p $out/bin
    ln -s /usr/bin/xcodebuild $out/bin
  '';
in
stdenv.mkDerivation rec {
  # ...
  nativeBuildInputs = [ buildSymlinks ];
  # ...
}

but this did not work for the only other person who commented on that PR, and Ofborg was also unable to build it.

Does anyone have any advice on how I can get this package to build in any kind of pure way?

When you say “in any kind of pure way”, my workaround is definitely not pure, and the package definitely won’t build in the sandbox (I haven’t actually tried, but there’s no way it can without adding /Applications/Xcode.app and /usr/bin/xcodebuild—and probably some other stuff too—to extra-sandbox-paths).

For your case the first thing I’d suggest trying is using xcbuild to build it. I haven’t actually tried this myself, but it’s supposed to handle a fair number of Xcode projects. From the manual it looks like there’s even a package setup hook called xcbuildHook that uses xcbuild automatically for the build/install phases (and is configured with xcbuildFlags). I haven’t tried using this for MacVim yet because we rely on using ibtool to patch the xib, which means we need Xcode anyway.

I tried to replace the buildSymlinks approach with xcbuild, but that didn’t work:

these derivations will be built:
  /nix/store/ricrb5ha8vzh8rdymihblal0z4cinqq3-swiftformat-0.40.11.drv
building '/nix/store/ricrb5ha8vzh8rdymihblal0z4cinqq3-swiftformat-0.40.11.drv'...
unpacking sources
unpacking source archive /nix/store/hwlsqkpwcickn6p4qvlz9kyshxpr2cys-source
source root is source
patching sources
configuring
no configure script, doing nothing
building
warning: unable to find Swift libraries
Build settings from the command line:
    CODE_SIGN_IDENTITY=
    DERIVED_DATA_DIR=.
    OBJROOT=build
    SDKROOT=MacOSX10.12
    SYMROOT=build

=== BUILD TARGET CommandLineTool OF PROJECT SwiftFormat WITH THE DEFAULT CONFIGURATION (Debug) ===

Check dependencies

Write auxiliary files
/bin/mkdir -p build/SwiftFormat.build/Debug/CommandLineTool.build
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat.hmap
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat-own-target-headers.hmap
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat-all-target-headers.hmap
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat-all-non-framework-target-headers.hmap
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat-generated-files.hmap
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/swiftformat-project-headers.hmap
/bin/mkdir -p build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformatTool-OutputFileMap.json
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformat.LinkFileList
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/Script-017AEBB31D6F27D500764325.sh
chmod 0755 build/SwiftFormat.build/Debug/CommandLineTool.build/Script-017AEBB31D6F27D500764325.sh
write-file build/SwiftFormat.build/Debug/CommandLineTool.build/Script-0111360720872D83000FF63D.sh
chmod 0755 build/SwiftFormat.build/Debug/CommandLineTool.build/Script-0111360720872D83000FF63D.sh

Create product structure

Ditto build/SwiftFormat.build/Debug/CommandLineTool.build/DerivedSources/swiftformatTool-Swift.h build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformatTool-Swift.h
    cd /private/var/folders/md/kw3kgndd11sc9vb5w4rtl5b0000gfh/T/nix-build-swiftformat-0.40.11.drv-0/source
    /usr/bin/ditto -rsrc build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformatTool-Swift.h build/SwiftFormat.build/Debug/CommandLineTool.build/DerivedSources/swiftformatTool-Swift.h
ditto: can't get real path for source 'build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformatTool-Swift.h'

** BUILD FAILED **

The following build commands failed:
    Ditto build/SwiftFormat.build/Debug/CommandLineTool.build/DerivedSources/swiftformatTool-Swift.h build/SwiftFormat.build/Debug/CommandLineTool.build/Objects-normal/x86_64/swiftformatTool-Swift.h
(1 failure)
builder for '/nix/store/ricrb5ha8vzh8rdymihblal0z4cinqq3-swiftformat-0.40.11.drv' failed with exit code 1
error: build of '/nix/store/ricrb5ha8vzh8rdymihblal0z4cinqq3-swiftformat-0.40.11.drv' failed

Aside from the build command that failed, this also says “warning: unable to find Swift libraries”. Any idea if there’s something else I should be making available in the build environment?

It’s entirely possible that xcbuild doesn’t work well with Swift. I don’t know, I’ve never actually tried it, I just know it’s recommended by the manual as an option.

If you can’t get it working with xcbuild then you could just abandon purity and live with it failing to build in the sandbox.

I also notice there’s nixpkgs derivations for older Xcode versions, which at first glance appear to download the actual dmg for that Xcode and I guess run it directly from the nix store. That seems like a very extreme solution though, as it means having to download a multi-gigabyte dmg before you can build.