20

The man page for xcodebuild reads:

Run xcodebuild from the directory containing your project (i.e. the directory containing the projectname.xcodeproj package).

I would like to keep my source directory (which is a Subversion external) clean and unmodified, and build my object files and executables to a location completely outside of the source directory.

Is there any way to build into a separate build directory from a terminal using xcodebuild like you can do with make tools or even msbuild on Windows?

ctn
  • 2,887
  • 13
  • 23
Dave Mateer
  • 17,608
  • 15
  • 96
  • 149

7 Answers7

39

You can set build settings from the command line. The CONFIGURATION_BUILD_DIR will set the build directory. For example:

xcodebuild -project YourProject.xcodeproj -configuration Debug -target All ARCHS=x86_64 ONLY_ACTIVE_ARCH=YES CONFIGURATION_BUILD_DIR=../some/other/dir

A reference is found on Apple's site:

Dave Mateer
  • 17,608
  • 15
  • 96
  • 149
13

To achieve complete separation the following build settings have to be changed (more than just CONFIGURATION_BUILD_DIR like accepted answer suggests), otherwise Xcode still builds some of its artifacts under its default build folder.

On my machine Xcode normally builds everything to ./Build and ./DerivedData where current directory is one of my project.

I wanted xcodebuild to build everything under Build-command-line folder so I used xcodebuild -scheme MyScheme -showBuildSettings | grep Build\/ to find all build settings that correspond to all build paths and by trial-end-error I found "the generative" build settings that are enough to redirect all build artefacts produced by xcodebuild to custom folder.

I ended up using the following command:

BUILD_DIR=./Build-command-line
DERIVED_DATA_DIR=$(BUILD_DIR)/DerivedData

xcodebuild -project MyProject.xcodeproj \
         -IDEBuildOperationMaxNumberOfConcurrentCompileTasks=`sysctl -n hw.ncpu` \
         -scheme MyScheme \
         -sdk iphonesimulator \
         -destination 'platform=iOS Simulator,name=iPhone 6S Plus,OS=latest' \
         -xcconfig command-line-build.xcconfig \
         -derivedDataPath $(DERIVED_DATA_DIR) \
         test

Where command-line-build.xcconfig is:

HERE_BUILD=$(SRCROOT)/Build-command-line
HERE_INTERMEDIATES=$(HERE_BUILD)/Intermediates

// Paths
// the following paths are enough to redirect everything to $HERE_BUILD
MODULE_CACHE_DIR    = $(HERE_BUILD)/DerivedData/ModuleCache
OBJROOT             = $(HERE_INTERMEDIATES)
SHARED_PRECOMPS_DIR = $(HERE_INTERMEDIATES)/PrecompiledHeaders
SYMROOT

Note: Make sure you use absolute paths in your xcconfig, otherwise you may have error: Xcode crashing on startup “parentPath must be nil but it is not.

I have written a post about this solution with a bit of background: xcodebuild: how to really change its build path.

P.S. Of course this information is subject to change but as of Xcode Version 7.3.1 (7D1014) it works perfectly for me.

Community
  • 1
  • 1
Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
  • Stanislav, you may be (the only person :) ) who knows [this one](https://stackoverflow.com/questions/54024900/what-the-heck-is-xcbuilddata-and-why-are-the-build-folders-not-actually-updated) :O – Fattie Jan 03 '19 at 15:25
  • No, I don’t. Sorry :) – Stanislav Pankevich Jan 03 '19 at 15:56
  • I'm not 100% sure, but at least for scenarios that I personally encounter (with Xcode 13), the problem with SYMROOT, OBJROOT, SHARED_PRECOMPS_DIR and others not affected by -derivedDataPath is solved by adding -IDECustomBuildProductsPath="" and -IDECustomBuildIntermediatesPath="" to xcodebuild invocation, see https://stackoverflow.com/a/71550519/1859783 below. – Grigory Entin Mar 20 '22 at 20:51
7

Xcode 10

For a Workspace if you're using CocoaPods:

xcodebuild -workspace youProject.xcworkspace -scheme yourScheme -sdk iphonesimulator -configuration Release SYMROOT=$(PWD)/build

That will put your .app in ./build/Release-iphonesimulator

Guy Daher
  • 5,526
  • 5
  • 42
  • 67
5

In my project, setting SYMROOT turned out to be sufficient to build the project in a different location, leaving other locations untouched.

From Apple's Xcode Build Setting Reference (which I came across via another answer here, thanks!):

SYMROOT (Build Products Path)

Description: Directory path. Identifies the root of the directory hierarchy that contains product files and intermediate build files. Product and build files are placed in subdirectories of this directory.

...

Affects: BUILT_PRODUCTS_DIR, CONFIGURATION_BUILD_DIR (...)

This setting is also mentioned a few times in the xcodebuild man page:

Available actions are:

build: Build the target in the build root (SYMROOT)...

clean: Remove build products and intermediate files from the build root (SYMROOT)....

Ashley
  • 5,865
  • 1
  • 19
  • 20
  • 2
    If you want to redirect **everything** to a custom folder, at least `OBJROOT` is very important because quite a few of folders depend on it, not on `SYMROOT`. I have just checked Xcode 7.3.1 - MODULE_CACHE_DIR and SHARED_PRECOMPS_DIR are also independent of `SYMROOT`. So your answer will still build some stuff to default build directory however maybe that is enough for your task. – Stanislav Pankevich Jun 03 '16 at 09:49
3

You should set the SYMROOT build setting to your desired location. All of the other relevant build settings are derived from it.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
1

If -derivedDataPath does not do the trick, add -IDECustomBuildProductsPath="" and -IDECustomBuildIntermediatesPath="" to xcodebuild invocation, like below:

xcodebuild -derivedDataPath /custom/path -IDECustomBuildProductsPath="" -IDECustomBuildIntermediatesPath="" ...

More info here: https://stackoverflow.com/a/71550483/1859783

Grigory Entin
  • 1,617
  • 18
  • 20
0

You can also temporarily change the working directory and run the command from there. i.e.

 (cd dir1/dir2/MyApp && xcodebuild build -workspace "MyApp.xcworkspace" -scheme "MyApp")
Alex Nguyen
  • 2,820
  • 1
  • 19
  • 14