Configuring Xcode project to be built with specific build tools version - xcode

In my build system, I am using xcodebuild to build multiple projects.
I want to configure different Xcode installation to be used per project.
I know about sudo xcode-select --switch <path>, but:
This option is system-wide, and might mess up with other parallel
builds.
It requires root, which I prefer to avoid (since it's an automatic build system).
It is not configured internally in the project.
Is there a way to specify the build tools path to use per project?

From the output of xcrun:
The active developer directory can be set using xcode-select, or via the DEVELOPER_DIR environment variable. See the xcrun and xcode-select manual
pages for more information.
E.g. to run xcodebuild with a specific Xcode-installation:
$ DEVELOPER_DIR=/path/to/my/Xcode.app/Contents/Developer xcodebuild
In a bash script:
export DEVELOPER_DIR=/path/to/my/Xcode.app/Contents/Developer
xcodebuild

You can probably launch xcodebuild directly from Applications/Xcode.app/Contents/Developer/usr/bin, so modifying the path you will use different Xcode version.

Related

Simultaneous Xcode command-line builds with different Xcode-select values

Our build server has multiple versions of Xcode installed. Our build scripts use xcode-select to choose the correct version. All that is fine.
Some of our builds take a while to run. We're thinking of allowing multiple simultaneous builds (Bamboo agents) on the same build server. My worry is that xcode-select on different (but simultaneous) builds would cause a race condition. A build that begins with Xcode 9.4.1 might get switched to Xcode 10.0 mid-build if a second build begins and requires that version.
My only thoughts are to use VM's/new machines to parallelize the builds.
I'm curious if anyone's dealt with this scenario. Thanks.
You might try using xcrun instead of xcode-select to invoke your xcodebuilds. You may find your builds contending for system resources when building concurrently...
You can set the DEVELOPER_DIR environment variable rather than switching the active Xcode using xcode-select.
From the xcode-select man page:
ENVIRONMENT
    DEVELOPER_DIR
        Overrides the active developer directory. When DEVELOPER_DIR is set, its value will be used instead of the system-wide active
developer directory.
        Note that for historical reason, the developer directory is considered to be the Developer content directory inside the Xcode
application (for example
/Applications/Xcode.app/Contents/Developer). You can set the environment variable to either the actual Developer contents
directory, or the Xcode application directory -- the
xcode-select provided shims will automatically convert the
environment variable into the full Developer content path.

How to use the configure command within Xcode?

I'm trying to customize the compilation of curl-7.60.0 with Xcode.
I added it as an External Build System target. There is no problem if I build it as is, but I would like to change the --prefix option from the ./configure command.
Need some help here please
For my case, I just ran the ./configure on the command prompt to generate the Makefile then go back to Xcode to build

Does DEVELOPER_DIR need to remain set in the environment?

I'd like to have side-by-side installations of XCode, and use the DEVELOPER_DIR environment variable to select between them. The goal for this is to use the result of xcrun -f --sdk macosx clang to determine the appropriate C compiler, and then use that in a script or build system.
CC=$(DEVELOPER_DIR=<something> xcrun -f --sdk macosx clang)
My question is whether DEVELOPER_DIR needs to remain set when using the tools found by xcrun, or whether it is OK to just set it during the execution of xcrun, as is done above, and then use the returned tools in the default environment, without DEVELOPER_DIR still set.
In other words, while xcrun clearly does depend on the value of DEVELOPER_DIR, do the tools themselves depend on it too? Is there a meaningful difference between:
DEVELOPER_DIR=<whatever> command CC=$(xcrun -f --sdk macosx clang)
command CC=$(DEVELOPER_DIR=<whatever> xcrun -f --sdk macosx clang)
Is the second one correct? Or only the first?
I'd like to have side-by-side installations of XCode, and use the DEVELOPER_DIR environment variable to select between them.
It's fine to have two or more versions of Xcode installed. The usual way to select between them is to use the xcode-select command, but the man page for that command does seem to say that you can accomplish the same thing for just the current session by setting the DEVELOPER_DIR environment variable yourself. Here's what the documentation for the --switch option says:
Sets the active developer directory to the given path, for example
/Applications/Xcode-DP.app. This command must be run with superuser
permissions (see sudo(8)), and will affect all users on the system. To
set the path with-out superuser permissions or only for the current
shell session, use the DEVELOPER_DIR environment variable instead
(see ENVIRONMENT).
However, you should also heed the advice given in the ENVIRONMENT section:
Note that for historical reason, the developer directory is considered
to be the Developer content directory inside the Xcode application
(for example /Applications/Xcode.app/Contents/Developer). You can set
the environment variable to either the actual Developer contents
directory, or the Xcode application directory -- the code-select
provided shims will automatically convert the environment variable
into the full Developer content path.
So the <whatever> in your question should specify the full path to the Developer directory, not just to the Xcode application.
In other words, while xcrun clearly does depend on the value of DEVELOPER_DIR, do the tools themselves depend on it too? Is there a meaningful difference between:
• DEVELOPER_DIR=<whatever> command CC=$(xcrun -f --sdk macosx clang)
Using xcrun to find the tools so that you can invoke them yourself and worrying about when to set and unset DEVELOPER_DIR seems overly complicated. Per the xcode-select documentation, all the "shims" respect the DEVELOPER_DIR setting. "Shims" here refers to the Xcode commands in /usr/bin. As long as that environment variable is set correctly, you can just invoke '/usr/bin/clang' instead of whatever xcrun finds, and /usr/bin/clang will call through to the clang version in DEVELOPER_DIR. Presumably, you're asking this question because you're writing a build script of some kind, so there should be no problem setting DEVELOPER_DIR early in that script and then just using the /usr/bin commands.
• command CC=$(DEVELOPER_DIR=<whatever> xcrun -f --sdk macosx clang)
Programs inherit the environment from their parent processes. Here you're finding the right copy of clang to use, but you'll invoke it in an environment where DEVELOPER_DIR isn't set. Whether this matters depends on whether the tool you're using invokes any other tools. I honestly don't know whether any of the tools do invoke other tools, but it seems logical that a tool like xcodebuild would invoke many of those tools and therefore depend on DEVELOPER_DIR being set correctly.
In short, there's no downside to setting DEVELOPER_DIR as needed in your build script, and trying to specify it only in your call to xcrun seems less reliable in general than the alternative approach.

xcodebuild does not install into applications folder

I have an XCode project with two executable targets, which I use for my own work (that is, I don't sell or publish the applications, but they are still important to me), which depends on one external project. Until now, it has been unproblematic to build the Application(s) and install into the /Applications folder. What I did, was go into the command line and type:
sudo xcodebuild -scheme Trainer install
This would install the target Trainer into the Applications folder, and the application could be run from there. If I tried to specify the target using -target Trainer instead, it would not work, as it would not find dependencies in the external project. Anyway, since last time it worked, two things have happened:
I have upgraded to OS X 10.11
I have upgraded XCode to Version 7.1.1 (7B1005)
Whatever the reason, xcodebuild does no longer install the built product into the /Applications folder. The last lines from the build log, when building with xcodebuild now are:
Touch /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/BuildProductsPath/Release/Trainer.app.dSYM
cd /Users/pbholmen/Projects/SoundSample
/usr/bin/touch -c /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/BuildProductsPath/Release/Trainer.app.dSYM
RegisterWithLaunchServices /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/InstallationBuildProductsLocation/Applications/Trainer.app
cd /Users/pbholmen/Projects/SoundSample
builtin-lsRegisterURL /var/root/Library/Developer/Xcode/DerivedData/SoundSample-bvsqlgnuhfmtjkgkhevztdzbjbie/Build/Intermediates/ArchiveIntermediates/Trainer/InstallationBuildProductsLocation/Applications/Trainer.app
** INSTALL SUCCEEDED **
I have tried to simply copy the Trainer.app that it builds into the /Applications folder, but if I double-click on it, it just won't run. Of course, the Application works when built and run from within XCode, both with the "Debug" and "Release" configuration.
Back when it did work, this would be the last lines of the build log (in Terminal):
Touch build/Release/Trainer.app.dSYM
cd /Users/pbholmen/Projects/SoundSample
/usr/bin/touch -c /Users/pbholmen/Projects/SoundSample/build/Release/SoundSample.app.dSYM
RegisterWithLaunchServices /Applications/Trainer.app
cd /Users/pbholmen/Projects/SoundSample
builtin-lsRegisterURL /Applications/Trainer.app
** INSTALL SUCCEEDED **
If I try to go into the build log from within XCode, find where it puts the builds, and maneuver into that location in Finder and start the application from outside of XCode, that doesn't work either.
Here you can see my Deployment build settings for the target:
Build settings
Under "Deployment location" I have tried both "YES" and "NO", and under "OS X Deployment target" I have tried both "OS X 10.10" and "OS X 10.11". And all four combinations of the two.
After hours of twiddling, I finally figured out the answer. First off, the command
sudo xcodebuild -scheme Trainer install
is wrong. It was a workaround, because I couldn't get XCode to manage my external dependencies from the command line, even though they were managed correctly within XCode. The correct invocation, for a target other than the project's main target is
sudo xcodebuild -target Trainer install
Previously, the first invocation would work, the product would be installed even though the scheme doesn't really include an "Install" action. This is clearly no longer so with XCode 7.1. The reason I couldn't use -target instead of -scheme previously, was because my target was dependent on a framework in another project, which was added to my main project (the external project was added, not just the framework). All dependencies were set up correctly in my main project, and from the command line it worked only when specifying the scheme, not when specifying the target. When running xcodebuild with -target specified, xcodebuild would not find the modules in the external project (a Swift framework).
I have now figured out the reason for this. The project which contained the external framework was not set up correctly. It was set up to install the framework into a bogus location (/tmp/ProjectName.dst/Library/Frameworks, which is the default). In addition, my main project needed to add /Library/Frameworks into the framework search paths. It seems that when the project is built inside XCode, or for archiving etc... libraries and executables are built into a "private" folder structure separate from the system itself. When running xcodebuild install, however, it tries to install the external frameworks into the proper system folders, and link it there. Therefore, setups that work inside XCode may not work when running 'xcodebuild'.
EDIT: It works now, but StackOverflow won't let me mark it as correct before two days.

Building Xcode Project in Terminal - Choosing another Xcode

I have two different Xcode version installed on the same mac (Xcode 4 and Xcode 5). Xcode 4 is in the Applications folder.
So whenever I build any projects from the terminal, naturally it compiles by using Xcode 4. Is there any way to use Xcode 5 (which is in desktop) to build a project from the terminal?
I think the command xcode-select is here for this precise reason.
Usage: xcode-select [options]
Print or change the path to the active developer directory. This directory
controls which tools are used for the Xcode command line tools (for example,
xcodebuild) as well as the BSD development commands (such as cc and make).
Options:
-h, --help print this help message and exit
-p, --print-path print the path of the active developer directory
-s <path>, --switch <path> set the path for the active developer directory
-v, --version print the xcode-select version
-r, --reset reset to the default command line tools path
I had the same problem. I had changed the command-line tools option in Xcode's preferences. Here you can choose which version of Xcode, you wanted to use.

Resources