16

I am working on my company's continuous integration server, and the build process is failing because the server does not have access to schemes in an xcode project.

Basically, they are using Cmake to generate xcode projects on the fly to be used for a single build, and then discarded until the next check in.

My research indicates that this problem will be fixed if there is an .xcscheme file with the .xcodeproj file, but for various reasons that can't be generated and checked in ahead of time.

Is there a way to generate this file using xcodebuild or some other command line tool so that we can work it into existing build shell scripts?

The xcodebuild documentation, google, and S.O. are surprisingly lacking on this topic.

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
  • As far as I understood xcscheme files should be marked as shared. All CI tools I know for xcode require this to be set. Have a look at xctool: https://github.com/facebook/xctool – Opal Jul 15 '14 at 07:46
  • I tried marking the scheme as shared but it doesn't do me any good because cmake creates the xcode project file after each commit. There isn't a way to generate it from a project file because the project file doesn't exist on the CI server, it generates it on the fly from source code. – FrustratedIntern Jul 15 '14 at 17:23
  • Ok, no idea then how to help You. – Opal Jul 15 '14 at 17:24
  • What problem are you trying to solve? How does the build process fail? What is the error message? Your research seems illogical. If the cmake build process passes on a dev machine by generating Xcode project files then it should pass on a CI server. Please post any errors and relevant code and a full description of the desired behavior in relation to the observed behavior. How does it work outside of CI? How does it fail on the CI server? – Gardner Bickford Jul 30 '14 at 19:36

5 Answers5

6

I generate the Xcode project using the -G Xcode too; I'm using the scan-build plugin ( http://blog.manbolo.com/2014/04/15/automated-static-code-analysis-with-xcode-5.1-and-jenkins ) in Jenkins. It requires the workspace files. My script to launch & watch Xcode looks like that: ($WORKSPACE is set by jenkins)

#!/bin/bash

/Applications/Xcode.app/Contents/MacOS/Xcode "${WORKSPACE}/Build/arangodb.xcodeproj" &
XCODE_PID=$!

# now we wait for Xcode to build the workspace:
WAIT_FOR_XCODE=0
while test ${WAIT_FOR_XCODE} -lt 6; do
    WAIT_FOR_XCODE=`find "${WORKSPACE}/Build/arangodb.xcodeproj" |wc -l`
    sleep 2
    COUNT=`ps -p ${XCODE_PID} |wc -l`
    if test ${COUNT} -lt 2; then 
        echo "Xcode went away unexpectedly!"
        exit -1
    fi
done

#ok, we believe its done. kill it, and wait until its realy dead.
kill ${XCODE_PID}
COUNT=2;
while test ${COUNT} -gt 1; do 
    sleep 1
    COUNT=`ps -p ${XCODE_PID} |wc -l`
done
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
dothebart
  • 5,972
  • 16
  • 40
  • Found this answer to be the most useful one, especially that it is fully automated. Thanks @dothebart ! – Erunehtar Jun 28 '16 at 19:00
5

Unfortunately, as of Xcode 5.1.1 there does not exist a mechanism for auto-generating .xcodeproj or .xcworkspace build schemes from the command line as the Xcode UI does. The good news though is that an Xcode project's pbxproj markup is an order of magnitude more complex than the XML markup that describes a build scheme. If you've managed to get CMake to spin up a well-formed Xcode project on-commit, then using a very similar procedure you can build out the 100 or so lines of XML that describe the build-run-test-profile-archive actions of that Xcode project.

If you've not taken a peek at the underlying XML structure of a scheme, create a sample iOS project from the new project wizards and then go poking through the contents of the .xcodeproj or .xcworkspace file for .xcscheme files. The structure is fairly self-documenting and you might even be able to get away without actually specifying the XML markup for those actions you know that will not be run on CI.

Failing that, a less robust approach would be to looking into opening up the Xcode project/workspace file upon the completion of your CMake build process. After a handful of seconds, Xcode's indexer will have had time to identify the projects and auto-generate the schemes for the projects within the master project file itself. Obviously, as you are relying on a UI-layer operation in this approach, you are subject to Xcode's whims, and the indexer may take more than a few seconds to build its index (ex. larger projects will take longer to auto-generate schemes!) ...and there is no trigger advising command-line processes that the indexing and generation has succeeded or failed. You'd wind up having to poll for the existence of a file with an appropriate timeout which can get a bit dicey in an automated build and test environment.

Bryan Musial
  • 8,340
  • 2
  • 43
  • 50
2

I was actually able to do this by using cmake to generate the project, then using the xcode gui to make the scheme files I need. I used the terminal to extract the xcscheme files from the project and put them in another directory being tracked by source control. As part of the generation process, I just added a bit of shell script to copy the copies I made earlier into the newly generated project, then continue the build process as normal.

  • Well, but this obviously does not solve the problem generally, as long as targets may change name or existence, right? – lef Apr 10 '15 at 12:58
  • 2
    would it be possible to see your cmake script to do this? – Frank May 31 '16 at 22:36
2

The latest version of cmake has added this functionality:

https://blog.kitware.com/cmake-3-9-0-rc3-is-now-ready-for-testing/

The "Xcode" generator learned to create Xcode schema files. This is an experimental feature and can be activated by setting the "CMAKE_XCODE_GENERATE_SCHEME" variable to a "TRUE" value.

TheNextman
  • 12,428
  • 2
  • 36
  • 75
0

For CMake based project use XCODE_GENERATE_SCHEME setting for your target. Setting:

set_target_properties(<your_target> PROPERTIES
  XCODE_GENERATE_SCHEME YES
)

will produce following file

your_project.xcodeproj/xcshareddata/xcschemes/your_target.xcscheme