Xcode commandline building with dependent project - ios

I'm building a iOS application that uses a library that I've built using jverkoey's framework structure. All is well and good, until I try to let my CI environment (Jenkins) build my project. Jenkins builds using the commandline and when it does so my dependent framework gets built in it's own build directory, and when my main application builds in it's own directory it can't find the framework.
As a test I copied the output from my dependent frameworks build directory into the main apps build directory and re-ran my commandline build and everything works fine. So what I think I have to do is update my Jenkins build scripts to be able to move the dependent build output before building the main app, or change them to all build in the same directory as XCode does from the IDE with it's DerivedData directory.
The question is, how? I'm no expert when it comes to building from the commandline and I could really use some help here.

Ok, I figured this out. Just incase anyone else has a similar problem you can set the SYMROOT setting to whatever directory you want when running xcodebuild.
xcodebuild -target MyTarget SYMROOT=/Build/MyProj/Sym.root

Related

xcodebuild default build path

I'm trying to make a FAT framework following this guide
What I'd like to understand is the xcodebuild build path. Based on that tutorial, this is created at the beginning:
BUILD_PATH="${SRCROOT}/build"
Now when I make a build, the builds for Release-iphoneos and Release-iphonesimulator go into that build folder. Is this a predefined variable that can be set to tell Xcode where your builds can go? Because based on this other tutorial: BUILD_DIR gets passed to xcodebuild.
I was wondering what the difference is here and how Xcode handles these arguments.
How does setting this directory work with DerivedData?
Also on the topics of building, does Xcode cache builds? Sometimes after I build and do a ls -al on my frameworks, they don't have current timestamps. But once I delete the build directory, it seems to force Xcode to build again and then I get "fresh" frameworks created. Is Xcode caching the build and not replacing the build? Is there a way to force it?

Build phase script is running before needed files are created in Xcode 10

https://github.com/realm/realm-cocoa/blob/master/scripts/strip-frameworks.sh
We are always using this script to remove architectures for dynamic frameworks. It has worked with Xcode 9.
In Xcode 10, it didn't remove the architectures.
Anything in Xcode 10 that could break this?
We have a theory that it is related to the new build system
Solution
The new build system is now running scripts in parallel if its dependency is already available or if it doesn't have any dependency.
The solution is to provide input files to tell "run scripts" not to run yet without those dependencies.
This is more elaborated in this post
Alternative Solution:
We used the legacy build system as a work around.
File > Workspace Settings

Slow compile times with react-native iOS app

I am currently working on a react-native iOS app. While developing I noticed that the compile times for the app are really slow. I got a CI hooked up which roughly does the following:
clean git checkout of the applications workspace
run unit tests
run UI tests build the app
Since this is a clean checkout the app always recompiles all of the react static libraries which come with the React.xcodeproj like libyoga.a, libReact.a, etc. This means that a clean CI build roughly takes ~8min only to build all of the react dependencies (~4min * 2 because the UI test target rebuilds React again).
I wondered whether it would be possible to speed up the compile times. I came up with the following idea but need your advice to tell me if it would work or if I am on the wrong track.
Compile all static libraries for iphoneos and iphonesimulator
Put them together in a single file via lipo
Move them to a folder
Put that folder into version control
Link the libraries in that folder into the Xcode project
This way it would only be necessary to build a new set of static libraries if I update the react-native version in the package.json, right ?
Another idea which came to my mind is to build a dynamic framework of react-native. The framework could be build only once and then added to the application via carthage or manually. The dynamic framework would link all the react static libraries and add the correct headers to the header search paths.
Does anyone can give me a hint if this could work or has an idea how to improve the build architecture in order to speed up the compile time ?
Check these two checkbox
1 Show environment variables in build log
2 Run script only when installing
but when you run first time then uncheck it because this load script for first time otherwise you can not open get loading script in packager.

Using xbuild on iOS application does not generate ipa

We have implemented Continuous Integration with Jenkins to help perform our builds for faster deployment. We have reviewed the documentation provided through the Xamarin website, and have come to an issue. In the walkthrough it describes how to use various plugins to perform the process, we use build scripts to perform our builds because we have some post-actions that we execute after the build, such as submitting the ipa to the TestFlight. The problem is that for iOS it is has been documented that we need to use xbuild instead of mdtool when building from the terminal/command line.
We followed this portion of the guide to construct our xbuild within the build script. It appears that the xbuild command works and creates the project reference dlls and even generates an exe, but does not generate an ipa file even if we set this /p:BuildIpa=true on the xbuild to ensure the ipa generation. We also have provided a location for the ipa to be generated within to ensure we are not missing the file with this /p:IpaPackageDir=$BUILD_PATH. Here is the whole xbuild command that we are currently using, is there something that is incorrect or we are missing?
/Library/Frameworks/Mono.framework/Commands/xbuild $PROJECT_FILE / t:Build /p:BuildIpa=true /p:IpaPackageDir=$BUILD_PATH /p:Configuration=”Release” /p:Platform=”iPhone” /p:OutputPath=$BUILD_PATH
($BUILD_PATH) -- The build path is just “%WORKSPACE%\bin\iPhone\Release\”
I did find this resource as well, which states that xbuild requires the solution file for iOS to build correctly, is that correct?
If this is correct, how do we resolve these errors because I have not been able to find any documentation that explains how to properly define the solution and project files for xbuild deployment, or even how to exclude particular projects during the build:
/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.Forms.UWP/Mobile3.Forms.UWP.csproj: warning : Could not find project file /Library/Frameworks/Mono.framework/External/xbuild/Microsoft/WindowsXaml/v14.0/Microsoft.Windows.UI.Xaml.CSharp.targets, to import. Ignoring.
/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.ServicePro.UWP/Mobile3.ServicePro.UWP.csproj: warning : Could not find project file /Library/Frameworks/Mono.framework/External/xbuild/Microsoft/WindowsXaml/v14.0/Microsoft.Windows.UI.Xaml.CSharp.targets, to import. Ignoring.
Project "/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.sln" (Mobile3.ServicePro.iOS target(s)):
Target ValidateSolutionConfiguration:
/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.sln: error : Invalid solution configuration and platform: "“Release”|“iPhone”".
Task "Error" execution -- FAILED
Done building target "ValidateSolutionConfiguration" in project "/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.sln".-- FAILED
Done building project "/Users/developer/.jenkins/workspace/Mobile3_Branch_3.20/ServicePro/iOS/Mobile3.sln".-- FAILED
Here is the xbuild command we used to build the solution:
/Library/Frameworks/Mono.framework/Commands/xbuild /p:Configuration=”Release” /p:Platform=”iPhone” /p:OutputPath=$BUILD_PATH /p:BuildIpa=true /p:IpaPackageDir=$BUILD_PATH /t:Build $SOLUTION_FILE
We are not concerned with building the UWP projects when building the iOS project because we have a separate build script that generates the appxbundle file correctly.
You can build an "individual project/app" by setting the SolutionDir and building a .csproj, all the referenced projects will be built and an .ipa created, something like:
xbuild
/p:SolutionDir="./src"
/p:OutputPath="$PWD/artifacts/"
/p:IpaPackageDir="$PWD/artifacts/"
/p:Configuration=Release
/p:Platform=iPhone
/target:Build
src/iOS/XamarinForms.iOS.csproj
Note: This assumes your provisioning profiles are setup on this Mac.

Unity3D/iOS: Running a shell script post-Xcode build

When clicking "Build and Run" for an iOS project, Unity generates an Xcode project, fires up Xcode, builds the project, and runs it on the device. I'd like to run a shell script after Xcode finishes building but before it runs. If this were a mere Xcode project, I could simply add a "Run Script" entry to the Build Phases tab, but since this project is auto-generated by Unity I'm not sure how to proceed.
(I'm running OS X Yosemite, if it matters.)
Depends on how much work you want to put into this.
Solution A: Using Unity's PostProcess
You could use Unity's PostProcess, to modify the Xcode project accordingly.
Just mark a static method with the [PostProcessBuild] annotation, and Unity will execute it after the Unity build.
Example:
[PostProcessBuild]
static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
// modify the Xcode project here, or run the shell script directly (if it is ok to do this already here)
}
Sources:
Source: http://docs.unity3d.com/412/Documentation/ScriptReference/PostProcessBuildAttribute.html
Python script to modify Xcode project (not sure if it can add a shell script in build phases): https://github.com/kronenthaler/mod-pbxproj
How to start a process in C#: How do I start a process from C#?
Solution B: Append the Xcode Project
You could modify your Xcode Project accordingly, and afterwards just use Append when starting the next build and Unity asks what to do, when detecting that the folder already exists.
Solution C: Do it manually
Use Build instead of Build And Run
Modify the Xcode project after Unity finished it's build
Manually Run on the Device using Xcode
Solution D: Run the build in batchmode / use CI like Jenkins
You can invoke the build from the command line (terminal), and do what ever you want during/between the different build steps. But as this is a lot of work, I'd recommend to take a look at a CI like Jenkins. It comes with an installer for Mac OS X and is not that hard to set up. I guess there is a lot of documentation and Q&As about it.
Jenkins: http://jenkins-ci.org
I hope there's something that fits your needs. Just let me know if you need some more help or information. Cheers.

Resources