Build

Build Process

Intro

This shell script (sh | bash) is a script which runs the xcode project build commands via terminal (CLI)
You can read on this MAN page of xcodeBuild

The project can have multiple targets and we specify the scheme which we want to make the CI/CD server run the project.

Information for xcodebuild, xcrun & swift
Copied off SO post

xcodebuild

xcodebuild is part of Xcode's bundled command-line tools package. From the manpages:

build Xcode projects and workspaces

xcodebuild builds one or more targets contained in an Xcode project, or builds a scheme contained in an Xcode workspace or Xcode project.

xcodebuild has lots of options and use cases. The options are equivalent to certain user actions within the Xcode IDE. Example usage:

xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme

Builds the scheme MyScheme in the Xcode workspace MyWorkspace.xcworkspace.

In the command above, we build the workspace without Xcode, using what Xcode runs internally for compilation. Xcode can only be installed on macOS and we have the same limitations for using its command-line tools, including xcodebuild and xcrun.

xcrun

xcrun is another Xcode command-line tool part of Xcode's CLI tools. From the manpages:

run or locate development tools

xcrun provides a means to locate or invoke coexistence- and platform-aware developer tools from the command-line, without requiring users to modify makefiles or otherwise take inconvenient measures to support multiple Xcode toolchains.

xcrun [-sdk SDK] -find <tool_name>

xcrun is also commonly used with Xcode-select to manage multiple Xcode versions on the same machine. Every version of Xcode comes bundled with its own development tools, and we can use xcrun to get the current path to them:

xcrun xcode-select --print-path

swift

swift is the Swift REPL. swift is a command-line tool that includes the Swift toolchain but can also be installed outside of the Xcode bundled tools. swift is different from xcodebuild and xcrun because it is compiled Swift rather than C. swift is not well documented in the MacOS manpages documentation, however, Apple has documented these tools on its blog:

Xcode 6.1 introduces yet another way to experiment with Swift in the form of an interactive Read Eval Print Loop, or REPL.

Mind Map

xcode build commands

xcode terminal commands

xcode performance analysis

Why Xcode CLI

It is not efficient to open up xcode app (GUI) when trying to work with CI/CD so a headless unit like xcodeBuild CLI is recommended which comes preinstalled with Xcode app or you can install them using

xcode-select --install

This installs Xcode Command Line Tools when you're opening up xcode setup process for first time.

Commands

List build devices

Lists all the xcode build CLI devices available to run.

xcrun xctrace list devices

Which Xcode version

xcodebuild -version

Swift version

xcrun swift -version

Command line tools version

gcc --version

Inspecting Binary

Xcode build process will always compile and link the output files in order to run that in machine readable (instructions SET). These usually are called binary files.

Sometimes we want to inspect a binary, you could do this by using this command

lipo -info <path-to-binary>

To be clear, a framework or an app can both be inspected with lipo. Similarly if you access the build folder on the simulator, you can inspect the binary as well.
llvm | lipo guide

Optimization

Debug

During active development, you want to build things fast. It doesn't make sense for you to actively build architectures you don't need to use.

Release

While releasing it â€” for others. Then because you don't want to limit/dictate how they build your app, then you have to build for all possible combinations and make sure your framework compiles for all of them.

Changeset in .pbxproj or .xcodeproj

This changeset is evident because we updated iOSDependencySupport SPM package with new version and also replaced the existing reference in our Xcode target schemes. So new unique identifier is been generated in order to link appropriately. Xcode + SPM cache and build optimization stuff. It internally maintains a graph of frameworks build with linking and what not. So subsequent builds are faster. Xcode maintains that unique tree / graph level ancestry in these files in order to make appropriate optimization necessary and not waste CPU cycle on rebuilding / linking frameworks, assets, libraries. Any resources which require compilation of some sort.

Auto Completion | Indexing | Source LSP

Great article around how xcode internally handles its stuff for getting more metadata around the project which it needs to make better inferences.

Resolving arch build errors

ARCHS

resolving build errors for apple silicon | apple developer

Apple Silicon and the library incompatibility problem for iOS development

ssh Binaries

You can solve this problem in three ways

  • netrc + scmProvider (xcodebuild)
  • Git config insteadOf rule override
  • keychain override

netrc_scmProvider

I did a few things:  

-  moved the keychain out of ~/Library
- put github credentials in a ~/.netrc file
- told xcodebuild to use the netrc: `-scmProvider system -packageAuthorizationProvider netrc`

Basically because the URL has [github.com](http://github.com/) in it, xcode wants to know what credentials are needed to get it, even if the URL is not private. This all works around that so that Xcode doesn't need to ask. It was hanging because ti was waiting to be provided with creds and no one is there to fill in the dialog.

Basically you can utilize xcode build system to appropriately ask them to use ssh agent and .netrc configs to get around this problem

Copied below stuff for archival purposes
swift | forums | Support for resolving private packages through HTTPS with xcodebuild

If you use `xcodebuild -scmProvider xcode`, HTTPS can be used, but you would typically log in via Xcode preferences to your SCM service account.
Looks like there is no alternative to using the Xcode UI today, so you would need to login once via that on the CI machine to store the credentials and then using `xcodebuild -scmProvider xcode` should be able to use those credentials you configured.

gitconfig_insteadOf

For us using the netrc file does the trick. But note that besides:

machine github.com
  login <username>
  password <personal access token>

You also need to add this if your Package.swift points to binaries stored in GitHub package registry:

machine maven.pkg.github.com
  login <username>
  password <personal access token>

Took me quite a while to figure this out, but sub domains are not included in the machine definitions, so specify them individually

keychain_override

aws | troubleshooting artifact downloading docs

github issue | keychain token option

Build Errors

Resources

Excellent StackOverflow post about xcode build process related to architecture and linking

Instruction set architecture

use-xcodebuild-command-line

build-ios-apps-from-the-command-line-using-xcodebuild